Incorrect angle, wrong rating.

I need to calculate the angle between 3 points. To do this, I do the following:

  • Take 3 points (previous, current and next, within the loop)
  • Calculate the distance between points using Pythagoras
  • Calculate the angle using Math.acos

It seems to be great for figures without angels more than 180 degrees, however, if the shape has such an angle, it calculates the short side. Here is an illustration to show what I mean (red values ​​are wrong):

A scatch illustrating what goes wrong with the calculations

This is the code that performs the calculations:

 // Pythagoras for calculating distance between two points (2D) pointDistance = function (p1x, p1y, p2x, p2y) { return Math.sqrt((p1x - p2x)*(p1x - p2x) + (p1y - p2y)*(p1y - p2y)); }; // Get the distance between the previous, current and next points // vprev, vcur and vnext are objects that look like this: // { x:float, y:float, z:float } lcn = pointDistance(vcur.x, vcur.z, vnext.x, vnext.z); lnp = pointDistance(vnext.x, vnext.z, vprev.x, vprev.z); lpc = pointDistance(vprev.x, vprev.z, vcur.x, vcur.z); // Calculate and print the angle Math.acos((lcn*lcn + lpc*lpc - lnp*lnp)/(2*lcn*lpc))*180/Math.PI 

Something is wrong in the code, I forgot to do something, otherwise it will be completely different?

+7
javascript math angle
source share
3 answers

That's where your math and calculations are perfect. Your job is with the same problem that most people do on calculators that are oriented. What I would do is find out if the point lies to the left or right of the vector created by the first two points using this code, which I found from

Determine which side of the line the point is.

 isLeft = function(ax,ay,bx,by,cx,cy){ return ((bx - ax)*(cy - ay) - (by - ay)*(cx - ax)) > 0; } 

Where ax and ay make up your first point bx your second and cx cy your third.

if it's on the left, add 180 to your corner

+4
source share

I have a working, but not necessarily brief example of how this might work:

 var point1x = 0, point1y = 0, point2x = 10, point2y = 10, point3x = 20, point3y = 10, point4x = 10, point4y = 20; var slope1 = Math.atan2(point2y-point1y,point2x-point1x)*180/Math.PI; var slope2 = Math.atan2(point3y-point2y,point3x-point2x)*180/Math.PI; var slope3 = Math.atan2(point4y-point3y,point4x-point3x)*180/Math.PI; alert(slope1); alert(slope2); alert(slope3); var Angle1 = slope1-slope2; var Angle2 = slope2-slope3; alert(180-Angle1); alert(180-Angle2); 

(see http://jsfiddle.net/ZUESt/1/ )

To explain a few steps, the slopeN variables are the slopes of the individual line segments. AngleN is the number rotated on each connection (i.e., point N + 1). A positive angle is a turn to the right and a negative angle to the left.

You can then subtract this angle from 180 to get the actual internal angle you want.

It should be noted that this code, of course, can be compressed and that five lines simply output the variables to see what happens. I will let you worry about optimizing it for your own use, as this is proof of concept.

+1
source share

You need to check the boundary conditions (apparently, if the points are collinear) and apply the correct calculation to find the angle. In addition, a triangle cannot have any (internal) angle exceeding 180 degrees. The sum of the angle of the triangle is 180 degrees.

0
source share

All Articles