如何找到路径上离另一点最近的位置

3

enter image description here

如图所示,点的位置是必需的。目标和障碍物的位置是动态的,但机器人的位置可以被视为宇宙的中心。到目前为止,我们所做的是:

float m = calculate_m();
float d = calculate_d(nearest_obstacle, m);
teta = (float)calculate_angle(d, nearest_obstacle);

float calculate_m()
{
    float m = (player.position.z - winning_state.position.z )/(player.position.x - winning_state.position.x);
    return m;
}

float calculate_d(Transform nearest_obstacle,float m)
{

    float b;
    b = (-1 * player.position.z) + (m * player.position.x);
    //changed: we remove || absolute value so it gives -90 90 degree  ||
    float d = (nearest_obstacle.position.z - (m * nearest_obstacle.position.x) + b) / (Mathf.Sqrt(Mathf.Pow(m, 2) + Mathf.Pow(1, 2)));
    return d;
}

float calculate_angle(float d,Transform nearest_obstacle)
{

    float pw_distance=my_distance(player.position.x,nearest_obstacle.position.x,player.position.z,nearest_obstacle.position.z);
    float mycalcInRadians = Mathf.Asin(d/pw_distance);
    float mycalcInDegrees = mycalcInRadians * 180 / Mathf.PI;
    return  mycalcInDegrees;
}

float my_distance(float x1,float x2,float z1,float z2)
{
    return Mathf.Sqrt (Mathf.Pow(x1-x2,2)+Mathf.Pow(z1-z2,2));
}

我现在需要的是给我点的位置的公式。

为了让我的问题更清晰,请参见以下图示和描述。

enter image description here

有一条线段叫做A。场景中有一个点叫做O。我想要从O到A画一条直线,使得它们交叉时交点成为90度角。此外,我想知道交点在哪里。我想在Unity中实现这个功能,所需的是一个公式。

提前感谢你。


2
Theta是哪个角度?它是在x轴和机器人目标之间还是在机器人障碍和机器人目标之间? - Bizhan
2
你的问题缺少关键信息和问题描述。看起来你已经完成了大部分工作,但没有提供信息。每个函数都是做什么的?你能缩小范围吗? - Bizhan
1
请澄清一下,您是否可以使用Unity提供的常见向量操作方法,还是必须手动编写所有步骤? - Serlite
1
teta是theta。m是斜率。d是什么? - Bizhan
1
这就是为什么我想让你简化的原因。在所有无关和未解释的信息中,我找不到你的问题。我甚至无法确定这是一个数学问题还是编程问题!我正在看图片,但我找不到O或A。 - Bizhan
显示剩余6条评论
1个回答

3
有两种方法可以解决这个问题:
  • 三角法(使用余弦计算长度)
  • 线性代数法(最近点在直线上)

我这里只讲述三角法,因为另一种方法已经在 Stack Overflow 上有详细记录了,例如 获取到直线上最近的点

您已经指出由 Robot、Obstacle 和 dr 连成的三角形是一个直角三角形。这是解决缺失信息的较简单的情况之一(除了等边三角形),可以使用 SOH CAH TAO 中描述的三角法规则来解决问题。

在这种情况下,我们将使用 CAH(余弦比)来计算该三角形的邻边长度,因为我们可以从可用信息中获得斜边(Robot-Obstacle)和角度(theta)。一旦我们有了侧面的长度,我们就可以沿着路径行驶该距离以确定交点位置。

以下是如何在代码中实现此功能的想法(我选择不使用您编写的任何方法,而是利用 Unity 提供的许多方法):

Vector3 GetClosestPointToObstacleOnPathToTarget(Transform robot, Transform obstacle, Transform target)
{
    // Calculate vector from robot to target
    Vector3 toTarget = target.position - robot.position;

    // Calculate vector and distance from robot to obstacle (hypotenuse)
    Vector3 toObstacle = obstacle.position - robot.position;
    float robotObstacleDistance = toObstacle.magnitude;

    // Calculate theta (angle)
    float theta = Vector3.Angle(toTarget, toObstacle);

    // Using CAH rule (cosine, adjacent, hypotenuse) to find the (adjacent) side length
    float robotIntersectionDistance = Mathf.Cos(theta * Mathf.Deg2Rad) * robotObstacleDistance;

    // Travelling the calculated distance in the direction of the target
    Vector3 intersectionPoint = robot.position + toTarget.normalized * robotIntersectionDistance;

    return intersectionPoint;
}

希望这可以帮到你!如果有任何问题,请告诉我。

我尝试了你的代码。它给出了交点,但是当我从障碍物到这个点画一条线时,交点并没有形成90度角。看一下这张图片->> http://pictub.club/image/XtaOQ。你的代码返回了错误的交点。 - Ehsan Jeihani
为了增加更多细节,我应该说对象的位置是可互换的,它们可以在任何位置。 - Ehsan Jeihani
1
@EhsanJeihani 很有趣!你确定你正确地实现了它吗?手动计算,这是我得到的值:toTarget = (30, -0.308, -4.9)toTarget.normalized = (0.9868, -0.01013, -0.1612)robotObstacleDistance = 27.414theta = 45.337robotIntersectionDistance = 19.274,和 intersectionPoint = (21.32, -1.39, 30.69)。这给出了这组点(紫色是交点),看起来大致符合你的要求。 - Serlite
这很有趣。除了robotIntersectionDistance = -3.226和intersectionPoint = (-0.9, 0.2, 34.3)之外,所有值都相同。我仔细检查了一切。你的代码只是复制和粘贴。 - Ehsan Jeihani
1
@EhsanJeihani 哈哈!明白了- 当我写这个的时候,我忘了 Vector3.Angle() 返回角度,Mathf.Cos() 需要弧度。我相应地更新了我的答案。 - Serlite
是的,它有效。这正是我所需要的。谢谢。 - Ehsan Jeihani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接