3
\$\begingroup\$

I'm trying to make game like portal which players can transform between two holes.
My problem is, how to detect if player's have the right angle to the hole. (hole has an angle to a direction, if player's angle to hole meet the right direction can do transform)

enter image description here

Pseudo code:

var range=30;
 if(collission){
     if(abs(ball.getAngle()-player.getAngle())<=range){
            ball.doTransform(player);
     }
 }

below is some situation:

ball.setAngle(20);
player.setAngle(30);
abs(ball.getAngle()-player.getAngle()) ==10 //ok
player.setAngle(350);
abs(ball.getAngle()-player.getAngle()) ==320 //not ok
ball.setAngle(350);
player.setAngle(20);
abs(ball.getAngle()-player.getAngle()) ==330 //not ok 
ball.setAngle(120);
player.setAngle(100);
abs(ball.getAngle()-player.getAngle()) ==20 //ok 

and anybody can help me to figure out the right condition so that ball can transform player? thanks!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ How do you use the range variable? What is the difference between player and ball? Why compare the player's angle with the ball's and the hole's? This way you couple the player with both ball and hole, don't you want to take care only of how the player "faces" the hole? (disregarding other objects). Rephrasing the question a bit might help us giving an answer. \$\endgroup\$
    – teodron
    May 16, 2012 at 8:55
  • \$\begingroup\$ Indeed, you need to clarify your question. I've edited it to git it a better look, but only you can add relevant infos on what exactly your problem is. \$\endgroup\$ May 16, 2012 at 9:50

2 Answers 2

3
\$\begingroup\$

If I understood your question correctly, you're trying to see whether two known angles match within a tolerance 'range', but subtracting them gives unwanted results when the 360° branch cut is traversed, e.g. the difference between 350° and 10° should show up as 20° instead of 340°.

One possible solution is to replace the abs-function with a function that adds 360° when the angle is below -180° and subtracts 360° when the angle is over 180°. The result is always in the range of -180° to 180°, the sign indicating left and right.

Pseudocode

take360(angle) {
  if(angle>180) { return(angle-360); }
  if(angle<-180) { return(angle+360); }
  return(angle);
}
var range=30;
  if(collission){
    if(abs(take360(ball.getAngle()-player.getAngle())) <= range){
      ball.doTransform(player);
    }
  }
\$\endgroup\$
1
  • 1
    \$\begingroup\$ if(angle<=180) return angle; \$\endgroup\$
    – Frei Zhang
    May 16, 2012 at 17:00
4
\$\begingroup\$

It's hard to understand what you are trying to do, but probably the answer is to use direction vectors instead of angles.

If you specify the directions as vectors, a simple dot product will tell you how the directions relate to each other. The dot product results in a range of values from 1 to -1: if the dot product is 1, they are facing exactly the same direction; if it is -1, they are facing exactly opposite directions. Thus you are looking for a dot product that is negative within some threshold.

\$\endgroup\$
2
  • \$\begingroup\$ sorry for my bad description,I just want to calculate if angleA - angleB = myRange,but ball's angle is between 0-360 ,I just cannot figure it out ,thank your time. \$\endgroup\$
    – Frei Zhang
    May 16, 2012 at 10:36
  • \$\begingroup\$ +1 I was about to suggest this. Handily, assuming your portal is represented with a texture on a flat plane, the direction vector of the portal is the normal of the plane. \$\endgroup\$
    – jhocking
    May 16, 2012 at 13:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .