Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c acosf()返回NaN_Objective C_C_Trigonometry - Fatal编程技术网

Objective c acosf()返回NaN

Objective c acosf()返回NaN,objective-c,c,trigonometry,Objective C,C,Trigonometry,我有一个用Objective C编写的iPhone应用程序,我正在收集用户在屏幕上绘制的接触点,以创建路径 我希望能够精简此数据。我的目标之一是通过检查点的角度是否超过某个阈值来实现这一点。例如,如果我取直线上的任意三个相邻点a,b,c,如果角度ABC在180度的5度范围内,那么我可以删除点b,而不会对直线造成太大影响 我试图通过将三角形ABC分成两个直角三角形来实现这一点。然后我用acosf()求a(BAC)处的角度和c(BCA)处的角度。然后我可以从180减去这两个角度,得到ABC的角度 我

我有一个用Objective C编写的iPhone应用程序,我正在收集用户在屏幕上绘制的接触点,以创建路径

我希望能够精简此数据。我的目标之一是通过检查点的角度是否超过某个阈值来实现这一点。例如,如果我取直线上的任意三个相邻点a,b,c,如果角度ABC在180度的5度范围内,那么我可以删除点b,而不会对直线造成太大影响

我试图通过将三角形ABC分成两个直角三角形来实现这一点。然后我用acosf()求a(BAC)处的角度和c(BCA)处的角度。然后我可以从180减去这两个角度,得到ABC的角度

我的问题是acosf()经常返回NaN。当它返回一个数字时,我已经在计算器上检查过了,值是正确的。我尝试过返回NaN的值,但它们在计算器上也不起作用。我知道这是因为它们超出了acosf()的范围。我怎样才能避免这种情况

以下是我正在使用的代码:

float prevToNextDist = ccpDistance(prevPoint.location, nextPoint.location);
    //work out the next point angle
    float pointToNextDistance = ccpDistance(point.location, nextPoint.location);
    float nextPointAngle = acosf((prevToNextDist/2)/pointToNextDistance);
    nextPointAngle = CC_RADIANS_TO_DEGREES(nextPointAngle);

    //work out the previous point angle
    float prevToPointDistance = ccpDistance(prevPoint.location, point.location);
    float prevPointAngle = acosf((prevToNextDist/2)/prevToPointDistance);
    prevPointAngle = CC_RADIANS_TO_DEGREES(prevPointAngle);

    //work out the point angle
    float pointAngle = 180 - nextPointAngle - prevPointAngle;

有什么想法吗?

1/浮点不是默认的浮点类型,它是双精度的。float可能足以存储,即使这样,您也应该使用double进行计算

2/如果没有CPPDestance的代码,很难确定,但我认为它不会像您认为的那样计算三角形的边(我认为如果没有3个点作为参数,这是不可能的)

3/如果您的点是(xa,ya)、(0,0)和(xb,yb),并且您正在寻找(0,0)处的角度(如果不是这样,只需更改坐标即可),则您正在寻找的角度为

acos((xa*xb+ya*yb)/sqrt((xa*xa+ya*ya)*(xb*xb+yb*yb)))

acos(x)
acosf(x)
的一个经典问题是确保参数在范围内


有时计算出的
x
刚好超出范围-1好的,我已经解决了这个问题,所以我发布了我的解决方案,供任何可能无意中发现这个趋势并发现它有用的人使用。虽然我使用的是我自己的解决方案,但chux和AProgrammers的建议都很好,帮助我提出了解决方案,所以我对他们都投了赞成票

正如chux所建议的,atan2()是比acosf()更好的函数。以下是基于角度显示点数据的代码:

#define kAngleTolerance 3

    double prevPointAngle = atan2(point.location.y - prevPoint.location.y, point.location.x - prevPoint.location.x) * 180.0f / M_PI;
    prevPointAngle = fabs(prevPointAngle);

    double nextPointAngle = atan2(nextPoint.location.y - point.location.y, nextPoint.location.x - point.location.x) * 180.0f / M_PI;
    nextPointAngle = fabs(nextPointAngle);

    double pointAngle = 180 - fabs(nextPointAngle - prevPointAngle);

    if (pointAngle < 180 + kAngleTolerance && pointAngle > 180 - kAngleTolerance ) {
        point.remove = YES;
        [pointsToRemove addObject:point];
    }
#定义kAngleTolerance 3
双prevPointAngle=atan2(点位置.y-点位置.y,点位置.x-点位置.x)*180.0f/MμPI;
prevPointAngle=fabs(prevPointAngle);
双nextPointAngle=atan2(nextPoint.location.y-point.location.y,nextPoint.location.x-point.location.x)*180.0f/MμPI;
nextPointAngle=fabs(nextPointAngle);
双点角=180-fabs(下一点角-上一点角);
if(点角<180+角度公差和点角>180-角度公差){
point.remove=是;
[pointsToRemove addObject:point];
}

注意:
晶圆厂(下一个点角-上一个点角)
的范围从0到360。你的代码的其余部分是为那个范围准备的吗?BTW,建议你的答案指出你为什么使用<代码> ATAN2F()/代码>而不是<代码> ATAN2()/<代码>,它和你的其他变量一起显示为<代码>双< /代码>。BTW:考虑一个非常不同的原始问题的方法:对于2点之间的每个点,计算该中心点到由两个端点形成的线段的距离。对所有这些点执行此操作,并消除接近的点。关于这个问题的数学运算不涉及trig,而且相当简单,但我必须查找它。在这种情况下,atan2()确实是首选函数,因为它返回一个double,谢谢您指出,我已经编辑了我的答案。您建议检查测试点和两个相邻点的中心点之间的距离,这是一个好主意。我有一种感觉,它很可能也会更快,我一定会尝试一下。再次感谢您的输入。次要点:它不是相邻2的点和中心点之间的距离,而是距离线段最近的点和距离。顺便说一句:你们可以找一个最小的距离平方,而不是距离。我想你们不会记得高中时的一切吧!在我的案例中,我不得不使用acos(fabs(相邻)/斜边)
#define kAngleTolerance 3

    double prevPointAngle = atan2(point.location.y - prevPoint.location.y, point.location.x - prevPoint.location.x) * 180.0f / M_PI;
    prevPointAngle = fabs(prevPointAngle);

    double nextPointAngle = atan2(nextPoint.location.y - point.location.y, nextPoint.location.x - point.location.x) * 180.0f / M_PI;
    nextPointAngle = fabs(nextPointAngle);

    double pointAngle = 180 - fabs(nextPointAngle - prevPointAngle);

    if (pointAngle < 180 + kAngleTolerance && pointAngle > 180 - kAngleTolerance ) {
        point.remove = YES;
        [pointsToRemove addObject:point];
    }