Finding an angle with 3 CGPoints

▼魔方 西西 提交于 2019-12-18 18:31:11

问题


In my application, a user taps 3 times and an angle will be created by the 3 points that were tapped. It draws the angle perfectly. I am trying to calculate the angle at the second tap, but I think I am doing it wrong (probably a math error). I haven't covered this in my calculus class yet, so I am going off of a formula on wikipedia.

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

Here is what I am trying:

Note: First, Second, and Third are CGPoints created at the user's tap.

        CGFloat xDistA = (second.x - third.x);
        CGFloat yDistA = (second.y - third.y);
        CGFloat a = sqrt((xDistA * xDistA) + (yDistA * yDistA));

        CGFloat xDistB = (first.x - third.x);
        CGFloat yDistB = (first.y - third.y);
        CGFloat b = sqrt((xDistB * xDistB) + (yDistB * yDistB));

        CGFloat xDistC = (second.x - first.x);
        CGFloat yDistC = (second.y - first.y);
        CGFloat c = sqrt((xDistC * xDistC) + (yDistC * yDistC));

        CGFloat angle = acos(((a*a)+(b*b)-(c*c))/((2*(a)*(b))));

        NSLog(@"FULL ANGLE IS: %f, ANGLE IS: %.2f",angle, angle);

Sometimes, it gives the angle as 1 which doesn't make sense to me. Can anyone explain why this is, or how to fix it please?


回答1:


Not sure if this is the main problem but it is a problem

Your answer gives the angle at the wrong point:

To get the angle in green (which is probably angle you want based on your variable names "first", "second" and "third), use:

CGFloat angle = acos(((a*a)+(c*c)-(b*b))/((2*(a)*(c))));




回答2:


Here's a way that circumvents the law of cosines and instead calculates the angles of the two vectors. The difference between the angles is the searched value:

CGVector vec1 = { first.x - second.x, first.y - second.y };
CGVector vec2 = { third.x - second.x, third.y - second.y };

CGFloat theta1 = atan2f(vec1.dy, vec1.dx);
CGFloat theta2 = atan2f(vec2.dy, vec2.dx);

CGFloat angle = theta1 - theta2;
NSLog(@"angle: %.1f°, ", angle / M_PI * 180);

Note the atan2 function that takes the x and y components as separate arguments and thus avoids the 0/90/180/270° ambiguity.




回答3:


The cosine formula implementation looks right; did you take into account that acos() returns the angle in radians, not in degrees? In order to convert into degrees, multiply the angle by 180 and divide by Pi (3.14159...).




回答4:


The way I have done it is to calculate the two angles separately using atan2(y,x) then using this function.

static inline double
AngleDiff(const double Angle1, const double Angle2)
{
    double diff = 0;
    diff = fabs(Angle1 - Angle2);
    if (diff > <Pi>) {
        diff = (<2Pi>) - diff;
    }
    return diff;
}

The function deals in radians, but you can change <Pi> to 180 and <2Pi> to 360




回答5:


Using this answer to compute angle of the vector:

CGFloat angleForVector(CGFloat dx, CGFloat dy) {
    return atan2(dx, -dy) * 180.0/M_PI;
}

// Compute angle at point Corner, that is between AC and BC:

CGFloat angle = angleForVector(A.x - Corner.x, A.y - Corner.y)
              - angleForVector(B.x - Corner.x, B.y - Corner.y);

NSLog(@"FULL ANGLE IS: %f, ANGLE IS: %.2f",angle, angle);


来源:https://stackoverflow.com/questions/20226804/finding-an-angle-with-3-cgpoints

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!