Rect collision problem

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