This is what atan2() does if given two Vector2D points on 2D plane?

Started by
11 comments, last by tom_mai78101 10 years, 1 month ago

[attachment=20102:math.png]

This is the basis of touch screen math calculations I'm working on. Just so happens, I tend to forget simple calculations. sad.png Especially where I don't even know the theta in the picture above is called? (The smaller angle of line and X-axis where the line intersects two arbitrarily given Vector2D points on a 2D plane? The atan2 angle?)

Anyway, I'm looking for the answer to the question: Is the theta the answer to atan2(Vector 1, Vector 2)?

Advertisement

Inverse trigonometric functions are applied to a length ratio which is a scalar value; there is no definition for vectors / points! With your formula you would need to calculate a division of two vectors what also is not defined that way.

Looking at the illustration in the OP, you want to compute the angle between the principal x vector

x = [ 1 0 ]T

and the vector v between point p1 and point p2

v = p2 - p1

The arccos computes the angle between the adjacent and the hypothenuse, where both of these legs are what you have given as x and v. Taking advantage of the dot-product

v . x = |v| * |x| * cos( <v,x> )

where the angle <v,x> is your theta, you get

<v,x> = arccos( ( v . x ) / ( |v| * |x| ) )

Now one of the vectors, namely x, is a unit vector, i.e. has length |x| == 1, so that the formula is simplified to

<v,x> = arccos( ( v . x ) / |v| )

Furthermore the y component of x is always 0 and its x component is always 1, so the dot-product is simplified to
v . x = vx * 1 + vy * 0 = vx
and hence the formula becomes

<v,x> = arccos( vx / |v| )

EDIT: The OP mentioned to compute "the smaller angle between the line and the x axis", which, following the more detailed requirements in one of the following posts, is too broadly interpreted by the above solution.

Chances are you don't need an angle at all. What are you planning to do with it? Perhaps we can suggest alternatives.

Chances are you don't need an angle at all. What are you planning to do with it? Perhaps we can suggest alternatives.

Using two fingers on an Android touch screen, the movement based on these two fingers determines the rotation angle the camera is facing. Two fingers swiped from left to right will cause the camera to pan in a circle towards the camera's right side view. The rotation angle, once converted to degrees, is needed in order to rotate the view matrix used in OpenGL ES 2.0. On Android, in order to rotate view matrix, I need to pass the view matrix into the first parameter of the


Matrix.rotateM(float[] matrix, int offset, float angle, float x, float y, float z);

method. After that, passing the view matrix as an uniform matrix in the vertex shader is the last thing I need to do.

This is what I'm trying to do.

If you ask why I didn't go with 1 finger, it's because it's already used to aim at the enemies with a cross in the center.

attachicon.gifmath.png

This is the basis of touch screen math calculations I'm working on. Just so happens, I tend to forget simple calculations. sad.png Especially where I don't even know the theta in the picture above is called? (The smaller angle of line and X-axis where the line intersects two arbitrarily given Vector2D points on a 2D plane? The atan2 angle?)

Anyway, I'm looking for the answer to the question: Is the theta the answer to atan2(Vector 1, Vector 2)?

Just to be clear, you're not passing in the points into atan2? but the vector, correct? If you're actually centered at 0,0 it doesn't matter, but I just wanted to make sure, as that'll cause you headaches.


Just to be clear, you're not passing in the points into atan2? but the vector, correct? If you're actually centered at 0,0 it doesn't matter, but I just wanted to make sure, as that'll cause you headaches.

1. Uh, to be honest, I have no clue as to the atan2(). I thought that method can also be used like this in order to calculate the theta.

2. It's not centered. There is only positive X and positive Y, because the values that were read in are values the touch screen gives where the finger is touched/pressed.

First, atan2( y, x ) expects values for y and x, not vectors. Also, it appears you're calling a single point (x,y) a vector. Note: a vector has a direction, but, if I understand what you're saying, you just have 2 pairs of (x,y) points on the screen. A point doesn't have a direction, it's just.. well.. a point.

Try:


atan2( fabs(vector2.y - vector1.y), fabs(vector2.x - vector1.x) );

As atan2 takes into account the signs of the two input values, so you may need:


atan2( (vector2.y - vector1.y),( vector2.x - vector1.x) );

Use the first code above if it only matters where the two points are relative to one another, not specifically that vector2 is further from the origin.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Well, after noticing that the angle should be used to compute a rotation matrix, the sentence "the smaller angle of line and X-axis where the line intersects two arbitrarily given Vector2D points on a 2D plane" in the OP is found misleading. Using the cosine as suggested by my post above computes the smallest angle and hence allows for a half circle rotation only. Using atan2(abs(…), abs(…)) as mentioned by Buckeye above allows for a fourth circle rotation only. Using atan2(…, …) without any abs(…) allows for a full circle rotation.

However, notice that the order of assignment, i.e. which point is p1 and which point is p2, plays a role whenever you do not use an abs(…). The difference when exchaning the points will be 180°. Perhaps you have to use the order when placing the 2 fingers, so that the first placement means the emanation point (i.e. p1) and the second placement means the point p2 where the difference vector is directed to.


If you ask why I didn't go with 1 finger, ...

Álvaro was asking probably because often angles are computed needlessly due to the fact that they subsequently are used to re-compute just vectors which are already there. It seems me that also here the same thing happens. The (2D) rotation can be set-up from the direction vector of p2 - p1 and one of its both perp-dot vectors (whch one depends on 2 finger touch problem as described above).


First, atan2( y, x ) expects values for y and x, not vectors. Also, it appears you're calling a single point (x,y) a vector. Note: a vector has a direction, but, if I understand what you're saying, you just have 2 pairs of (x,y) points on the screen. A point doesn't have a direction, it's just.. well.. a point.

AFAIK: The distinction is to be made between a scalar value and a vector value. As such also points are given as vectors. But you are right that the geometric interpretation as position vectors (or "point" for short), difference vectors, direction vectors (normalized difference vectors), and derived direction vectors (like normal or tangent vectors) is important.

Atan2 uses a ratio of lengths where the nominator and denominator of the ratio are given explicitly. As such atan2 expects two scalar values as arguments.

I see. I'll try to implement the math and will report back my findings in a new post in this thread. (Not a new thread, though. It's not worth it.)

There is no need to convert these vectors to angles to compute a rotation matrix. All you need to compute a rotation matrix in 2D are the cosine and sine of the angle and you already have them encoded in the direction of the difference vector. You indeed simply have to normalize the difference vector:

(cos(angle), sin(angle) ) = normalize(P2 - P1).

If you think you have to compute the angle to compare them between different fingers positions, then it is not true again. If P3 and P4 are different positions of your fingers, then you can compute the cosine and sine of the rotation angle between the two vectors by simply using a complex division. If do not know complex numbers I suggest to learn about them, but you can implement the division using the following formula:

(a, b) / (c, d) = ( a*c + b*d, b*c - a*d ) / (c*c + d*d).

This topic is closed to new replies.

Advertisement