You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何绘制含弧线及不规则路径的3D图形?

如何绘制带有弧线/不规则路径的3D图形?

我已掌握3D立方体的绘制与旋转方法,能绘制由直线构成的3D物体,但不知道如何绘制带有弧线的3D形状(类似3D弧的样式)。目前我的做法是将每个顶点从世界空间转换到2D屏幕空间,再用绘图基元连接顶点,但这种方法很难处理曲线。

以下是我绘制3D立方体的实现代码:

if (myCube == null)
{
    myCube = new XyCube(canvas.Width, canvas.Height, paint);
}

myCube.DrawCube(canvas);
public class XyCube
{
    public float width;
    public float height;
    public Color Color;
    public float center_x;
    public float center_y;
    public float center_z;
    public float size;

    public double speed;
    public double line_width = 0;

    Paint paint;

    public XyCube(float w, float h, Paint _paint)
    {
        width = w;
        height = h;
        center_x = width / 2;
        center_y = height / 2;
        center_z = 0;
        size = height / 2 / 2;
        speed = 30 / (float)180 * Math.PI;
        line_width = Math.Min(width, height) / 150;

        paint = _paint;

        vertices[0, 0] = center_x - size;
        vertices[0, 1] = center_y - size;
        vertices[0, 2] = center_z - size;
        vertices[1, 0] = center_x + size;
        vertices[1, 1] = center_y - size;
        vertices[1, 2] = center_z - size;
        vertices[2, 0] = center_x + size;
        vertices[2, 1] = center_y + size;
        vertices[2, 2] = center_z - size;
        vertices[3, 0] = center_x - size;
        vertices[3, 1] = center_y + size;
        vertices[3, 2] = center_z - size;
        vertices[3 + 1, 0] = center_x - size;
        vertices[3 + 1, 1] = center_y - size;
        vertices[3 + 1, 2] = center_z + size;
        vertices[5, 0] = center_x + size;
        vertices[5, 1] = center_y - size;
        vertices[5, 2] = center_z + size;
        vertices[6, 0] = center_x + size;
        vertices[6, 1] = center_y + size;
        vertices[6, 2] = center_z + size;
        vertices[7, 0] = center_x - size;
        vertices[7, 1] = center_y + size;
        vertices[7, 2] = center_z + size;
    }

    private int[,] edges = {
        { 0, 1 },{1,2},{2,3},{3,0},
        {3+1,5 },{5,6},{6,7},{7,3+1},
        {0,3+1 },{1,5},{2,6},{3,7}
    };

    private float[,] vertices = new float[8, 3];
    private float[,] vertices1 = new float[8, 3];

    private void DrawRect(Canvas canvas, float x1, float y1, float x2, float y2)
    {
        paint.SetStyle(Paint.Style.Fill);
        paint.Color = Color;
        canvas.DrawRect(x1, y1, x2, y2, paint);
    }

    public void DrawCube(Canvas canvas)
    {
        paint.SetStyle(Paint.Style.Stroke);
        paint.Color = Color;

        var ex = edges.GetLength(0);

        float _x = float.MaxValue;
        float _y = float.MaxValue;
        for (int i = 0; i < ex; i++)
        {
            var x1 = vertices[edges[i, 0], 0];
            var y1 = vertices[edges[i, 0], 1];
            if (x1 < _x)
            {
                _x = x1;
            }
            if (y1 < _y)
            {
                _y = y1;
            }
        }

        _x = center_x / 5 - _x;
        _y = center_y / 5 - _y;
        _x = 0;
        _y = 0;

        for (int i = 0; i < ex; i++)
        {
            //var x1 = vertices[edges[i, 0], 0];
            //var y1 = vertices[edges[i, 0], 1];
            //var x2 = vertices[edges[i, 1], 0];
            //var y2 = vertices[edges[i, 1], 1];
            var x1 = vertices1[edges[i, 0], 0];
            var y1 = vertices1[edges[i, 0], 1];
            var x2 = vertices1[edges[i, 1], 0];
            var y2 = vertices1[edges[i, 1], 1];

            canvas.DrawLine(x1 + _x, y1 + _y, x2 + _x, y2 + _y, paint);
        }
    }

    public float[,] MultiplyMatrices(float[,] m1, float[,] m2)
    {
        float[,] res = new float[m1.GetLength(0), m2.GetLength(1)];
        var row = m1.GetLength(0);
        var cols = m2.GetLength(1);
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                for (int x = 0; x < m2.GetLength(0); x++)
                {
                    res[i, j] += m1[i, x] * m2[x, j];
                }
            }
        }
        return res;
    }

    public float[,] RotateVertex(float x, float y, float angle_x, float angle_y, float angle_z)
    {
        float[,] rotate_x =
        {
            {1,0,0 },
            {0,(float)Math.Cos(angle_x), -(float)Math.Sin(angle_x)},
            {0,(float)Math.Sin(angle_x),(float)Math.Cos(angle_x) }
        };
        float[,] rotate_y =
        {
            {(float)Math.Cos(angle_y),0,(float)Math.Sin(angle_y) },
            {0,1,0 },
            {-(float)Math.Sin(angle_y),0,(float)Math.Cos(angle_y) }
        };
        float[,] rotate_z =
        {
            {(float)Math.Cos(angle_z),-(float)Math.Sin(angle_z),0 },
            {(float)Math.Sin(angle_z),(float)Math.Cos(angle_z),0 },
            {0,0,1 }
        };

        //x -= center_x;
        //y -= center_y;

        float[,] rotateCube = new float[8, 3];

        //float[]=MultiplyMatrices(rotate_x,)
        for (int i = 0; i < 8; i++)
        {
            float[,] p = new float[3, 1]
            {
                {vertices[i,0] },
                {vertices[i,1] },
                {vertices[i,2] }
            };

            float[,] rx = MultiplyMatrices(rotate_x, p);
            float[,] ry = MultiplyMatrices(rotate_y, rx);
            float[,] rz = MultiplyMatrices(rotate_z, ry);


            //rotateCube[i, 0] = rz[0, 0] + center_x;
            //rotateCube[i, 1] = rz[1, 0] + center_y;
            //rotateCube[i, 2] = rz[2, 0] + center_z;
            rotateCube[i, 0] = rz[0, 0];
            rotateCube[i, 1] = rz[1, 0];
            rotateCube[i, 2] = rz[2, 0];
        }

        //vertices = rotateCube;
        vertices1 = rotateCube;

        return rotateCube;
    }
}

内容的提问来源于stack exchange,提问作者liang.good

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 07:58:14