角度
计算两条线段之间的夹角
1. 计算两点间距离公式
d=\sqrt{(x2-x1)^2+(y2-y1)^2}
其中(x1,y1) 是线段的起点,(x2,y2) 是线段的终点
2.余弦定理
c^2 = a^2 + b^2 - 2ab\cos(\theta)
其中 a, b, c 分别是三角形的三边,\theta 是 a 和 b 之间的夹角。从余弦定力中解出\cos(\theta):
\cos(\theta)=\frac{a^2+b^2-c^2}{2ab}
3.反余弦函数
\theta = \arccos\left(\frac{a^2 + b^2 - c^2}{2ab}\right)
4.角度转换
\theta_{\text{degrees}} = \theta_{\text{radians}} \times \frac{180}{\pi}
代码实现
// Calculate angle
double a = Math.Sqrt(Math.Pow((origin.X - x1.X),2) + Math.Pow((origin.Y - x1.Y),2));
double b = Math.Sqrt(Math.Pow((origin.X - x2.X),2) + Math.Pow((origin.Y - x2.Y),2));
double c = Math.Sqrt(Math.Pow((x2.X - x1.X),2) + Math.Pow((x2.Y - x1.Y),2));
double cTheta = (a * a + b * b - c * c) / (2 * a * b);
double theta = Math.Acos(cTheta) * 180 / Math.PI;
圆弧上的点
实际程序中需要通过计算角度的正弦值(得通过向量来计算)来判断角度是否处于水平轴下方。
5.计算起始角度
反正切计算线段与水平坐标轴的夹角
\theta_0 = \arctan\left(\frac{y_2 - y_1}{x_2 - x_1}\right)
其中(x1,y1) 是线段的起点,(x2,y2) 是线段的终点
6.正弦值计算
向量叉积(也称为外积或向量积)的基本性质之一:向量叉积的结果是一个向量,其等于两个向量的模长乘以它们之间夹角的正弦值
通过两个向量的叉积算法(得出平行四边形的面积)来计算两个向量之间的夹角正弦值。
三角形面积\times2=|\vec{u}||\vec{v}|\times\sin(\theta)
\sin{(\theta)}=\frac{|\vec{u} \times \vec{v}|}{|\vec{u}||\vec{v}|}
向量计算:
u=(x2-x1,y2-y1) \\ \ \ \ \ \ \ v=(x3-x1,y3-y1)
向量叉积:
\vec{u}\times\vec{v}=u_xv_y-u_yv_x
向量的模(长度):
最后得出公式:
\sin(\theta) = \frac{(x_2 - x_1)(y_3 - y_1) - (y_2 - y_1)(x_3 - x_1)}{a \times b}
其中(x1,y1)是线段a和线段b的起点,(x2,y2) 是线段a 的终点,(x3,y3)是线段b的终点
7. 圆弧上点的坐标计算
其中, (x_{\text{center}}, y_{\text{center}}) 是圆心坐标,r 是圆的半径, \theta 是从圆心到点的角度
代码实现
double r=25;//半径
//起始角度
double theta0 = Math.Atan((origin.Y - x1.Y) / (x1.X - origin.X + 1e-10)) * 180 / Math.PI;
var pointList = new List<System.Windows.Point>();//保存圆弧上的点
//计算正弦值
double sin_ab = ((x1.X - origin.X) * (x2.Y - origin.Y) - (x1.Y - origin.Y) * (x2.X - origin.X)) / (a * b);
if (sin_ab <= 0)
{ //水平轴上方
for (double delta = 0; delta <= theta; delta++)
{
double th = delta + theta0;
pointList.Add(new System.Windows.Point(origin.X + r * Math.Cos(th * Math.PI / 180), origin.Y - r * Math.Sin(th * Math.PI / 180)));
}
}
else
{
for (double delta = -theta; delta <= 0; delta++)
{
double th = delta + theta0;
pointList.Add(new System.Windows.Point(origin.X + r * Math.Cos(th * Math.PI / 180), inoriginiP.Y - r * Math.Sin(th * Math.PI / 180)));
}
}