我有一个点(A)和一个向量(V)(假设它是无限长),并且我想找到直线上与原始点(A)最接近的点(B)。使用Unity Vector2或Vector3的最简单的表达式是什么?
答案 0 :(得分:4)
无限长:
如果您的线具有无限长且具有 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;
}
答案 1 :(得分:1)
// 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);
}
答案 2 :(得分:0)
我假设您不知道两个点的位置,因为找到两个已知点之间距离的解决方案是简单的减法。如果您要动态查找距离,建议您使用A
。
将这样的脚本添加到您认为raycasting
的游戏对象中可能适用于您:
pointA
确保要寻找的点上面有对撞机;然后可以将射线投射的距离设置为using UnityEngine;
public class Raycasting : MonoBehaviour
{
[SerializeField]
private LayerMask pointMask; //Set this to the same tag as any GameObject you consider a "point"
private Vector2 pointA, distance;
private void Update()
{
CheckForPoint();
Debug.Log(distance);
}
private void CheckForPoint()
{
pointA = transform.position; //The GameObject's current position in the world
RaycastHit2D pointB = Physics2D.Raycast(pointA, Vector2.right * Mathf.Sign(transform.localScale.x), Mathf.Infinity, pointMask);
//Draws a visible ray in the game view (must have gizmos enabled)
Debug.DrawRay(pointA, Vector2.right * Mathf.Sign(transform.localScale.x), Color.green);
if (pointB)
{
distance = (Vector2)pointB.transform.position - pointA;
}
}
}
(或您想要的任何其他长度),并且Mathf.Infinity
将是射线与之碰撞的第一个对象。
您可以阅读有关pointB
API here的更多信息,尽管相同的方法也适用于3D。