math - Advanced rectangles collision in processing -


coded in procesing (processing.org): want know when mouse or shape collides rectangle, easy have 1 problem: want work when rectangle rotated (example: rotate(radians(90))).

both kevin , asad's contributions useful.

in terms of using 2d renderer, need roll own functionality that. should familiar few bits , bobs of linear algebra (vector , matrices , few operations anyway).

i going assume you're familiar 2d transformations (using pushmatrix()/popmatrix() along translate(),rotate(),scale()) if not, warmly recommend 2d transformations processing tutorial

i going explain of concepts briefly (as it's big topic on it's own).

if used translate()/rotate()/scale() before, it's been matrix operations handled behind scenes. in 2d, transformation can stored in 3x3 matrix so:

x y t 1 0 0 0 1 0 0 0 1 

the rotation , scale stored in 1st , 2nd column (2 values each) while translation stored in last column. in theory have 2x3 matrix instead of 3x3 matrix, nxn matrix has few nice properties. 1 of nice things being simple multiply vector. position can stored vectors , we'd transform vector multiplying transformation matrix. if @ vector single column vector, 3x3 form of matrix allow multiplication(see matrix multiplication rules here).

in short:

  1. you can store transformations in matrix
  2. you can apply these transformation vector using multiplication

back issue, checking if point within box transformations applied, can this:

convert test point's coordinate system box's transformed coordinate system by:

  1. inverting box's transformation matrix and
  2. multiplying point inverted transformation matrix.

this may hard comprehend @ first, 1 way @ imagining rotate whole 'world'(coordinate system) rotated box straight (essentially rotating in opposite direction, or inverting transformation) check if point in box.

luckily these matrix operations don't need implemented scratch: pmatrix2d deals this.

here basic commented sketch explaining above:

box box1,box2;  void setup(){   size(400,400);    box1 = new box(200,100);   box1.translate(75,100);   box1.rotate(radians(30));   box1.scale(1.1);    box2 = new box(100,200);   box2.translate(275,150);   box2.rotate(radians(-5));   box2.scale(.95); }  void draw(){   background(255);   box1.update(mousex,mousey);   box2.update(mousex,mousey);   box1.draw();   box2.draw(); }  class box{    pmatrix2d coordinates = new pmatrix2d();//box coordinate system   pmatrix2d reversecoordinates = new pmatrix2d();//inverted coordinate system    pvector reversedtestpoint = new pvector();//allocate reversed point vector   pvector testpoint = new pvector();//allocate regular point vector     float w,h;//box width , height   boolean ishovered;    box(float w,float h){     this.w = w;     this.h = h;   }   //whenever update regular coordinate system, update reversed 1   void updatereversecoordinates(){     reversecoordinates = coordinates.get();//clone original coordinate system     reversecoordinates.invert();//simply invert   }    void translate(float x,float y){     coordinates.translate(x,y);       updatereversecoordinates();   }   void rotate(float angle){     coordinates.rotate(angle);       updatereversecoordinates();   }   void scale(float s){     coordinates.scale(s);     updatereversecoordinates();   }   boolean isover(float x,float y){     reversedtestpoint.set(0,0);//reset reverse test point     testpoint.set(x,y);//set x,y coordinates want test     //transform passed x,y coordinates reversed coordinates using matrix multiplication     reversecoordinates.mult(testpoint,reversedtestpoint);     //simply test bounding box     return ((reversedtestpoint.x >= 0 && reversedtestpoint.x <= w) &&              (reversedtestpoint.y >= 0 && reversedtestpoint.y <= h));   }    void update(float x,float y){     ishovered = isover(x,y);   }   void draw(){     if(ishovered) fill(127);     else          fill(255);     pushmatrix();     applymatrix(coordinates);     rect(0,0,w,h);     popmatrix();   }  } 

Comments