在3D中绘制椭圆

时间:2012-08-29 10:45:30

标签: c# 3d path plot ellipse

前一段时间我在3D空间中绘制椭圆时遇到了问题。我似乎已经解决了这个问题,并按照我需要的方式(当时)旋转了东西。我的解决方案几乎完美无缺。它将椭圆旋转到正确的方向...但是,椭圆的起点和终点(在图中用青色和红色十字表示)总是不正确对齐。这里有一些图片来展示正在发生的事情,以及我需要发生的事情。

enter image description here

enter image description here

正如您所看到的,第一张图显示了仅在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);
}
毫无疑问,这是一个愚蠢的问题,我有一个额外的旋转,我错过了,或者我在旋转之前错过了对椭圆生成的调整,但我一直在为现在和现在是时候问一些可能更了解的人。

1 个答案:

答案 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);
}