解析几何(一)两个向量的夹角解法

时间:2023-02-10 17:30:08
最近在项目中需要判断点和四边形关系,我的算法中涉及到了求解线段夹角的问题,于是编写了如下代码。

问题描述
平面坐标系中,已知三点坐标,求出任意两点组成的线段之间的夹角。
 

解析几何(一)两个向量的夹角解法

使用向量夹角公式
cos<夹角> = 两向量之积 / 两向量模的乘积
<夹角> = arccos( 两向量之积 / 两向量模的乘积 )
 
 1 #include <cmath>
2 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.
 
下一期准备将点和四边形关系的代码和思路贴出来。欢迎大家提出意见,不胜感激~~~