1.1 三角函数概算
三角函数(trigonometric function)是从直角三角形发展起来的一种角度和边的对应关系。常见的三角函数有sin、cos、tan三个函数,反三角函数有arcsin、arccos、arctan三个反三角函数(反三角函数也有写为sin-1、cos-1、tan-1方式,表示相反的计算,可以通过三角函数值反算出对应的角度)。
三角形的任意一个角度的范围是(0°,180°),可以完美的解决三角形的角度和边的计算关系。
1.2 三角函数的局限
其局限性在于,我们在2D应用中,经常会在[0°,360°)的范围内需要使用三角函数,而此时会出现两个角度的三角函数是一样的,对应的一个超过180的角度在计算反三角函数时也无法达到我们的预期。
1.3 局限性分析
三角函数的局限就在于它的角度范围在计算超过180°时出现的不能一一对应的关系,我们经常需要进行其他判断后才能准确知道在2D环境下其对应的真实角度。
如:
cos(60°)=0.5,arccos(0.5)=60°
cos(300°)=0.5, arcsin(0.5)=60°
但是我们在程序中经常需要使用整个圆角角度,为减少复杂性,建议将【三角函数】升级为【圆角函数】
2.1 在2D空间中,三角函数值隐藏了x y的部分正负属性。造成这种根本原因是我们已经习惯认为“负负得正”。
其实,(-3)×(-3) =?= 3 × 3 是一个不太严谨的说法。
要保留x y的方向,最简单的办法就是圆角函数不要采用x和y之间的计算值,而是直接采用x和y。
在许多新的语言中,都有(x,y)元数据格式,但是在传统计算机语言中,并没有这种格式。
为此,本例程采用QT中的QPoint来作为三角函数的输入值。建立QPoint和角度之间的关系。
2.2 圆心角的单位
角度(Agree)有两种表示方式Degrees和Radians,考虑到我们在程序中0°、90°、180°、270°,分别对应前后左右,会经常用到。而这四个方向的角度用弧度表示并不是很方便,所以我们建立的圆角函数直接使用度数。
2.3 本例程直接利用qt中作为依托,x,y类型为qreal缺省等同于double,角度采用double。
3.1 函数名设置
新词汇:圆角函数 Circlemetric Functions
函数名:DegreesToPoint、PointToDegrees两个函数名。
返回的点坐标均位于半径为“1”的圆上。
返回角度范围为[0, 360°)
3.2 函数体
/***
使用到的qt中的三角函数
qreal qSin(qreal v)
qreal qCos(qreal v)
qreal qTan(qreal v)
qreal qASin(qreal v)
qreal qACos(qreal v)
qreal qATan(qreal v)
***/#include
QPointF DegreesToPoint(double degrees);
double PointToDegrees(QPointF pos);QPointF DegreesToPoint(double degrees)
{while (degrees < 0.0) degrees += 360.0;while (degrees > 360.0) degrees -= 360.0;if (degrees == 0.0){return QPointF(1.0, 0.0);}if (degrees == 90.0){return QPointF(0.0, 1.0);}if (degrees == 180.0){return QPointF(-1.0, 0.0);}if (degrees == 270.0){return QPointF(0.0, -1.0);}double r = qDegreesToRadians(degrees);return QPointF(qCos(r), qSin(r));
}
double PointToDegrees(QPointF pos)
{if (pos == QPointF(0.0, 0.0)) return 0;if (pos.x() == 0.0){if (pos.y() > 0) return 90.0;else return 270.0;}else if (pos.y() == 0.0){if (pos.x() > 0) return 0.0;else return 180.0;}double r = qAtan(pos.y / pos.x);if (pos.x() > 0.0){//M_PI_4 Quarter M_PI, π / 4if (pos.y() < 0.0) r += M_PI * 2;}else{ //pos.x() < 0.0r += M_PI;}return qRadiansToDegrees(r);
}
4.1 测试结果
DegreesToPoint(0): QPointF(1,0)
DegreesToPoint(30): QPointF(0.866025,0.5)
DegreesToPoint(135): QPointF(-0.707107,0.707107)
DegreesToPoint(180): QPointF(-1,0)
DegreesToPoint(225): QPointF(-0.707107,-0.707107)
DegreesToPoint(330): QPointF(0.866025,-0.5)
PointToDegress(QPointF(0,0)): 0
PointToDegress(QPointF(4,5)): 51.3402
PointToDegress(QPointF(20,0)): 0
PointToDegress(QPointF(-5,-2)): 201.801
PointToDegress(QPointF(-5,2)): 158.199
PointToDegress(QPointF(0,-12)): 270
PointToDegress(QPointF(15,-5)): 341.565
PointToDegress(QPointF(1000,-0.1)): 359.994
qAtan2(-0.1,1000): -0.0001
可以看出,计算无误,基本可以解决。
4.2 其他
因为QT本身有函数
qreal qAtan2(qreal y, qreal x)
Returns the arctangent of a point specified by the coordinates y and x. This function will return the angle (argument) of that point.
返回由坐标y和x指定的点的arctan值。此函数将返回该点的角度(参数)。
测试该函数如下:
qRadiansToRadians(qAtan2(1,1)): 45 I象限
qRadiansToRadians(qAtan2(-1,1)): -45 IV象限
qRadiansToRadians(qAtan2(-1,-1)): -135 III象限
qRadiansToRadians(qAtan2(1,-1)): 135 II象限
可以看出,该函数返回的角度是-180°到180°。同时该函数的参数是y在先,x在后。
如果要使用qAtan2这个函数,需要对角度的换算进行重新修订,这里不再赘述。
上一篇:求大师帮我测测(姻缘)