We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Relative angle
Page Index Toggle Pages: 1
Relative angle (Read 676 times)
Relative angle
Apr 30th, 2007, 3:28pm
 
I have a game character swinging on a rope. I want him to crawl up when the mouse is above him and down when the mouse is below him.

But I want this to work from the character's point of view, which fails to work when he is swinging to the left because at PI radians you step immediately into -PI radians. This means it works fine doing < or > when swinging to the right but when he swings to the left the mouse always registers as above at -PI radians or less.

Example:
Code:

float theta;
float x,y;
void setup(){
size(200, 200);
smooth();
strokeWeight(2);
x = y = 100;
theta = HALF_PI;
}
void draw(){
background(255);
stroke(0, 0, 255);
line(0, y, x, y);
float dx = mouseX - x;
float dy = mouseY - y;
float mTheta = atan2(dy, dx);
if(mouseBelow(mTheta)){
stroke(0,155,0);
}
else {
stroke(255,0,0);
}
line(x, y, mouseX, mouseY);
// projected normals
float vx = cos(theta) * 50;
float vy = sin(theta) * 50;
// right hand normal projected
float rx = -vy;
float ry = vx;
// left hand normal projected
float lx = vy;
float ly = -vx;
stroke(0);
line(x + lx, y + ly, x + rx, y + ry);
line(x, y, x + vx, y + vy);
if(keyPressed){
switch(keyCode){
case LEFT:
theta -= 0.1;
break;
case RIGHT:
theta += 0.1;
break;
}
}
}
boolean mouseBelow(float mTheta){
float minTheta = theta - HALF_PI;
float maxTheta = theta + HALF_PI;
println("min:"+minTheta+" max:"+maxTheta+" theta:"+mTheta);
return mTheta > minTheta && mTheta < maxTheta;
}


How can I get a relative angle check that overcomes the jump from +PI radians to -PI radians?
Re: Relative angle
Reply #1 - Apr 30th, 2007, 7:39pm
 
You can just check angleA to angleB, angleA to angleB+TWO_PI and angleA+TWO_PI to angleB and then take the minimum value of the three, which should give the angle beween as a human would calculate it.
Re: Relative angle
Reply #2 - Apr 30th, 2007, 11:49pm
 
You could also just examine the sign of the dot product between your line's normal (towards the "inside" half space, that is: towards the "below" in your usage) and a vector constructed from the line to the mouse point.  If N.V==0 then on line, if <0 then outside or "above", if >0 then inside or "below".
Re: Relative angle
Reply #3 - May 1st, 2007, 11:29am
 
I managed to cobble together a rather wierd condition that solves the problem - I didn't realise that I'd already used this method for a demo of rope catching on platforms.

Code:

boolean mouseRight(float mTheta){
float minTheta = angle - PI;
float maxTheta = angle;
if(maxTheta+PI <= PI){
return mTheta > minTheta && mTheta < maxTheta;
}
return mTheta + PI < minTheta || (mTheta > minTheta && mTheta < maxTheta);
}


But davbol's method certainly works well! I've just cobbled a quick implementation of it (having to find out what a dot product is).

Code:

boolean mouseBelow2(float vx, float vy){
float vx1 = vx;
float vx2 = mouseX - x;
float vy1 = vy;
float vy2 = mouseY - y;
float dotProduct = vx1*vx2 + vy1*vy2;
return dotProduct > 0;
}


I should be able to implement the latter and ease up the load on the processor.

Edit: Thank you!
Page Index Toggle Pages: 1