Trigonometry Issues

Discussion in 'Java' started by AurimasMB, Nov 4, 2008.

1. AurimasMBGuest

I am working on a simple particle simulator, one of my first JAVA
apps, and I'm having some difficulty with Inverse Tangents. My first
goal is to have the particles move towards the mouse. Finding the
angle between those two points, from what I understand of geometry, is
done using the Inverse Tangent of (Y Distance / X Distance) between
the two points.

m_ang = Math.toDegrees(Math.atan((y_pos - my)/(x_pos - mx)));

x_pos and y_pos is the location of the particle, while mx and my are
the location of the mouse.

I've yielded all manner of interesting results with the simulator, but
I have not been able to make the particles all point at the mouse.
Sometimes the particles will all point towards the mouse from above,
but once past it, will continue to point away from it. Does this mean
I have to split the function into two parts?
Any suggestions?

AurimasMB, Nov 4, 2008

2. Stefan RybackiGuest

AurimasMB schrieb:
> I am working on a simple particle simulator, one of my first JAVA
> apps, and I'm having some difficulty with Inverse Tangents. My first
> goal is to have the particles move towards the mouse. Finding the
> angle between those two points, from what I understand of geometry, is
> done using the Inverse Tangent of (Y Distance / X Distance) between
> the two points.
>
> m_ang = Math.toDegrees(Math.atan((y_pos - my)/(x_pos - mx)));
>

What do you need the angle for? Just use some vector arithmetic. Way easier.

> x_pos and y_pos is the location of the particle, while mx and my are
> the location of the mouse.
>
> I've yielded all manner of interesting results with the simulator, but
> I have not been able to make the particles all point at the mouse.
> Sometimes the particles will all point towards the mouse from above,
> but once past it, will continue to point away from it. Does this mean
> I have to split the function into two parts?

Yes. Since atan only returns values that map to the degree range of 0 to 180°.

> Any suggestions?

Stefan Rybacki, Nov 4, 2008

3. Roedy GreenGuest

On Mon, 3 Nov 2008 23:45:02 -0800 (PST), AurimasMB
<> wrote, quoted or indirectly quoted someone who
said :

>m_ang = Math.toDegrees(Math.atan((y_pos - my)/(x_pos - mx)));

there are two atan functions. You want the one that takes x and y
separately to get the right quadrant.

See http://mindprod.com/jgloss/trigonometry.html
--
http://mindprod.com
Make your vote count. Use a paper ballot.
Voting machines invite massive fraud.

Roedy Green, Nov 4, 2008
4. Patricia ShanahanGuest

AurimasMB wrote:
> I am working on a simple particle simulator, one of my first JAVA
> apps, and I'm having some difficulty with Inverse Tangents. My first
> goal is to have the particles move towards the mouse. Finding the
> angle between those two points, from what I understand of geometry, is
> done using the Inverse Tangent of (Y Distance / X Distance) between
> the two points.
>
> m_ang = Math.toDegrees(Math.atan((y_pos - my)/(x_pos - mx)));
>
> x_pos and y_pos is the location of the particle, while mx and my are
> the location of the mouse.
>
> I've yielded all manner of interesting results with the simulator, but
> I have not been able to make the particles all point at the mouse.
> Sometimes the particles will all point towards the mouse from above,
> but once past it, will continue to point away from it. Does this mean
> I have to split the function into two parts?
> Any suggestions?

Math.atan2(y_pos-my, x_pos-mx)

There two angles in the circle that have the same tangent, so Math.atan
can only select from a semicircle, -pi/2 through pi/2. Math.atan2 gets
two sign bits, one from each coordinate, and so can select the correct

Patricia

Patricia Shanahan, Nov 4, 2008
5. Joshua CranmerGuest

atan versus atan2 [was Re: Trigonometry Issues]

Patricia Shanahan wrote:
> Math.atan2(y_pos-my, x_pos-mx)

You know, out of curiosity, is there any common use case that would use
arctangent, atan2 was a better match for the problem.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

Joshua Cranmer, Nov 4, 2008
6. Patricia ShanahanGuest

Re: atan versus atan2 [was Re: Trigonometry Issues]

Joshua Cranmer wrote:
> Patricia Shanahan wrote:
>> Math.atan2(y_pos-my, x_pos-mx)

>
> You know, out of curiosity, is there any common use case that would use
> arctangent, atan2 was a better match for the problem.
>

My experience matches yours. My best guess is that atan is provided for
symmetry with asin and acos.

However, I am not sure that really makes sense. Arcsine and arccosine
arise in solving triangles, where there is an inherent limit on the
angle range. Math.asin and Math.acos pick the angles that could appear
in a triangle, if you include the degenerate case in which the angles
are pi, 0, and 0.

The only use I've actually seen for arctangent is exactly what the OP is
doing, calculating a direction from the difference in the Cartesian
coordinates of two points. Atan2 is indeed a better match for that job.

Patricia

Patricia Shanahan, Nov 4, 2008
7. John B. MatthewsGuest

In article
<>,
AurimasMB <> wrote:

> I am working on a simple particle simulator[...]
> Any suggestions?

Instead of explicit trigonometry, you can do 2-D elastic collisions with
just vector algebra:

<http://www.geocities.com/vobarian/2dcollisions>

Here's a Java implementation:

Understanding how this works may aid your study of the trigonometric
functions in relation to the unit circle.

--
John B. Matthews
trashgod at gmail dot com

John B. Matthews, Nov 4, 2008
8. Daniel PittsGuest

AurimasMB wrote:
> I am working on a simple particle simulator, one of my first JAVA
> apps, and I'm having some difficulty with Inverse Tangents. My first
> goal is to have the particles move towards the mouse. Finding the
> angle between those two points, from what I understand of geometry, is
> done using the Inverse Tangent of (Y Distance / X Distance) between
> the two points.
>
> m_ang = Math.toDegrees(Math.atan((y_pos - my)/(x_pos - mx)));
>
> x_pos and y_pos is the location of the particle, while mx and my are
> the location of the mouse.
>
> I've yielded all manner of interesting results with the simulator, but
> I have not been able to make the particles all point at the mouse.
> Sometimes the particles will all point towards the mouse from above,
> but once past it, will continue to point away from it. Does this mean
> I have to split the function into two parts?
> Any suggestions?

First, you can use Math.atan2 instead of atan. It correctly handles -x/y
vs x/-y and x/y vs -x/-y

Second, you can "move in the direction" much more simply, without
actually calculating angles at all, using vector algebra

You have the particle point (lets call it P): P = <Xp, Yp>,
and the Mouse Point (lets call it M): M = <Xm, Ym>
The Delta (difference) vector between them is:
D = M - P = <Xd, Yd> = <Xm - Xp, Ym - Yp>
Now find the "unit" direction vector:
U = D / Math.hypot(Xd, Yd) // Math.hypot is Math.sqrt(Xd*Xd + Yd*Yd)

<Xu, Yu> = <Xd / Math.hypot(Xd, Yd), Yd / Math.hypot(Xd, Yd)>

Now, you can add any multiple of U to P to get your new point closer to
the mouse.

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

Daniel Pitts, Nov 4, 2008
9. Daniel PittsGuest

Re: atan versus atan2 [was Re: Trigonometry Issues]

Joshua Cranmer wrote:
> Patricia Shanahan wrote:
>> Math.atan2(y_pos-my, x_pos-mx)

>
> You know, out of curiosity, is there any common use case that would use
> arctangent, atan2 was a better match for the problem.
>

atan2 probably uses atan internally

atan formally finds the reference angle, where atan2 finds the actual
angle by using the reference angle in the appropriate quadrant depending
on the signs of x and y. atan is useful, but atan2 is useful in many
more situations.

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

Daniel Pitts, Nov 4, 2008
10. Mike SchillingGuest

Re: atan versus atan2 [was Re: Trigonometry Issues]

Patricia Shanahan wrote:
> Joshua Cranmer wrote:
>> Patricia Shanahan wrote:
>>> Math.atan2(y_pos-my, x_pos-mx)

>>
>> You know, out of curiosity, is there any common use case that would
>> to do an arctangent, atan2 was a better match for the problem.
>>

>
> My experience matches yours. My best guess is that atan is provided
> for symmetry with asin and acos.
>
> However, I am not sure that really makes sense. Arcsine and arccosine
> arise in solving triangles, where there is an inherent limit on the
> angle range. Math.asin and Math.acos pick the angles that could appear
> in a triangle, if you include the degenerate case in which the angles
> are pi, 0, and 0.
>
> The only use I've actually seen for arctangent is exactly what the OP
> is doing, calculating a direction from the difference in the Cartesian
> coordinates of two points. Atan2 is indeed a better match for that
> job.

I'm just speculating here, not having tried it, but I'd think atan2() can
also handle the case where the y-coordinate is 0, making it impossible to
use atan() (its parameter would be undefined.) There's no analogous
situation for asin() and acos().

Mike Schilling, Nov 4, 2008
11. Joshua CranmerGuest

Re: atan versus atan2 [was Re: Trigonometry Issues]

Daniel Pitts wrote:
> Joshua Cranmer wrote:
>> Patricia Shanahan wrote:
>>> Math.atan2(y_pos-my, x_pos-mx)

>>
>> You know, out of curiosity, is there any common use case that would
>> do an arctangent, atan2 was a better match for the problem.
>>

> atan2 probably uses atan internally

Only if __ieee754_atan2 does __ieee754_atan internally, according to my
copy of the OpenJDK.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

Joshua Cranmer, Nov 4, 2008
12. Daniel PittsGuest

Re: atan versus atan2 [was Re: Trigonometry Issues]

Joshua Cranmer wrote:
> Daniel Pitts wrote:
>> Joshua Cranmer wrote:
>>> Patricia Shanahan wrote:
>>>> Math.atan2(y_pos-my, x_pos-mx)
>>>
>>> You know, out of curiosity, is there any common use case that would
>>> do an arctangent, atan2 was a better match for the problem.
>>>

>> atan2 probably uses atan internally

>
> Only if __ieee754_atan2 does __ieee754_atan internally, according to my
> copy of the OpenJDK.
>

Algorithmically speaking, of course

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

Daniel Pitts, Nov 4, 2008
13. Patricia ShanahanGuest

Re: atan versus atan2 [was Re: Trigonometry Issues]

Mike Schilling wrote:
> Patricia Shanahan wrote:
>> Joshua Cranmer wrote:
>>> Patricia Shanahan wrote:
>>>> Math.atan2(y_pos-my, x_pos-mx)
>>> You know, out of curiosity, is there any common use case that would
>>> to do an arctangent, atan2 was a better match for the problem.
>>>

>> My experience matches yours. My best guess is that atan is provided
>> for symmetry with asin and acos.
>>
>> However, I am not sure that really makes sense. Arcsine and arccosine
>> arise in solving triangles, where there is an inherent limit on the
>> angle range. Math.asin and Math.acos pick the angles that could appear
>> in a triangle, if you include the degenerate case in which the angles
>> are pi, 0, and 0.
>>
>> The only use I've actually seen for arctangent is exactly what the OP
>> is doing, calculating a direction from the difference in the Cartesian
>> coordinates of two points. Atan2 is indeed a better match for that
>> job.

>
> I'm just speculating here, not having tried it, but I'd think atan2() can
> also handle the case where the y-coordinate is 0, making it impossible to
> use atan() (its parameter would be undefined.) There's no analogous
> situation for asin() and acos().

Yes, there is a problem with atan() if the x and y are both zero. The
y/x division results in a NaN.

In terms of the normal use-case, that amounts to asking for the
direction of a line from a point to itself. In other systems, in which
division by zero is an error, the division is an issue when asking for
the direction of a line from a point to a point with the same x coordinate.

Patricia

Patricia Shanahan, Nov 4, 2008