在我的应用程序中,用户点击3次,并且点击的3个点将创建一个角度。它完美地绘制了角度。我想在第二次敲击时计算角度,但我认为我做错了(可能是数学错误)。我还没有在我的微积分课程中介绍过这个,所以我将在维基百科上找到一个公式。
http://en.wikipedia.org/wiki/Law_of_cosines
以下是我的尝试:
注意:第一个,第二个和第三个是在用户点击时创建的CGPoints
。
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);
有时,它会将角度设为1,这对我来说没有意义。谁能解释为什么会这样,或者如何解决它?
答案 0 :(得分:9)
不确定这是否是主要问题,但这是一个问题
你的答案给出了错误点的角度:
要获得绿色的角度(根据您的变量名称“first”,“second”和“third”,这可能是您想要的角度),请使用:
CGFloat angle = acos(((a*a)+(c*c)-(b*b))/((2*(a)*(c))));
答案 1 :(得分:4)
这是一种规避余弦定律的方法,而是计算两个向量的角度。角度之间的差异是搜索值:
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);
注意atan2
函数将x和y分量作为单独的参数,从而避免了0/90/180/270°的模糊性。
答案 2 :(得分:1)
余弦公式实现看起来正确;你是否考虑到acos()
以弧度返回角度,而不是度数?为了转换为度数,将角度乘以180并除以Pi(3.14159 ...)。
答案 3 :(得分:1)
我这样做的方法是使用atan2(y,x)
然后使用此函数分别计算两个角度。
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;
}
该函数以弧度为单位,但您可以将<Pi>
更改为180,将<2Pi>
更改为360
答案 4 :(得分:0)
使用this answer计算向量的角度:
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);