我正在寻找一种方法来计算被视为两个向量的三个点之间的角度(见下文):
using System.Windows.Media.Media3D;
public static float AngleBetweenThreePoints(Point3D[] points)
{
var v1 = points[1] - points[0];
var v2 = points[2] - points[1];
var cross = Vector3D.CrossProduct(v1, v2);
var dot = Vector3D.DotProduct(v1, v2);
var angle = Math.PI - Math.Atan2(cross.Length, dot);
return (float) angle;
}
如果你给出以下几点:
var points = new[]
{
new Point3D(90, 100, 300),
new Point3D(100, 200, 300),
new Point3D(100, 300, 300)
};
或以下:
var points = new[]
{
new Point3D(110, 100, 300),
new Point3D(100, 200, 300),
new Point3D(100, 300, 300)
};
你得到相同的结果。我可以看到函数中的交叉积在第一种情况下返回(0,0,10000),在第二种情况下返回(0,0,-10000),但是这个信息会因为cross.Length而丢失,而这种信息永远不会返回-ve结果
我正在寻找的结果范围0 - 360不限于0 - 180.我如何实现这一目标?
答案 0 :(得分:1)
你在找这个吗?
θ_radian= arccos((P⋅Q)/(| P || Q |))与向量P和Q
θ_radian=θ_degree*π/ 180
编辑0-360范围
angle = angle * 360 / (2*Math.PI);
if (angle < 0) angle = angle + 360;
答案 1 :(得分:0)
答案是提供参考UP向量:
public static float AngleBetweenThreePoints(Point3D[] points, Vector3D up)
{
var v1 = points[1] - points[0];
var v2 = points[2] - points[1];
var cross = Vector3D.CrossProduct(v1, v2);
var dot = Vector3D.DotProduct(v1, v2);
var angle = Math.Atan2(cross.Length, dot);
var test = Vector3D.DotProduct(up, cross);
if (test < 0.0) angle = -angle;
return (float) angle;
}