tags:

views:

5058

answers:

8

Lets say you have this:

P1 = (x=2, y=50) P2 = (x=9, y=40) P3 = (x=5, y=20)

Assume that P1 is the center point of a circle. It is always the same. I want the angle that is made up by P2 and P3, or in other words the angle that is next to P1. The inner angle to be precise. It will be always a sharp angle, so less than -90 degrees.

I thought: Man, that's simplest geometry maths. But I looked for a formula for like 6 hours now and people talk about most complicated NASA stuff like arcos and vector scalar product stuff. My head feels like in a fridge.

Some math gurus here that think this is a simple problem? I think the programing language doesn't matter here but for those who think it does: java and objective-c. need that for both. haven't tagged it for these, though.

+7  A: 
Andre Miller
+17  A: 

If you have 3 points, you have a triangle who's edge lengths are all known. So use the cosine rule:

http://en.wikipedia.org/wiki/Law_of_cosines

ire_and_curses
+7  A: 

If you mean the angle that P1 is the vertex of then this should work (though there's probably more efficient methods):

arccos((P23^2 - P12^2 - P13^2)/(-2*P12*P13))

where P12 is the length of the segment from P1 to P2, calculated by

sqrt((P1x-P2x)^2 + (P1y-P2y)^2)

Lance Roberts
I don't think there is a more efficient way to do this.
Treb
That could be, though maybe with some vector math it could be done, but it's too late for me to think that hard.
Lance Roberts
I believe there is a slight error in the equation. It should be arccos((P23^2 - P12^2 - P13^2)/(-2*P12*P13))
Dan Littlejohn
@Dan, thanks for the catch.
Lance Roberts
+3  A: 

If you are thinking of P1 as the center of a circle, you are thinking too complicated. You have a simple triangle, so your problem is solveable with the law of cosines. No need for any polar coordinate tranformation or somesuch. Say the distances are P1-P2 = A, P2-P3 = B and P3-P1 = C:

Angle = arccos ( (B^2-A^2-C^2) / 2AC )

All you need to do is calculate the length of the distances A, B and C. Those are easily available from the x- and y-coordinates of your points and Pythagoras' theorem

Length = sqrt( (X2-X1)^2 + (Y2-Y1)^2 )

Treb
+2  A: 

You mentioned a signed angle (-90). In many applications angles may have signs (positive and negative, see http://en.wikipedia.org/wiki/Angle). If the points are (say) P2(1,0), P1(0,0), P3(0,1) then the angle P3-P1-P2 is conventionally positive (PI/2) whereas the angle P2-P1-P3 is negative. Using the lengths of the sides will not distinguish between + and - so if this matters you will need to use vectors or a function such as Math.atan2(a, b).

Angles can also extend beyond 2*PI and while this is not relevant to the current question it was sufficiently important that I wrote my own Angle class (also to make sure that degrees and radians did not get mixed up). The questions as to whether angle1 is less than angle2 depends critically on how angles are defined. It may also be important to decide whether a line (-1,0)(0,0)(1,0) is represented as Math.PI or -Math.PI

peter.murray.rust
+2  A: 
Andrea Ambu
+1  A: 

I ran into a similar problem recently, only I needed to differentiate between a positive and negative angles. In case this is of use to anyone, I recommend the code snippet I grabbed from this mailing list about detecting rotation over a touch event for Android: link

 @Override
 public boolean onTouchEvent(MotionEvent e) {
    float x = e.getX();
    float y = e.getY();
    switch (e.getAction()) {
    case MotionEvent.ACTION_MOVE:
       //find an approximate angle between them.

       float dx = x-cx;
       float dy = y-cy;
       double a=Math.atan2(dy,dx);

       float dpx= mPreviousX-cx;
       float dpy= mPreviousY-cy;
       double b=Math.atan2(dpy, dpx);

       double diff  = a-b;
       this.bearing -= Math.toDegrees(diff);
       this.invalidate();
    }
    mPreviousX = x;
    mPreviousY = y;
    return true;
 }
Marc
+1  A: 

In Objective-C you could do this by

float xpoint = (((atan2((newPoint.x - oldPoint.x) , (newPoint.y - oldPoint.y)))*180)/M_PI);

Or read more here

http://www.iphonedevsdk.com/forum/iphone-sdk-development/49847-how-find-angle-two-points.html

Adeem Maqsood Basraa