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:
- you can store transformations in matrix
- 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:
- inverting box's transformation matrix and
- 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
Post a Comment