***EDIT: I just notice this is a p5.js question. Below is the concept demonstrated using processing java.
This is an excellent case that demonstrates one reference frame is more convenient than another one. In fact, this not only applies to points but also to circles when checking for coincidence against other geometries. Instead of applying the rotating to the rectangle, you can calculate the coordinates of your point in the rotated frame of the rectangle and then test if it is inside of it. That is, instead of rotating the rectangle theta degrees, you rotated the point. In Cartesian coordinate system, you rotate the position of the point -theta
degrees (notice the minus sign).
In Processing, you need to watch for the inversion of the y dimension. I correct for this using explicit inversion via scale()
function. Notice that mouseX
/mouseY
is not affected by transformations on your sketch, so you have to apply those transformations manually to it.
In the following code, you can choose where to place your point using mouseX/Y. When pressing the mouse, the rectangle is shown with no rotation and the point is transformed. Code below.
I used straight simple geometry to calculate the angle. you can use heading()
from PVector, which is shown and commented out in the code.
Kf
//===========================================================================
// FINAL FIELDS:
final color ORANGE=color(250,150,0);
final color GREEN=color(0,250,0);
final color BLUE=color(0,0,250);
//===========================================================================
// GLOBAL VARIABLES:
float x, y;
float theta=30; //Rectangle rotation, in degrees
//===========================================================================
// PROCESSING DEFAULT FUNCTIONS:
void settings() {
size(600, 400);
}
void setup() {
//textAlign(CENTER, CENTER);
rectMode(CENTER);
textSize(18);
x=width*0.4;
y=0;
}
void draw() {
background(0);
translate(width/2, height/2);
drawHelpingLines();
pushMatrix();
scale(1, -1); //Invert y axis to match cartesian system
if (!mousePressed) {
//Draws user point and rotated rectangle
surface.setTitle("Hold mouse down to see transformed point, unrotated rect");
x=mouseX-width/2;
y=-mouseY+height/2; //Invert mouse
drawPoint(x,y,GREEN);
rotate(radians(theta));
drawRectangle();
} else {
//calculates original angle of giving coordinate point
float phi= x!=0 ? atan2(y, x) : 0; //Value in radians, checks for zero div!
float hyp=sqrt(x*x+y*y);
float nx=hyp*cos(phi-radians(theta));
float ny=hyp*sin(phi-radians(theta));
surface.setTitle("Ref frame theta:"+theta+" Phi:"+nf(degrees(phi), 0, 1));
////ANOTHER way to calculate the angle
//PVector v=new PVector(x,y);
//println(v.heading()+" "+phi); //Same value
//Draws un-rotated rectangle and transformed user point
drawPoint(nx,ny,ORANGE);
drawRectangle();
}
popMatrix();
text("User point [X,Y] \n " +x+","+y, width*0.2, -height*0.4);
}
//===========================================================================
// OTHER FUNCTIONS:
void drawRectangle() {
noStroke();
fill(255, 125);
rect(0, 0, width/2, height/4);
}
void drawPoint(float xx, float yy, color c) {
strokeWeight(16);
stroke(c);
point(xx,yy);
}
void drawHelpingLines() {
strokeWeight(1);
stroke(BLUE);
line(-width/2, 0, width/2, 0);
line(0, -height/2, 0, height/2);
stroke(255, 0, 0, 180); //red
noFill();
float hyp=sqrt(x*x+y*y);
ellipse(0, 0, 2*hyp, 2*hyp);
}