[英]Calculate 3D rotation of a plane given 3 points and their relative position
我正在尝试在 Unity 中旋转 3D 中的平面,给出三点。 这些点并不总是相同的,但它们始终位于此图像中的红点上
我知道这些点的绝对位置,以及它们相对于平面的 position。 例如,我可能知道点 (-5, 5) 位于 (10, -4, 13) 上。
我知道当三个点在一条线上时(例如(-5, 5)、(0, 5)和(5, 5)),不可能计算完整的旋转,所以我已经抛出异常案子。 但是,当三个点不在一条线上时,应该可以计算完整的旋转。
到目前为止,我已经使用下面的代码进行旋转,但这错过了围绕 y 轴的旋转(示例使用点 (-5, 5)、(5, 5) 和 (-5, -5)。
Vector3 p1 = Point1.transform.position;// point 1 absolute position
Vector3 p1Relative = new Vector3(-5, 0, 5);
Vector3 p2 = Point2.transform.position;// point 2 absolute position
Vector3 p2Relative = new Vector3(5, 0, 5);
Vector3 p3 = Point3.transform.position;// point 3 absolute position
Vector3 p3Relative = new Vector3(-5, 0, -5);
Gizmos.DrawSphere(p1, .1f);
Gizmos.DrawSphere(p2, .1f);
Gizmos.DrawSphere(p3, .1f);
Vector3 normal = Vector3.Cross(p2 - p1, p3- p1);
rotator.transform.up = normal;
我将如何扩展或更改此代码以包含围绕 Y 轴的旋转? 先感谢您。
听起来你实际上有给定的分数
所以你可能会得到两个方向,并简单地假设给定的 3 点实际上是他们声称的
var ul = UpperLeft.transform.position;
var ur = UpperRight.transform.position;
var ll = LowerLeft.transform.position;
// actually ignored since setting right and up is already enough
// need it though to calculate the up vector and the final position
var forward = ul - ll;
var right = ur - ul;
var up = Vector3.Cross(forward, right);
rotator.transform.up = up;
rotator.transform.right = right;
// and finally if needed place the center
rotator.transform.position = ul + right * 0.5f - forward * 0.5f;
一旦你确定了向前和向上的方向, Quaternion.LookRotation
让这变得简单:
struct VirtualPoint
{
Vector3 absolutePos;
Vector3 relativePos;
}
// Uses list of points, but works for 3
void GetMinMaxPoints(List<VirtualPoint> points, out VirtualPoint xMinP,
out VirtualPoint xMaxP, out VirtualPoint yMinP,
out VirtualPoint yMaxP)
{
Debug.Assert(points.Count >= 1);
xMinP = xMaxP = yMinP = yMaxP = points[0];
float xMin, xMax, yMin, yMax;
xMin = xMax = points[0].relativePos.x;
yMin = yMax = points[0].relativePos.y;
foreach (Virtual point: points)
{
Vector3 pos = point.relativePos;
if (pos.x < xMin)
{
xMin = pos.x;
xMinP = point;
}
else if (pos.x > xMax)
{
xMax = pos.x;
xMaxP = point
}
if (pos.y < yMin)
{
yMin = pos.y;
yMinP = point;
}
else if (pos.y > yMax)
{
yMax = pos.y;
yMaxP = point;
}
}
}
Quaternion GetPlaneRotation(List<VirtualPoint> points)
{
Debug.Assert(points.Count >= 3);
GetMinMaxPoints( out VirtualPoint xMinP, out VirtualPoint xMaxP,
out VirtualPoint yMinP, out VirtualPoint yMaxP);
if (xMinP.absolutePos == xMaxP.absolutePos
|| yMinP.absolutePos == xMinP.absolutePos)
{
throw new System.Exception("points don't define plane");
}
Vector3 forwardDir = yMaxP.absolutePos - yMinP.absolutePos;
Vector3 rightdir = xMaxP.absolutePos - xMaxP.absolutePos;
Vector3 upDir = Vector3.Cross(forwardDir, rightDir);
return Quaternion.LookRotation(forwardDir, upDir);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.