Halo everyone. I am quite a newbie in processing. Recently I am working on a project on rect moving around the screen and collision detection. Here is the script I found on a text book. It works perfectly.
// Rotating Square with Accurate Wall Collisions
// declare global variables
// for moving square
float x, y, w;
float spdX, spdY, theta, rotSpd;
// enables accurate wall collisions
float cornerRadiusOffset, dynamicRadius, collisionTheta;
void setup() {
size(600, 600);
// initialize global variables
x = width/2;
y = height/2;
w = 150;
spdX = 2.1;
spdY = 1.5;
rotSpd = PI/180;
fill(0, 175, 175);
noStroke();
} // end setup
void draw() {
background(255, 127, 0);
pushMatrix();
translate(x, y);
rotate(theta);
rect(-w/2, -w/2, w, w);
popMatrix();
x += spdX;
y += spdY;
theta += rotSpd;
// check for wall collisions
collide();
} // end draw
void collide() {
// calculate dynamicRadius for more
// accurate wall collisions
cornerRadiusOffset = w/2/cos(PI/4) - w/2; // calculate difference between corner and side
dynamicRadius = abs(sin(collisionTheta)*cornerRadiusOffset);
if (x > width-w/2-dynamicRadius) {
spdX *= -1;
rotSpd *= -1;
}
else if (x < w/2+dynamicRadius) {
spdX *= -1;
rotSpd *= -1;
}
if (y > height-w/2-dynamicRadius) {
spdY *= -1;
rotSpd *= -1;
}
else if (y < w/2+dynamicRadius) {
spdY *= -1;
rotSpd *= -1;
}
// used to calculate dynamicRadius
collisionTheta += rotSpd*2;
}
I am quite confused in the dynamicRadius concept. I have drawn the relevant graph many time but i still cannot figure why it is a sin function.
Can anyone give a help?
Thanks!!
dynamicRadius is an odd name. It only works because the shape is a square. If it were a rectangle then you would need two variables – dynamicWidth, and dynamicHeight. These express the difference between the unrotated square and the rotated square bounding boxed, as expressed by rotation of a corner point (this is where sin comes in).
So the collision detection itself is standard collision detection against a square – but it is a bounding square drawn around the rotating shape. To find that square, you need to know how far the arc of the corner moved – and with a square, rotation expands symmetrically (if you find how much it got wider, you also find how much it got taller). Again, if it were a rectangle, this would require two values.
Does that help? Try using the dynamicRadius value to draw an axis-aligned bounding box around the turning shape to get the idea:
// Rotating Square with Accurate Wall Collisions
// declare global variables
// for moving square
float x, y, w;
float spdX, spdY, theta, rotSpd;
// enables accurate wall collisions
float cornerRadiusOffset, dynamicRadius, collisionTheta;
void setup() {
size(600, 600);
// initialize global variables
x = width/2;
y = height/2;
w = 150;
spdX = 2.1;
spdY = 1.5;
rotSpd = PI/180;
noStroke();
} // end setup
void draw() {
background(255, 127, 0);
fill(175,0,174);
rect(x-w/2-dynamicRadius, y-w/2-dynamicRadius, w+2*dynamicRadius, w+2*dynamicRadius);
pushMatrix();
translate(x, y);
rotate(theta);
fill(0, 175, 175);
rect(-w/2, -w/2, w, w);
popMatrix();
x += spdX;
y += spdY;
theta += rotSpd;
// check for wall collisions
collide();
} // end draw
void collide() {
// calculate dynamicRadius for more
// accurate wall collisions
cornerRadiusOffset = w/2/cos(PI/4) - w/2; // calculate difference between corner and side
dynamicRadius = abs(sin(collisionTheta)*cornerRadiusOffset);
if (x > width-w/2-dynamicRadius) {
spdX *= -1;
rotSpd *= -1;
}
else if (x < w/2+dynamicRadius) {
spdX *= -1;
rotSpd *= -1;
}
if (y > height-w/2-dynamicRadius) {
spdY *= -1;
rotSpd *= -1;
}
else if (y < w/2+dynamicRadius) {
spdY *= -1;
rotSpd *= -1;
}
// used to calculate dynamicRadius
collisionTheta += rotSpd*2;
}
1 Like