问题描述
平面坐标系中,已知三点坐标,求出任意两点组成的线段之间的夹角。
使用向量夹角公式
cos<夹角> = 两向量之积 / 两向量模的乘积
<夹角> = arccos( 两向量之积 / 两向量模的乘积 )
1 #include2 using std::acos; // 反余弦函数 3 using std::sqrt; // 平方根函数 4 //--------------------------------------------------------------------------- 5 6 // 点结构体的定义 7 struct TPoint : public POINT 8 { 9 TPoint() {} 10 TPoint(int _x, int _y) { x = _x; y = _y; } 11 TPoint(POINT & pt) 12 { 13 x = pt.x; 14 y = pt.y; 15 } 16 }; 17 //--------------------------------------------------------------------------- 18 19 double getAngle(TPoint pSrc, TPoint p1, TPoint p2) 20 { 21 double angle = 0.0f; // 夹角 22 23 // 向量Vector a的(x, y)坐标 24 double va_x = p1.x - pSrc.x; 25 double va_y = p1.y - pSrc.y; 26 27 // 向量b的(x, y)坐标 28 double vb_x = p2.x - pSrc.x; 29 double vb_y = p2.y - pSrc.y; 30 31 double productValue = (va_x * vb_x) + (va_y * vb_y); // 向量的乘积 32 double va_val = sqrt(va_x * va_x + va_y * va_y); // 向量a的模 33 double vb_val = sqrt(vb_x * vb_x + vb_y * vb_y); // 向量b的模 34 double cosValue = productValue / (va_val * vb_val); // 余弦公式 35 36 // acos的输入参数范围必须在[-1, 1]之间,否则会"domain error" 37 // 对输入参数作校验和处理 38 if(cosValue < -1 && cosValue > -2) 39 cosValue = -1; 40 else if(cosValue > 1 && cosValue < 2) 41 cosValue = 1; 42 43 // acos返回的是弧度值,转换为角度值 44 angle = acos(cosValue) * 180 / M_PI; 45 46 return angle; 47 } 48 //---------------------------------------------------------------------------
附录
acos函数的介绍
Header File
math.h
Category
Math Routines
Prototype
double acos(double x);
long double acosl(long double x);
Description
Calculates the arc cosine.
acos returns the arc cosine of the input value.
acosl is the long double version; it takes a long double argument and returns a long double result.
Arguments to acos and acosl must be in the range -1 to 1, or else acos and acosl return NAN and set the global variable errno to:
EDOM Domain error
Return Value
acos and acosl of an argument between -1 and +1 return a value in the range 0 to pi. Error handling for these routines can be modified through the functions _matherr_matherr and _matherrl.