如何找到线上最近的点?
How to find closest point on line?
我有一个点 (A) 和一个向量 (V)(假设它的长度是无限的),我想在直线上找到离我的原始点 (A) 最近的点 (B)。使用 Unity Vector2 或 Vector3 得到这个的最简单的表达式是什么?
无限长度:
如果你有无限长的线 start 和 direction,计算线方向的点积然后乘以方向并将起点添加到它。
public Vector2 FindNearestPointOnLine(Vector2 origin, Vector2 direction, Vector2 point)
{
direction.Normalize();
Vector2 lhs = point - origin;
float dotP = Vector2.Dot(lhs, direction);
return origin + direction * dotP;
}
有限长度:
如果你有有限长度的线从 start 到 end 位置,获取标题从起点到这。另外,使用 Mathf.Clamp
拍一下,以防断线。
public Vector2 FindNearestPointOnLine(Vector2 origin, Vector2 end, Vector2 point)
{
//Get heading
Vector2 heading = (end - origin);
float magnitudeMax = heading.magnitude;
heading.Normalize();
//Do projection from the point but clamp it
Vector2 lhs = point - origin;
float dotP = Vector2.Dot(lhs, heading);
dotP = Mathf.Clamp(dotP, 0f, magnitudeMax);
return origin + heading * dotP;
}
对于无限行:
Vector3 GetPoint(Vector3 p, Vector3 a, Vector3 b)
{
return a + Vector3.Project(p - a, b - a);
}
此方法适用于 Vector3
输入,如果参数为 Vector2
并自动转换为 Vector2
,则此方法也适用。如果需要,输出将隐式转换为 Vector2
。
// For finite lines:
Vector3 GetClosestPointOnFiniteLine(Vector3 point, Vector3 line_start, Vector3 line_end)
{
Vector3 line_direction = line_end - line_start;
float line_length = line_direction.magnitude;
line_direction.Normalize();
float project_length = Mathf.Clamp(Vector3.Dot(point - line_start, line_direction), 0f, line_length);
return line_start + line_direction * project_length;
}
// For infinite lines:
Vector3 GetClosestPointOnInfiniteLine(Vector3 point, Vector3 line_start, Vector3 line_end)
{
return line_start + Vector3.Project(point - line_start, line_end - line_start);
}
我有一个点 (A) 和一个向量 (V)(假设它的长度是无限的),我想在直线上找到离我的原始点 (A) 最近的点 (B)。使用 Unity Vector2 或 Vector3 得到这个的最简单的表达式是什么?
无限长度:
如果你有无限长的线 start 和 direction,计算线方向的点积然后乘以方向并将起点添加到它。
public Vector2 FindNearestPointOnLine(Vector2 origin, Vector2 direction, Vector2 point)
{
direction.Normalize();
Vector2 lhs = point - origin;
float dotP = Vector2.Dot(lhs, direction);
return origin + direction * dotP;
}
有限长度:
如果你有有限长度的线从 start 到 end 位置,获取标题从起点到这。另外,使用 Mathf.Clamp
拍一下,以防断线。
public Vector2 FindNearestPointOnLine(Vector2 origin, Vector2 end, Vector2 point)
{
//Get heading
Vector2 heading = (end - origin);
float magnitudeMax = heading.magnitude;
heading.Normalize();
//Do projection from the point but clamp it
Vector2 lhs = point - origin;
float dotP = Vector2.Dot(lhs, heading);
dotP = Mathf.Clamp(dotP, 0f, magnitudeMax);
return origin + heading * dotP;
}
对于无限行:
Vector3 GetPoint(Vector3 p, Vector3 a, Vector3 b)
{
return a + Vector3.Project(p - a, b - a);
}
此方法适用于 Vector3
输入,如果参数为 Vector2
并自动转换为 Vector2
,则此方法也适用。如果需要,输出将隐式转换为 Vector2
。
// For finite lines:
Vector3 GetClosestPointOnFiniteLine(Vector3 point, Vector3 line_start, Vector3 line_end)
{
Vector3 line_direction = line_end - line_start;
float line_length = line_direction.magnitude;
line_direction.Normalize();
float project_length = Mathf.Clamp(Vector3.Dot(point - line_start, line_direction), 0f, line_length);
return line_start + line_direction * project_length;
}
// For infinite lines:
Vector3 GetClosestPointOnInfiniteLine(Vector3 point, Vector3 line_start, Vector3 line_end)
{
return line_start + Vector3.Project(point - line_start, line_end - line_start);
}