Math function request.

  ... the case you feel the need for a new feature or want to submit one.

Math function request.

Postby darklord » Sat Dec 18, 2010 3:27 pm

Hello,

I was wondering if the Math Utils library could be extended with a method that calculates the angle between two points. E.a. the angle between x=100 y=150 and x=125 y=200

I currently use the following method, so you could use it.. however i'm not 100% sure it's correct.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. mStartX = 100;
  3. mStartY = 150;
  4. mEndX = 125;
  5. mEndY = 200;
  6.  
  7. mDeltaX = mStartX - mEndX;
  8. mDeltaY = mStartY - mEndY;
  9.  
  10. mAtan2=Math.atan2(mDeltaX,mDeltaY);
  11. mRadToDeg = (180f/Math.PI);
  12.  
  13. mAngle= (float) Math.abs(mAtan2*mRad);
  14.  
Parsed in 0.012 seconds, using GeSHi 1.0.8.4
darklord
 
Posts: 121
Joined: Thu Aug 12, 2010 2:48 pm

Re: Math function request.

Postby HexWave » Sat Dec 18, 2010 9:34 pm

Your function is correct. There is a small issue with abs though since atan2 returns an angle in radians between -PI and PI. Abs will return the same angle if you're on the left or right of the Y axis. To clarify there is no such thing as an angle between two points. It's the angle between the fixed X axis and the vector formed by the two points that you're calculating.

Here is a patch that adds a few things to MathUtils. I also changed distance to static, which is a useful function to get the distance between two points. I hadn't noticed this was here before and had written it a few times in my code :)

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. --- a/src/org/anddev/andengine/util/MathUtils.java      Tue Nov 30 12:19:27 2010 +0100
  2. +++ b/src/org/anddev/andengine/util/MathUtils.java      Sat Dec 18 14:28:50 2010 -0500
  3. @@ -191,11 +191,66 @@
  4.                 return Math.max(pMinValue, Math.min(pMaxValue, pValue));
  5.         }
  6.  
  7. -       public float distance(final float pX1, final float pY1, final float pX2, final float pY2){
  8. +       public static float distance(final float pX1, final float pY1, final float pX2, final float pY2){
  9.                 final float dX = pX2 - pX1;
  10.                 final float dY = pY2 - pY1;
  11.                 return FloatMath.sqrt((dX * dX) + (dY * dY));
  12.         }
  13. +
  14. +       /**
  15. +        * Return the angle in radians from the fixed X axis and the vector x1,y1 x2,y2
  16. +        * The angle is normalized between -PI and PI. 0 is parallel to the fixed Y axis.
  17. +        * Positive angles from 0 to PI/2 are in the top right quadrant
  18. +        * Positive angles from PI/2 to PI are in the bottom right quadrant
  19. +        * Negative angles from 0 to -PI/2 are in the top left quadrant
  20. +        * Negative angles from -PI/2 to -PI are in the bottom left quadrant
  21. +        *
  22. +        * @param pX1 The X coordinate of the first point
  23. +        * @param pY1 The Y coordinate of the first point
  24. +        * @param pX2 The X coordinate of the second point
  25. +        * @param pY2 The Y coordinate of the second point
  26. +        * @return Angle between the X axis and the vector specified by pX1,pY1 pX2,pY2
  27. +        */
  28. +       public static float angleAxisToVector(final float pX1, final float pY1, final float pX2, final float pY2)
  29. +       {
  30. +               final float dX = pX2 - pX1;
  31. +               final float dY = pY2 - pY1;
  32. +               return (float)Math.atan2(dX, dY);
  33. +       }
  34. +
  35. +       /**
  36. +        * Return the angle in degrees from the fixed X axis and the vector x1,y1 x2,y2
  37. +        * The angle is normalized between 0 and 360. 360.00 is not included (360.00 == 0 degrees)
  38. +        *
  39. +        * @param pX1 The X coordinate of the first point
  40. +        * @param pY1 The Y coordinate of the first point
  41. +        * @param pX2 The X coordinate of the second point
  42. +        * @param pY2 The Y coordinate of the second point
  43. +        * @return Angle between the X axis and the vector specified by pX1,pY1 pX2,pY2
  44. +        */
  45. +       public static float angleAxisToVectorDegrees(final float pX1, final float pY1, final float pX2, final float pY2)
  46. +       {
  47. +               final float angleRad = angleAxisToVector(pX1, pY1, pX2, pY2);
  48. +
  49. +               return normalAngleDegrees(radToDeg(angleRad));
  50. +       }
  51. +
  52. +
  53. +       /**
  54. +        * Normalize an angle in degrees between 0 and 360
  55. +        * The value 360.00 itself is not included in the output range.
  56. +        *
  57. +        * @param pDeg Angle to normalize
  58. +        * @return Normalized angle between 0 and 360
  59. +        */
  60. +       public static float normalAngleDegrees(final float pDeg)
  61. +       {
  62. +               final float pMod = pDeg % 360;
  63. +               if(pMod >= 0)
  64. +                       return pMod;
  65. +               return pMod + 360;
  66. +       }
  67. +
  68.  
  69.         // ===========================================================
  70.         // Inner and Anonymous Classes
  71.  
Parsed in 0.013 seconds, using GeSHi 1.0.8.4


Use angleAxisVectorDegrees to get an angle between 0 and 360. 0 degrees is collinear to the positive Y axis.

Cheers!
Matt
HexWave
HexWave
 
Posts: 22
Joined: Sat Nov 13, 2010 12:12 am

Re: Math function request.

Postby darklord » Mon Dec 20, 2010 12:53 pm

Thanks for explaining that! And even a bigger thanks for this submit. I hope it gets added soon. :D
darklord
 
Posts: 121
Joined: Thu Aug 12, 2010 2:48 pm

Re: Math function request.

Postby Biggz » Thu Feb 03, 2011 11:00 pm

Have I really just spent ages solving this in a different way when this thread was already here? Are there any differences other than I used a longer equation? :?
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.    //calculate the angle between the vertical y axis (vector 0, 10) and the given vector
  2.     private float spriteAngleDeg(int X, int Y) {
  3.         int vX = 0, vY = 10;
  4.         double angle = Math.toDegrees(Math.acos(((X * vX)+(Y * vY)) / (Math.sqrt((Math.pow(X,2)+Math.pow(Y,2))) * Math.sqrt((Math.pow(vX,2)+Math.pow(vY,2)))))) ;
  5.        
  6.         //The angle returned for X<0 is the angle from the Y-Axis anti-clockwise
  7.         //and for X>0 the angle is from the Y-axis clockwise.
  8.         //This is so the sprite once rotated by angle doesn't look inverted when tilting right.
  9.         if (X>0){
  10.                 double temp = 360-angle;
  11.                 angle=temp;            
  12.         }
  13.         return (float) angle;
  14.     }
Parsed in 0.011 seconds, using GeSHi 1.0.8.4
Biggz
 
Posts: 4
Joined: Wed Jan 26, 2011 10:40 pm


Return to Features

Who is online

Users browsing this forum: No registered users and 3 guests