c# - 方向确定算法混合左右

标签 c# algorithm

我正在研究一种算法来确定边 BC 相对于边 AB 的方向。

我已经实现了 ArcCos 确定。它几乎可以工作。它正确地确定前进并正确地确定何时需要转弯。但不能正确判断是右转还是左转。

private Direction DetermineDirectionOfV2(Vertex v1, Vertex v2, Vertex v3)
{
    if (v1 == null || v2 == null || v3 == null)
        return Direction.Forward;

    double p12 = v1.distance2D(v2);
    double p13 = v1.distance2D(v3);
    double p23 = v2.distance2D(v3);

    double p12S = p12 * p12;
    double p13S = p13 * p13;
    double p23S = p23 * p23;

    double a = p12S + p13S - p23S;
    double b = 2 * p12 * p13;

    if(b == 0.0)
         return Direction.Forward;

    double angle = Math.Acos(a / b);

    double thresh = 0.1;
    if(angle >= -thresh && angle <= thresh)
    {
        return Direction.Forward;
    }
    else if (angle > 0 && angle < Math.PI)
    {
        return Direction.Right;
    }
    else
    {
        return Direction.Left;
    }

}

我不确定问题出在哪里,但我认为这可能会告诉我角度 ABC,而不是 BC 相对于 AB 的角度。

在左转的情况下,我得到大约 1.1 弧度的角度是错误的。它应该至少 > 3.14 弧度或 -1.1 弧度。

有什么问题吗?

这 3 个顶点:

//x,y,z  (z is unused)
            v1 = new Vertex(0.0f, 0.0f, 0.0f,"");
            v2 = new Vertex(0.0f, -10.0f, 0.0f, "");
            v3 = new Vertex(5.0f, -10.0f, 0.0f, "");

给出一个 0.46 弧度的角,实际上它应该是 4.71238898 弧度,因为从 AB 的角度来看,BC 形成一个 270 度角。

谢谢

例子

如果我们有这样的点:

A


B       C

这应该产生 270 度或 4.7rad,因为如果我们从 A 走到 B,我们将左转到达 C。

最佳答案

首先,你的分子符号错了。余弦规则是

c² = a² + b² - 2*a*b*cos(alpha)

因此,

cos(alpha) = (c² - a² - b²) / (2 * a * b)

在你的术语中意味着:

angle = Math.Acos(p13S - p12S - p23S / (2 * p12 * p13));

很遗憾,这不能解决您的问题。

余弦规则给出了两个导管之间的最小角度。您只处理长度,因此会丢失方向信息。 acos 函数返回 0 到 π 范围内的角度,但您需要从 -π 到 π 的整个圆。

你的问题没有说清楚,但我猜你在 x,y 平面上有二维向量。 (没有引用平面,左右方向就没有意义。)

如果是这样,您可以通过计算 AB 和 BC 的叉积来确定您是左转还是右转。然后检查 z 分量的符号:

private Direction dir(Vertex v1, Vertex v2, Vertex v3)
{
    double ax = v2.x - v1.x;
    double ay = v2.y - v1.y;
    double bx = v3.x - v2.x;
    double by = v3.y - v2.y;

    double z = ax*by - ay*bx;

    if (z > 0.0) return Direction.Left;
    if (z < 0.0) return Direction.Right;
    return Direction.Forward;
}

0.0 的检查当然应该使用合适的阈值进行,就像在您的原始代码中一样。然而,该阈值取决于向量的长度,因为:

|a x b| = |a| * |b| * sin(angle)

此外,前进方向也适用于后退。如果你想区分那些方向,你可以检查标量积是否

ax*bx + ay*by

是正向(Forward)或负向(Backward)。

关于c# - 方向确定算法混合左右,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26552373/

相关文章:

c# - 如何使用 Xamarin-Forms 下载图像并将其保存在本地存储中?

algorithm - 如何将一个矩形缩放到另一个矩形内可能的最大尺寸?

algorithm - 怎么解释 "exact cover "的意思

c# - 在不使用指针的情况下编辑文本文件中的一行?

c# - Web API 项目在部署时不会运行 - 无法加载文件或程序集 'Newtonsoft.Json,版本 = 4.5.0.0

java - 从抽象泛型到非抽象非泛型

algorithm - 在允许交换列的情况下找到最大的 1 矩形

algorithm - 检查二叉树是否是另一棵二叉树的子树的有效算法

c# - 通过unity从服务器获取数据

c# - LINQ 如何向这条语句添加一个 order by?