C# C语言中三维线图的校正#

C# C语言中三维线图的校正#,c#,3d,drawing,line,C#,3d,Drawing,Line,我(在帮助下)创建了一个函数,可以在3D空间中绘制一行块。通常在64x64x64网格立方体中执行此操作 这是我的代码: internal static int DrawLine(Player theplayer, Byte drawBlock, int x0, int y0, int z0, int x1, int y1, int z1) { int blocks = 0; bool

我(在帮助下)创建了一个函数,可以在3D空间中绘制一行块。通常在64x64x64网格立方体中执行此操作

这是我的代码:

    internal static int DrawLine(Player theplayer, Byte drawBlock,
                                 int x0, int y0, int z0, int x1, int y1, int z1)
    {
        int blocks = 0;
        bool cannotUndo = false;
        bool detected = false;

        int dx = x1 - x0;
        int dy = y1 - y0;
        int dz = z1 - z0;

        DrawOneBlock(theplayer, drawBlock, x0, y0, z0, ref blocks, ref cannotUndo);
        if (Math.Abs(dx) > Math.Abs(dy) &&
            Math.Abs(dx) > Math.Abs(dz) && 
            detected == false)
        {
            detected = true;
            float my = (float)dy / (float)dx;
            float mz = (float)dz / (float)dx;
            float by = y0 - my * x0;
            float bz = z0 - mz * x0;
            dx = (dx < 0) ? -1 : 1;
            while (x0 != x1)
            {
                x0 += dx;
                DrawOneBlock(theplayer, drawBlock,
                    Convert.ToInt32(x0),
                    Convert.ToInt32(Math.Round(my * x0 + by)),
                    Convert.ToInt32(Math.Round(mz * x0 + bz)),
                    ref blocks, ref cannotUndo);
            }
        }
        if (Math.Abs(dy) > Math.Abs(dz) && 
            Math.Abs(dy) > Math.Abs(dx) &&
            detected == false)
        {
            detected = true;
            float mz = (float)dz / (float)dy;
            float mx = (float)dx / (float)dy;
            float bz = z0 - mz * y0;
            float bx = x0 - mx * y0;
            dy = (dy < 0) ? -1 : 1;
            while (y0 != y1)
            {
                y0 += dy;
                DrawOneBlock(theplayer, drawBlock,
                             Convert.ToInt32(Math.Round(mx * y0 + bx)),
                             Convert.ToInt32(y0),
                             Convert.ToInt32(Math.Round(mz * y0 + bz)),
                             ref blocks, ref cannotUndo);
            }
        }
        if (detected == false)
        {
            detected = true;
            float mx = (float)dx / (float)dz;
            float my = (float)dy / (float)dz;
            float bx = x0 - mx * z0;
            float by = y0 - my * z0;
            dz = (dz < 0) ? -1 : 1;
            while (z0 != z1)
            {
                z0 += dz;
                DrawOneBlock(theplayer, drawBlock,
                             Convert.ToInt32(Math.Round(mx * z0 + bx)),
                             Convert.ToInt32(Math.Round(my * z0 + by)),
                             Convert.ToInt32(z0),
                             ref blocks, ref cannotUndo);
            }
        }
        return blocks;
    }
内部静态int绘图线(播放器、播放器、字节绘图块、,
内部x0、内部y0、内部z0、内部x1、内部y1、内部z1)
{
整数块=0;
bool cannotUndo=false;
检测到布尔=假;
int dx=x1-x0;
int-dy=y1-y0;
int dz=z1-z0;
DrawOneBlock(图层、绘图块、x0、y0、z0、参考块、参考不能撤消);
if(Math.Abs(dx)>Math.Abs(dy)&&
数学Abs(dx)>数学Abs(dz)&
检测到==错误)
{
检测到=真;
float my=(float)dy/(float)dx;
浮点数mz=(浮点数)dz/(浮点数)dx;
浮点数=y0-my*x0;
浮子bz=z0-mz*x0;
dx=(dx<0)?-1:1;
而(x0!=x1)
{
x0+=dx;
DrawOneBlock(打印机、drawBlock、,
转换为32(x0),
转换为32(数学圆整(my*x0+by)),
转换为32(数学圆(mz*x0+bz)),
ref块,ref不能撤消);
}
}
如果(数学Abs(dy)>数学Abs(dz)&
Math.Abs(dy)>Math.Abs(dx)&&
检测到==错误)
{
检测到=真;
浮动mz=(浮动)dz/(浮动)dy;
浮点mx=(浮点)dx/(浮点)dy;
浮子bz=z0-mz*y0;
浮点数bx=x0-mx*y0;
dy=(dy<0)?-1:1;
而(y0!=y1)
{
y0+=dy;
DrawOneBlock(打印机、drawBlock、,
转换为32(数学圆(mx*y0+bx)),
转换为32(y0),
转换为32(数学圆(mz*y0+bz)),
ref块,ref不能撤消);
}
}
如果(检测到==错误)
{
检测到=真;
浮点数mx=(浮点数)dx/(浮点数)dz;
float my=(float)dy/(float)dz;
浮点数bx=x0-mx*z0;
浮点数=y0-my*z0;
dz=(dz<0)?-1:1;
而(z0!=z1)
{
z0+=dz;
DrawOneBlock(打印机、drawBlock、,
转换为32(数学四舍五入(mx*z0+bx)),
转换为32(数学四舍五入(my*z0+by)),
转换为32(z0),
ref块,ref不能撤消);
}
}
返回块;
}
它应将块图形排队,并返回已绘制的块数。问题是它没有画出一条不折线。在某些情况下,当至少所有块都应通过其顶点连接时,它会在块之间留下间隙

代码中唯一让我费劲的部分是,我在计算轴的最大差值,并创建一个斜率常数。我在尝试画一条完美的对角线时遇到了一个问题。所有的值都是相等的,所以我只是默认为z轴-这就是我认为存在问题的地方。

也许修改为(希望)在3D中工作对您来说是一个替代方案

public static void Swap<T>(ref T x, ref T y)
{
    T tmp = y;
    y = x;
    x = tmp;
}

private void Draw3DLine(int x0, int y0, int z0, int x1, int y1, int z1)
{
    bool steepXY = Math.Abs(y1 - y0) > Math.Abs(x1 - x0);
    if (steepXY) { Swap(ref x0, ref y0); Swap(ref x1, ref y1); }

    bool steepXZ = Math.Abs(z1 - z0) > Math.Abs(x1 - x0);
    if (steepXZ) { Swap(ref x0, ref z0); Swap(ref x1, ref z1); }

    int deltaX = Math.Abs(x1 - x0);
    int deltaY = Math.Abs(y1 - y0);
    int deltaZ = Math.Abs(z1 - z0);

    int errorXY = deltaX / 2, errorXZ = deltaX / 2;

    int stepX = (x0 > x1) ? -1 : 1;  
    int stepY = (y0 > y1) ? -1 : 1;
    int stepZ = (z0 > z1) ? -1 : 1;

    int y=y0, z=z0;

    // Check if the end of the line hasn't been reached.
    for(int x = x0; x!=x1; x+=stepX) 
    {
        int xCopy=x, yCopy=y, zCopy=z;

        if (steepXZ) Swap(ref xCopy, ref zCopy);
        if (steepXY) Swap(ref xCopy, ref yCopy);

        // Replace the WriteLine with your call to DrawOneBlock
        Console.WriteLine("[" + xCopy + ", " + yCopy + ", " + zCopy + "], ");

        errorXY -= deltaY;
        errorXZ -= deltaZ;

        if (errorXY < 0) 
        {
            y += stepY;
            errorXY += deltaX;
        }

        if (errorXZ < 0) 
        {
            z += stepZ;
            errorXZ += deltaX;
        }
    }
}
公共静态无效交换(参考T x,参考T y)
{
T tmp=y;
y=x;
x=tmp;
}
专用空心绘制线(内部x0、内部y0、内部z0、内部x1、内部y1、内部z1)
{
bool-stypxy=Math.Abs(y1-y0)>Math.Abs(x1-x0);
如果(陡度xy){Swap(ref x0,ref y0);Swap(ref x1,ref y1);}
bool-xz=Math.Abs(z1-z0)>Math.Abs(x1-x0);
if(xz){Swap(ref x0,ref z0);Swap(ref x1,ref z1);}
int deltaX=Math.Abs(x1-x0);
int deltaY=Math.Abs(y1-y0);
int deltaZ=数学绝对值(z1-z0);
int errorXY=deltaX/2,errorXZ=deltaX/2;
int-stepX=(x0>x1)?-1:1;
int-stepY=(y0>y1)?-1:1;
int stepZ=(z0>z1)?-1:1;
int y=y0,z=z0;
//检查是否尚未到达线路的末端。
对于(int x=x0;x!=x1;x+=stepX)
{
int xCopy=x,yCopy=y,zCopy=z;
if(xz)交换(ref xCopy,ref zCopy);
if(陡度XY)交换(参考xCopy,参考yCopy);
//用对DrawOneBlock的调用替换WriteLine
Console.WriteLine(“[”+xCopy+“,“+yCopy+”,“+zCopy+”],”);
errorXY-=三角洲;
errorXZ-=deltaZ;
if(errorXY<0)
{
y+=stepY;
errorXY+=deltaX;
}
如果(错误xz<0)
{
z+=stepZ;
errorXZ+=deltaX;
}
}
}
内部静态无效行回调(玩家、位置[]标记、对象标记)//已修改//
{
字节drawBlock=(字节)标记;
if(drawBlock==(字节)Block.Undefined)
{
drawBlock=(字节)player.lastUsedBlockType;
}
player.undoBuffer.Clear();
整数块=0;
bool cannotUndo=false;
//行号
int x1=标记[0]。x,y1=标记[0]。y,z1=标记[0]。h,x2=标记[1]。x,y2=标记[1]。y,z2=标记[1]。h;
int i,dx,dy,dz,l,m,n,x_inc,y_inc,z_inc,err_1,err_2,dx2,dy2,dx2;
int[]像素=新的int[3];
像素[0]=x1;
像素[1]=y1;
像素[2]=z1;
dx=x2-x1;
dy=y2-y1;
dz=z2-z1;
x_inc=(dx<0)?-1:1;
l=数学绝对值(dx);
y_inc=(dy<0)?-1:1;
m=数学绝对值(dy);
z_inc=(dz<0)?-1:1;
n=数学绝对值(dz);
dx2=l0){
像素[1]+=y_公司;
err_1-=dx2;
}
如果(错误2>0){
像素[2]+=z_公司;
err_2-=dx2;
}
internal static void LineCallback(Player player, Position[] marks, object tag) //MODIFIED//
    {
        byte drawBlock = (byte)tag;
        if (drawBlock == (byte)Block.Undefined)
        {
            drawBlock = (byte)player.lastUsedBlockType;
        }

        player.undoBuffer.Clear();

        int blocks = 0;
        bool cannotUndo = false;

        // LINE CODE

        int x1 = marks[0].x, y1 = marks[0].y, z1 = marks[0].h, x2 = marks[1].x, y2 = marks[1].y, z2 = marks[1].h;
        int i, dx, dy, dz, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2;
        int[] pixel = new int[3];
        pixel[0] = x1;
        pixel[1] = y1;
        pixel[2] = z1;
        dx = x2 - x1;
        dy = y2 - y1;
        dz = z2 - z1;
        x_inc = (dx < 0) ? -1 : 1;
        l = Math.Abs(dx);
        y_inc = (dy < 0) ? -1 : 1;
        m = Math.Abs(dy);
        z_inc = (dz < 0) ? -1 : 1;
        n = Math.Abs(dz);
        dx2 = l << 1;
        dy2 = m << 1;
        dz2 = n << 1;

        DrawOneBlock(player, drawBlock, x2, y2, z2, ref blocks, ref cannotUndo);
        DrawOneBlock(player, drawBlock, x2, y2, z2, ref blocks, ref cannotUndo);

        if ((l >= m) && (l >= n)) {

            err_1 = dy2 - l;
            err_2 = dz2 - l;
            for (i = 0; i < l; i++) {
                DrawOneBlock(player, drawBlock, pixel[0], pixel[1], pixel[2], ref blocks, ref cannotUndo);
                if (err_1 > 0) {
                    pixel[1] += y_inc;
                    err_1 -= dx2;
                }
                if (err_2 > 0) {
                    pixel[2] += z_inc;
                    err_2 -= dx2;
                }
                err_1 += dy2;
                err_2 += dz2;
                pixel[0] += x_inc;
            }
        } else if ((m >= l) && (m >= n)) {
            err_1 = dx2 - m;
            err_2 = dz2 - m;
            for (i = 0; i < m; i++) {
                DrawOneBlock(player, drawBlock, pixel[0], pixel[1], pixel[2], ref blocks, ref cannotUndo);
                if (err_1 > 0) {
                    pixel[0] += x_inc;
                    err_1 -= dy2;
                }
                if (err_2 > 0) {
                    pixel[2] += z_inc;
                    err_2 -= dy2;
                }
                err_1 += dx2;
                err_2 += dz2;
                pixel[1] += y_inc;
            }
        } else {
            err_1 = dy2 - n;
            err_2 = dx2 - n;
            for (i = 0; i < n; i++) {
                DrawOneBlock(player, drawBlock, pixel[0], pixel[1], pixel[2], ref blocks, ref cannotUndo);
                if (err_1 > 0) {
                    pixel[1] += y_inc;
                    err_1 -= dz2;
                }
                if (err_2 > 0) {
                    pixel[0] += x_inc;
                    err_2 -= dz2;
                }
                err_1 += dy2;
                err_2 += dx2;
                pixel[2] += z_inc;
            }
        }

        // END LINE CODE
    }