Reputation: 533
I am trying to create a 25x25 grid with rotating compasses based on Perlin noise. However, the rotations are affecting subsequent lines even with the use of push/pop. Where have I gone wrong and how can I do it correctly?
var stepSize = 20;
function setup() {
createCanvas(500, 500);
}
function draw() {
background(125);
compassGrid();
}
function compassGrid(){
angleMode(DEGREES);
for(var i = 0; i < 25; ++i){
for(var j = 0; j < 25; ++j){
var change = map(mouseX, 0, width, 50, 200);
var n = noise(i/100, j/100, frameCount/change);
var angle = map(n, 0, 1, 0, 720);
stroke(0);
noFill();
push();
translate(10, 10);
rotate(angle);
line(i * stepSize, j * stepSize,
i * stepSize, j * stepSize - stepSize)
pop();
}
}
}
This is what it looks like currently:
Thanks for any help.
Upvotes: 2
Views: 232
Reputation: 51837
Your issue is similar to this Processing one (which includes a lengthy answer).
TLDR; This section
line(i * stepSize, j * stepSize,
i * stepSize, j * stepSize - stepSize)
"implies" translating after rotation (since you're using absolute coordinates). The order of transformations is important (e.g. translate first, then rotate).
You should be able to explicitly translate first, then, after rotation draw the lines (using relative coordinates):
push();
translate(i * stepSize, j * stepSize);
rotate(angle);
line(0, 0, 0, - stepSize);
pop();
var stepSize = 20;
function setup() {
createCanvas(500, 500);
angleMode(DEGREES);
}
function draw() {
background(125);
compassGrid();
}
function compassGrid(){
translate(10, 10);
for(var i = 0; i < 25; ++i){
for(var j = 0; j < 25; ++j){
var change = map(mouseX, 0, width, 50, 200);
var n = noise(i/100, j/100, frameCount/change);
var angle = map(n, 0, 1, 0, 720);
stroke(0);
noFill();
push();
translate(i * stepSize, j * stepSize);
rotate(angle);
line(0, 0, 0, - stepSize);
pop();
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.min.js"></script>
Upvotes: 2