有几种方法可以表达这个问题。
沿着 B 的上轴找到一个与 A 成直角的点。这将忽略 A 的任何旋转。
为此,将 A 的位置沿 B 向上投影。换句话说,找到 (A-B) 和 B 的点积,将其乘以 B 的上,然后将其与 B 相加。
Vector3 cPos = B.transform.position + Vector3.Dot(A.transform.position - B.transform.position, B.transform.up) * B.transform.up;
C.transform.position = cPos;
另一种方法是找到 B 向上和 A 向右的交点。根据 A 和 B 的旋转,这可能会产生非直角或根本没有点。
这有点复杂,the link in the comments 有很好的实现:
public static bool LineLineIntersection(out Vector3 intersection, Vector3 linePoint1, Vector3 lineVec1, Vector3 linePoint2, Vector3 lineVec2){
Vector3 lineVec3 = linePoint2 - linePoint1;
Vector3 crossVec1and2 = Vector3.Cross(lineVec1, lineVec2);
Vector3 crossVec3and2 = Vector3.Cross(lineVec3, lineVec2);
float planarFactor = Vector3.Dot(lineVec3, crossVec1and2);
//is coplanar, and not parrallel
if(Mathf.Abs(planarFactor) < 0.0001f && crossVec1and2.sqrMagnitude > 0.0001f)
{
float s = Vector3.Dot(crossVec3and2, crossVec1and2) / crossVec1and2.sqrMagnitude;
intersection = linePoint1 + (lineVec1 * s);
return true;
}
else
{
intersection = Vector3.zero;
return false;
}
}
然后找到你的位置:
Vector3 cPos;
bool doIntersect = LineLineIntersection(out cPos, A.transform.position, A.transform.right, B.transform.position, B.transform.up);
if (doIntersect) {
C.transform.position = cPos;
} else {
// do something reasonable, like using projection, or not changing the position
Vector3 cPos = B.transform.position + Vector3.Dot(A.transform.position - B.transform.position, B.transform.up) * B.transform.up;
C.transform.position = cPos;
}