前一段时间我在3D空间中绘制椭圆时遇到了问题。我似乎已经解决了这个问题,并按照我需要的方式(当时)旋转了东西。我的解决方案几乎完美无缺。它将椭圆旋转到正确的方向...但是,椭圆的起点和终点(在图中用青色和红色十字表示)总是不正确对齐。这里有一些图片来展示正在发生的事情,以及我需要发生的事情。
正如您所看到的,第一张图显示了仅在y轴上发生旋转时的结果,青色十字架位于脚上,红色位于椭圆的另一端。然而,第二张图片的椭圆正确定向,但十字架似乎并未在正确的位置。 (它们应该在黑线连接椭圆的点上。
目前的代码就是这个。
public static void DrawEllipse(Vector3 p1, Vector3 p2, float height, Vector3 up)
{
Quaternion quat = Quaternion.identity;
int halfPoints = 25;
int totalPoints = halfPoints*2;
Vector3[] points1 = new Vector3[halfPoints];
Vector3[] points2 = new Vector3[halfPoints];
Vector3 midPoint = (p1 + ((p2 - p1)) * 0.5f);
Vector3 tmp = Vector3.zero;
quat *= Quaternion.LookRotation(Vector3.Cross(up,p2-p1));
for (int i = 0; i < totalPoints; i++)
{
// build the coordinates in arbitrary space.
tmp = Vector3.zero;
tmp.x = Mathf.Cos(((float)i / totalPoints) * (Mathf.PI * 2)) * (Vector3.Distance(p1, p2) * 0.5f);
tmp.y = Mathf.Sin(((float)i / totalPoints) * (Mathf.PI * 2)) * height;
// modify the point for correct orientation.
tmp = (quat * tmp);
// push to the arrays (split to show outward and return halves)
if (i < halfPoints)
points1[i] = tmp + midPoint;
else
points2[i - halfPoints] = tmp + midPoint;
}
DrawPath(points1, Color.cyan, false);
DrawPath(points2, Color.red, false);
Debug.DrawLine(p1, p2, Color.black);
DrawCross(points1[0], 0.2f, Color.cyan);
DrawCross(points2[0], 0.2f, Color.red);
}
毫无疑问,这是一个愚蠢的问题,我有一个额外的旋转,我错过了,或者我在旋转之前错过了对椭圆生成的调整,但我一直在为现在和现在是时候问一些可能更了解的人。
答案 0 :(得分:0)
OP解决方案。
解决方案现在似乎很明显,可以简化定向过程。因此,我调整了坐标生成以强制在z / y平面上生成椭圆,在此修改的情况下,第一个点生成为0,0,0,方向变为具有指定向上矢量的简单LookRotation,然后偏移以将其放置在正确的位置。 (有时您只需要中断代码即可)这可能只是一个解决方案,因此,如果有人有更好的主意可以随意发布,但这对我来说仍然有效。
这是可以正常运行的新代码
public static void DrawEllipse(Vector3 p1, Vector3 p2, float height, Vector3 up)
{
Quaternion quat = Quaternion.identity;
int halfPoints = 25;
int totalPoints = halfPoints*2;
Vector3[] points1 = new Vector3[halfPoints];
Vector3[] points2 = new Vector3[halfPoints];
Vector3 midPoint = (p1 + ((p2 - p1)) * 0.5f);
Vector3 tmp = Vector3.zero;
Vector3 firstPoint = Vector3.zero;
quat *= Quaternion.LookRotation(p2-p1, up);
for (int i = 0; i < totalPoints; i++)
{
tmp = Vector3.zero;
// build the coordinates in arbitrary space.
tmp.z = -Mathf.Cos(((float)i / totalPoints) * (Mathf.PI * 2)) * (Vector3.Distance(p1, p2) * 0.5f);
tmp.y = Mathf.Sin(((float)i / totalPoints) * (Mathf.PI * 2)) * height;
if (i == 0) firstPoint = tmp;
tmp -= firstPoint;
// modify the point for correct orientation.
tmp = (quat * tmp);
// push to the arrays (split to show outward and return halves)
if (i < halfPoints)
{
points1[i] = tmp + p1;
}
else
{
points2[i - halfPoints] = tmp + p1;
}
}
//draw the results.
DrawPath(points1, Color.cyan, false);
DrawPath(points2, Color.red, false);
Debug.DrawLine(p1, p2, Color.black);
DrawCross(points1[0], 0.2f, Color.cyan);
DrawCross(points2[0], 0.2f, Color.red);
}