1

I want to develop a kind of wheel of fortune in Java/Android. When the user touch the screen, i detect the mouvement and for each changes, i calculate the angle between the old pressure et the newest (function onScroll). I've a problem because i don't remember how i can calculate the angle between 3 points...

I develop 3 functions but each one give me a various result :

public class Test {

public static void main(String[] args) {
    Test test = new Test();

    Point center = new Point(2.26f, 2.26f);
    Point current = new Point(2.54f, 3.64f);
    Point previous = new Point(2.25f, 3.73f);

    System.out.println("1) Angle is "
            + test.function1(center, current, previous));
    System.out.println("2) Angle is "
            + test.function2(center, current, previous));
    System.out.println("3) Angle is "
            + test.function3(center, current, previous));
    System.out.println("################################");

    center = new Point(2.26f, 2.26f);
    previous = new Point(3.29f, 1.04f);
    current = new Point(0.98f, 2.25f);
    System.out.println("1) Angle is "
            + test.function1(center, current, previous));
    System.out.println("2) Angle is "
            + test.function2(center, current, previous));
    System.out.println("3) Angle is "
            + test.function3(center, current, previous));
    System.out.println("################################");

    center = new Point(226.0f, 226.0f);
    previous = new Point(225.21994f, 373.3158f);
    current = new Point(254.31085f, 364.05264f);
    System.out.println("1) Angle is "
            + test.function1(center, current, previous));
    System.out.println("2) Angle is "
            + test.function2(center, current, previous));
    System.out.println("3) Angle is "
            + test.function3(center, current, previous));
    System.out.println("################################");
}

public double function1(Point center, Point current, Point previous) {

    double ang1 = Math.atan((previous.getdY() - center.getdY())
            / (previous.getdX() - center.getdX()));
    double ang2 = Math.atan((current.getdY() - center.getdY())
            / (current.getdX() - center.getdX()));
    double rslt = ang1 - ang2;

    return Math.toDegrees(rslt) * -1;
}

private double function2(Point center, Point current, Point previous) {
    float dx = current.getdX() - center.getdX();
    float dy = current.getdY() - center.getdY();
    double a = Math.atan2(dy, dx);

    float dpx = previous.getdX() - center.getdX();
    float dpy = previous.getdY() - center.getdY();
    double b = Math.atan2(dpy, dpx);

    double diff = a - b;
    double degres = Math.toDegrees(diff);
    return degres;
}

public double function3(Point center, Point current, Point previous) {
    Point p1 = new Point(current.getdX() - center.getdX(), current.getdY()
            - center.getdY());
    Point p2 = new Point(previous.getdX() - center.getdX(),
            previous.getdY() - previous.getdY());
    double angle = Math.atan2(p1.getdY() - p2.getdY(),
            p1.getdX() - p2.getdX());

    return Math.toDegrees(angle);
}

}

I found this function on the net but i can't know which is the best.

Can you help me ?

FinalSpirit
  • 569
  • 1
  • 6
  • 17
  • The best answer would be to take real examples, and build unit tests out of them. Be wise, test well and pick the right ones. – Snicolas Aug 15 '11 at 15:24
  • take a look on this: http://stackoverflow.com/questions/1211212/how-to-calculate-an-angle-from-three-points – AlexR Aug 15 '11 at 15:26
  • What results do you get? – Ted Hopp Aug 15 '11 at 15:27
  • The Thomas example's seams to works perfectely. Now, i want to know if my angle is positive or negative. I'm looking the link to find the solution. – FinalSpirit Aug 15 '11 at 15:41

3 Answers3

9
private double angleBetween(Point center, Point current, Point previous) {

  return Math.toDegrees(Math.atan2(current.x - center.x,current.y - center.y)-
                        Math.atan2(previous.x- center.x,previous.y- center.y));
}

this first calculates the angle of center->current and center->previous against the x-axis and takes the difference between the 2

this is similar to function2

ratchet freak
  • 47,288
  • 5
  • 68
  • 106
2

Have a look here: http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm

In terms of your function2:

private double function2(Point center, Point current, Point previous) {
  float v1x = current.getdX() - center.getdX(); 
  float v1y = current.getdY() - center.getdY();

  //need to normalize:
  float l1 = Math.sqrt(v1x * v1x + v1y * v1y);
  v1x /= l1;
  v1y /= l1;

  float v2x = previous.getdX() - center.getdX();
  float v2y = previous.getdY() - center.getdY();

  //need to normalize:
  float l2 = Math.sqrt(v2x * v2x + v2y * v2y);
  v2x /= l2;
  v2y /= l2;    

  double rad = Math.acos( v1x * v2x + v1y * v2y );

  double degres = Math.toDegrees(rad);
  return degres;
}

Edit: for signed values use Math.atan2(...). Quote from the linked page:

If we want a + or - value to indicate which vector is ahead, then we probably need to use the atan2 function (as explained on this page). using:

angle of 2 relative to 1= atan2(v2.y,v2.x) - atan2(v1.y,v1.x)

Thus replace double rad = Math.acos( v1x * v2x + v1y * v2y ); with double rad = Math.atan2( v2y,v2x) - Math.atan2(v1y,v1x); and you should be fine.

Community
  • 1
  • 1
Thomas
  • 87,414
  • 12
  • 119
  • 157
  • @FinalSpirit The page I linked give's you a hint, but to make it easier I added an edit. – Thomas Aug 15 '11 at 15:46
  • Thanks but i don't understand these results :
    In first, i've this point : `Previous = Point(94.78006;219.21054) Current = Point(93.37244;225.10526) Center = Point(226.0;226.0) Calculate degres = -2.575375011820518 (good degres)` And for the next, i've this : `Previous = Point(93.37244;225.10526) Current = Point(92.43402;227.63159) Center = Point(226.0;226.0) Calculate degres = 358.9136026239169 (It's very big !!!)`
    – FinalSpirit Aug 15 '11 at 15:57
0

Create two vectors out of the points and use dot product.

SJuan76
  • 24,532
  • 6
  • 47
  • 87