1

不久前,我在 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);
}

'毫无疑问,这是一个愚蠢的问题,我错过了额外的旋转,或者我在旋转之前错过了对椭圆生成的调整,但我已经绕圈子跑了一段时间了是时候问任何可能更了解的人了。

4

1 回答 1

0

Solution from OP.

The solution now seems obvious, simplify the orientation process. So I tweaked the coordinate generation to force the ellipse to be generated in the z/y plane, with the first point generated at 0,0,0 with this modification, the orientation becomes a simple LookRotation with a specified up vector, and then an offset to put it in the right place. (sometimes you just need a break from the code) This might only be one solution so if anyone has better ideas feel free to post them, but this works for me for now.

This is the new code that works as desired

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);
}
于 2019-01-13T16:15:09.870 回答