C# 结果范围为0-360的两个三维向量之间的角度

C# 结果范围为0-360的两个三维向量之间的角度,c#,math,3d,C#,Math,3d,我正在寻找一种方法来计算被视为两个向量的三个点之间的角度(见下文): 如果您给出以下几点: 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,

我正在寻找一种方法来计算被视为两个向量的三个点之间的角度(见下文):

如果您给出以下几点:

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。我怎样才能做到这一点呢?

你在找这个吗

θ_弧度=arccos((​P⋅Q) /​(∣P∣∣Q∣)​ ​​) 用向量P和Q

θ_弧度=θ_度*π/180

编辑0-360范围

angle = angle * 360 / (2*Math.PI);
if (angle < 0) angle = angle + 360;
angle=angle*360/(2*Math.PI);
如果(角度<0)角度=角度+360;

答案是提供一个参考上方向向量:

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;
}
三个点之间的公共静态浮动角度(点3D[]点,矢量3D向上)
{
var v1=点[1]-点[0];
var v2=点[2]-点[1];
var cross=Vector3D.叉积(v1,v2);
var dot=Vector3D.DotProduct(v1,v2);
变量角度=数学Atan2(交叉长度,点);
var测试=向量3D.DotProduct(向上,交叉);
如果(试验<0.0)角度=-角度;
返回(浮动)角;
}

这来自这里:

不要从Math.PI减去180度。你的结果是0到360度,所以当你从180度减去时,你得到的结果是+180到-180。在3D空间中,两个向量之间的角度仅定义在0到180度之间。在什么情况下你想要180到360度之间的答案?这很容易理解在二维空间中定义为有向角或有符号角,但这不扩展到三维空间。这是我的第一个解决方案,但它也有相同的问题。它的角度限制为0-180。弧度角位于[-π;π]间隔和π弧度角是180度,所以是的,这是你的极限0-180。但我给你展示了一个从弧度到度的转换公式。arccos的结果范围是0到π(不是π*2)。因此我提到的极限是180。
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;
}