0

I need to calculate an angle between two points in 2D space. Is it a good idea to calculate it using right triangle? Please give me the formula, written in Java code. Thank you!

Here's my code:

public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
                    float pTouchAreaLocalX, float pTouchAreaLocalY) {
                double angle = Math.atan2(
                        pTouchAreaLocalX - boundSpriteCenterX,
                        boundSpriteCenterY - pTouchAreaLocalY);
                angle = Math.toDegrees(angle);
                Log.i("egor", "angle " + angle);
                return true;
            };

And here's what I'm getting when I rotate my finger around the sprite:

    07-21 16:07:00.736: INFO/egor(12600): angle -11.401802094139539
07-21 16:07:00.786: INFO/egor(12600): angle -11.349729213136412
07-21 16:07:00.826: INFO/egor(12600): angle -11.422536712363058
07-21 16:07:00.956: INFO/egor(12600): angle -11.234933754467884
07-21 16:07:00.986: INFO/egor(12600): angle -10.762776313908919
07-21 16:07:01.026: INFO/egor(12600): angle -10.18502866163197
07-21 16:07:01.086: INFO/egor(12600): angle -8.791364033967513
07-21 16:07:01.126: INFO/egor(12600): angle -7.51789397098733
07-21 16:07:01.266: INFO/egor(12600): angle -5.964822509364536
07-21 16:07:01.266: INFO/egor(12600): angle -3.8833834235199327
07-21 16:07:01.316: INFO/egor(12600): angle -3.518004982991794
07-21 16:07:01.316: INFO/egor(12600): angle -3.2335041547308747
07-21 16:07:01.356: INFO/egor(12600): angle -2.8893793853454013
07-21 16:07:01.366: INFO/egor(12600): angle -2.591166578194567
07-21 16:07:01.396: INFO/egor(12600): angle -2.4890755982704613
07-21 16:07:01.426: INFO/egor(12600): angle -2.4041628132172432
07-21 16:07:01.466: INFO/egor(12600): angle -2.606754218788734
07-21 16:07:01.486: INFO/egor(12600): angle -2.9585030905373477
07-21 16:07:01.516: INFO/egor(12600): angle -3.203094764102693
07-21 16:07:01.546: INFO/egor(12600): angle -4.143849229994
07-21 16:07:01.576: INFO/egor(12600): angle -4.833402961115934
07-21 16:07:01.596: INFO/egor(12600): angle -5.201363076921709
07-21 16:07:01.626: INFO/egor(12600): angle -7.182189581196999
07-21 16:07:01.666: INFO/egor(12600): angle -8.30009901770206
07-21 16:07:01.706: INFO/egor(12600): angle -10.305907456087617
07-21 16:07:01.746: INFO/egor(12600): angle -11.845396664651743
07-21 16:07:01.776: INFO/egor(12600): angle -13.486956315730428
07-21 16:07:01.796: INFO/egor(12600): angle -14.928485252180119
07-21 16:07:01.826: INFO/egor(12600): angle -15.930527466185383
07-21 16:07:01.856: INFO/egor(12600): angle -17.523214080867536
07-21 16:07:01.876: INFO/egor(12600): angle -18.670097079838413
07-21 16:07:01.906: INFO/egor(12600): angle -19.784066963586145
07-21 16:07:01.946: INFO/egor(12600): angle -20.967697211428263
07-21 16:07:01.966: INFO/egor(12600): angle -22.839177072269344
07-21 16:07:01.986: INFO/egor(12600): angle -23.995902815112903
07-21 16:07:02.026: INFO/egor(12600): angle -24.94729858380699
07-21 16:07:02.046: INFO/egor(12600): angle -25.824795978977953
07-21 16:07:02.066: INFO/egor(12600): angle -26.163619752371858
07-21 16:07:02.106: INFO/egor(12600): angle -27.036651116353283
07-21 16:07:02.126: INFO/egor(12600): angle -27.392238974828167
07-21 16:07:02.266: INFO/egor(12600): angle -28.076676644069305
07-21 16:07:02.276: INFO/egor(12600): angle -28.49774854622218
07-21 16:07:02.316: INFO/egor(12600): angle -28.408406568602896
07-21 16:07:02.316: INFO/egor(12600): angle -28.323322872571392
07-21 16:07:02.356: INFO/egor(12600): angle -28.24684157963425
07-21 16:07:02.366: INFO/egor(12600): angle -28.115274003009183
07-21 16:07:02.406: INFO/egor(12600): angle -27.97540955255425
07-21 16:07:02.426: INFO/egor(12600): angle -27.947947494965728
07-21 16:07:02.446: INFO/egor(12600): angle -27.908408445343735
07-21 16:07:02.486: INFO/egor(12600): angle -27.621472392453533
07-21 16:07:02.506: INFO/egor(12600): angle -27.31775291690124
07-21 16:07:02.526: INFO/egor(12600): angle -26.84707894871403
07-21 16:07:02.556: INFO/egor(12600): angle -26.573497423338885
07-21 16:07:02.586: INFO/egor(12600): angle -25.553344674326492
07-21 16:07:02.606: INFO/egor(12600): angle -24.681035396816615
07-21 16:07:02.646: INFO/egor(12600): angle -23.164315738891876
07-21 16:07:02.686: INFO/egor(12600): angle -22.001937944957152
07-21 16:07:02.696: INFO/egor(12600): angle -21.108728821882377
07-21 16:07:02.726: INFO/egor(12600): angle -20.777362892583056
07-21 16:07:02.756: INFO/egor(12600): angle -20.331914563591184
07-21 16:07:02.776: INFO/egor(12600): angle -19.842422968714942
07-21 16:07:02.796: INFO/egor(12600): angle -18.943202330016586
07-21 16:07:02.836: INFO/egor(12600): angle -17.900217339627066
07-21 16:07:02.886: INFO/egor(12600): angle -16.38438849186955
07-21 16:07:02.896: INFO/egor(12600): angle -15.49309440885704
07-21 16:07:02.916: INFO/egor(12600): angle -14.663361857753415
07-21 16:07:02.956: INFO/egor(12600): angle -14.06291160310325
07-21 16:07:02.976: INFO/egor(12600): angle -13.743513115207124
07-21 16:07:02.996: INFO/egor(12600): angle -13.436847871994882
07-21 16:07:03.076: INFO/egor(12600): angle -13.436847871994882
user1118321
  • 25,567
  • 4
  • 55
  • 86
Egor
  • 39,695
  • 10
  • 113
  • 130
  • possible duplicate of [Calculating the angle between the line defined by two points](http://stackoverflow.com/questions/2676719/calculating-the-angle-between-the-line-defined-by-two-points) – Johan Kotlinski Jul 21 '11 at 11:21
  • two points aren't enough to determine an angle, you need a third one (or a line). The origin, one of the axis? – Eineki Jul 21 '11 at 11:22
  • 2
    The question makes no sense. You can only calculate an angle between 3 points, or 2 lines. Are you after a bearing? Please explain better and give an example of what you're trying to actually find. – Mark Fisher Jul 21 '11 at 11:22
  • 1
    @Egor Do you mean, given points A and B, the angle between the lines OA and OB coming from the origin of the coordinate system ("point zero") O? – quant_dev Jul 21 '11 at 11:27
  • @Mark Fisher, sorry, understood my mistake. I've got a picture that I need to rotate while rotating finger around it. Figure's top must always look at the finger, though there are two lines: one from the center of figure up, and second from the center of figure to the finger. – Egor Jul 21 '11 at 11:28
  • http://en.wikipedia.org/wiki/Trigonometry – Patrick Jul 21 '11 at 13:00
  • Perhaps as well as the output you could log the coordinates being used to calculate the angle. I suspect the problem must lie there. Are the sprite and touch area positions given in the same coordinate system? I am not an Android developer as you may have guessed. – Ben Jul 21 '11 at 13:20
  • @Egor : As ben says, please supply all 4 coordinate values in your output so we can see if the two are in the same space. – Mark Fisher Jul 21 '11 at 13:32
  • @Ben, Okay, found my mistake, it was so silly.. Thanks for your answer, it worked! – Egor Jul 21 '11 at 13:36

2 Answers2

9

In screen coordinates (where the origin is at the top left and Y increases downwards) if the centre of the image is (x0,y0) and the "finger" is at (xa,ya) then the angle you require is

Math.atan2(xa-x0,y0-ya)

This will give you the angle in radians by which you have to rotate the image clockwise from its starting position.

Ben
  • 2,348
  • 2
  • 19
  • 28
  • Can you be more specific? I am using a coordinate system where X points to the right and Y points upwards. If you are using screen pixel coordinates you may need to change the sign of Y. The result is in radians. I can't think what else can "not work". – Ben Jul 21 '11 at 11:58
  • I'm working in a standard coordinate system where (0,0) is in the upper left corner of the screen. I have a figure, that initially is looking up. When I tap my finger on the screen, I want the figure to turn to my finger's tap. Means I want to rotate it on the angle between the positive Y axis and my finger's touch. – Egor Jul 21 '11 at 12:13
  • OK, I've changed the sign of y for you. – Ben Jul 21 '11 at 12:26
0

I agree with Ben's solution above, here's some code giving examples in all 4 quadrants and at edges

public class CalculateAngle {
    public static void main(String[] args) {
        System.out.println(angleInDegrees(100, 100, 100, 0)); // directly above centre = 0.0
        System.out.println(angleInDegrees(100, 100, 200, 100)); // directly to the right = 90.0 
        System.out.println(angleInDegrees(100, 100, 0, 100)); // directly to the left = -90.0 
        System.out.println(angleInDegrees(100, 100, 100, 200)); // directly below centre = 180.0
        System.out.println(angleInDegrees(100, 100, 200, 0)); // 45 degrees to right and above = 45.0
        System.out.println(angleInDegrees(100, 100, 0, 0)); // 45 degrees to left and above = -45.0
        System.out.println(angleInDegrees(100, 100, 0, 200)); // 45 degrees to left and below = -135.0
        System.out.println(angleInDegrees(100, 100, 200, 200)); // 45 degrees to the right and below = 135.0
    }

    public static double angleInDegrees(double centreX, double centreY, double pointX, double pointY) {
        return Math.atan2(pointX - centreX, centreY - pointY) * 180.0F / Math.PI;
    }
}

Just remove the * 180.0F / Math.PI to return the angle in radians for use in rotations.

Mark Fisher
  • 9,838
  • 3
  • 32
  • 38
  • Thanks for the testing! You could also use Math.toDegrees() and Math.toRadians() to do the conversions. – Ben Jul 21 '11 at 13:04
  • It doesn't seem to work right, probably I'm missing something. Please check my post, I've edited it with my code and values I'm getting. Thank you. – Egor Jul 21 '11 at 13:09