C# 像素在WriteableBitmap中移动

C# 像素在WriteableBitmap中移动,c#,wpf,graphics,3d,writeablebitmap,C#,Wpf,Graphics,3d,Writeablebitmap,我在WriteableBitmap方面遇到了一个问题。我正在尝试渲染三维立方体。但是,当像素被写入WriteableBitmap时,其中的一部分只是移动 已初始化多维数据集: 当我试着把它沿着x旋转45度时,会发生这样的事情。 所有类型的旋转都会出现问题,y除外(沿z旋转10度) 我用常用的位图和SetPixel()方法测试了相同的点。这就是我将立方体沿三轴旋转45度后得到的结果。我看这里没有任何问题 我认为这个问题可能与我的writeableBitmap像素设置算法有关(可能是像素偏移

我在WriteableBitmap方面遇到了一个问题。我正在尝试渲染三维立方体。但是,当像素被写入WriteableBitmap时,其中的一部分只是移动

已初始化多维数据集:

当我试着把它沿着x旋转45度时,会发生这样的事情。

所有类型的旋转都会出现问题,y除外(沿z旋转10度)

我用常用的位图和SetPixel()方法测试了相同的点。这就是我将立方体沿三轴旋转45度后得到的结果。我看这里没有任何问题

我认为这个问题可能与我的writeableBitmap像素设置算法有关(可能是像素偏移的问题?)

灰色背景的第二幅图像:

我所期望的是立方体沿x轴旋转45度。红线-边缘。文本方面


WriteableBitmap绘制算法:
public WriteableBitmap DrawSceneByPoints(整数宽度、整数高度、列表点)
{
WriteableBitmap wBitmap=新的WriteableBitmap(宽度、高度,96,96,PixelFormats.Bgra32,null);
Int32Rect rect=新的Int32Rect(0,0,宽度,高度);
var stride=(rect.Width*wBitmap.Format.BitsPerPixel+7)/8;
字节[]像素=新字节[rect.Height*stride];
//对于用户:将0,0点从左上角移动到左下角
对于(int i=0;i
常用位图绘制算法:
公共位图DrawSceneByPointsBitmap(整数宽度、整数高度、列表点)
{
位图位图=新位图(宽度、高度);
//对于用户:将0,0点从左上角移动到左下角
对于(int i=0;i
场景渲染方法:
public WriteableBitmap Render()
{
新建ShapeEditor()。转换形状(形状,当前相机);
列出所有点=GetAllPoints();
返回新的Painter().DrawSceneByPoints(this.Width,this.Height,allPoints);
}
行光栅化器:
class-BresenhamLine:i擦除器
{
公共列表GetLine(MPoint点1、MPoint点2)
{
返回Bresenham3D((int)point1.X,(int)point1.Y,(int)point1.Z,(int)point2.X,(int)point2.Y,(int)point2.Z);
}
私人列表Bresenham3D(int x1、int y1、int z1、int x2、int y2、int z2)
{
var points=新列表();
浮点数x0=x1,y0=y1,z0=z1;
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;
}
err_1+=dy2;
err_2+=dz2;
点[0]+=x_公司;
}
}
如果((m>=l)和&(m>=n))为else
{
err_1=dx2-m;
err_2=dz2-m;
对于(i=0;i0)
{
点[0]+=x_公司;
err_1-=dy2;
}
如果(错误2>0)
{
点[2]+=z_公司;
err_2-=dy2;
}
err_1+=dx2;
err_2+=dz2;
点[1]+=y_公司;
}
}
其他的
{
err_1=dy2-n;
err_2=dx2-n;
对于(i=0;i0)
{
点[1]+=y_公司;
err_1-=dz2;
}
如果(错误2>0)
{
点[0]+=x_公司;
err_2-=dz2;
}
err_1+=dy2;
err_2+=dx2;
点[2]+=z_公司;
}
}
返回点;
}
私人无效掉期(参考TL、参考TR)
{
温度T=l;
l=r;
r=温度;
}
}
多边形光栅化器:
公共列表栅格化多边形(MFacet三角形)
{
var points=新列表();
Vector2 vertex0=新矢量2(三角形.顶点[0].X,三角形.顶点[0].Y),
vertex1=新矢量2(三角形.顶点[1].X,三角形.顶点[1].Y),
vertex2=新矢量2(三角形。顶点[2]。X,三角形。顶点[2]。Y);
if(vertex0.Y==vertex1.Y&&vertex0.Y==vertex2.Y)返回新的BresenhamLine().GetLine(triangle.Vertices[0],triangle.Vertices[2]);
//对顶点、顶点0和顶点进行排序
public WriteableBitmap DrawSceneByPoints(int width, int height, List<MPoint> points)
    {
        WriteableBitmap wBitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgra32, null);

        Int32Rect rect = new Int32Rect(0, 0, width, height);

        var stride = (rect.Width * wBitmap.Format.BitsPerPixel + 7) / 8;

        byte[] pixels = new byte[rect.Height * stride];

        // For user: Moves 0,0 point from top-left to bottom-left
        for (int i = 0; i < points.Count; ++i)
            points[i].Y = height - points[i].Y;

        int alpha = 255;
        int red = 0;
        int green = 0;
        int blue = 0;

        for (int i = 0; i < points.Count; ++i)
        {               
            int pixelOffset = (int)(points[i].X + points[i].Y * wBitmap.PixelWidth) * wBitmap.Format.BitsPerPixel / 8;

            pixels[pixelOffset] = (byte)blue;
            pixels[pixelOffset + 1] = (byte)green;
            pixels[pixelOffset + 2] = (byte)red;
            pixels[pixelOffset + 3] = (byte)alpha;
        }

        wBitmap.WritePixels(rect, pixels, stride, 0);

        return wBitmap;
    }
public Bitmap DrawSceneByPointsBitmap(int width, int height, List<MPoint> points)
    {
        Bitmap bitmap = new Bitmap(width, height);

        // For user: Moves 0,0 point from top-left to bottom-left
        for (int i = 0; i < points.Count; ++i)
            points[i].Y = height - points[i].Y;

        for (int i = 0; i < points.Count; ++i)
            bitmap.SetPixel((int)points[i].X, (int)points[i].Y, System.Drawing.Color.White);

        return bitmap;
    }
public WriteableBitmap Render()
    {
        new ShapeEditor().TransformShapes(Shapes, CurrentCamera);

        List<MPoint> allPoints = GetAllPoints();

        return new Painter().DrawSceneByPoints(this.Width, this.Height, allPoints);
    }
class BresenhamLine : ILineRasterizer
{
    public List<MPoint> GetLine(MPoint point1, MPoint point2)
    {
        return Bresenham3D((int)point1.X, (int)point1.Y, (int)point1.Z, (int)point2.X, (int)point2.Y, (int)point2.Z);
    }

    private List<MPoint> Bresenham3D(int x1, int y1, int z1, int x2, int y2, int z2)
    {
        var points = new List<MPoint>();

        float x0 = x1, y0 = y1, z0 = z1;
        int i, dx, dy, dz, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2;
        int[] point = new int[3];

        point[0] = x1;
        point[1] = y1;
        point[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;

        if ((l >= m) && (l >= n))
        {
            err_1 = dy2 - l;
            err_2 = dz2 - l;
            for (i = 0; i < l; i++)
            {
                points.Add(new MPoint(point[0], point[1], point[2]));

                if (err_1 > 0)
                {
                    point[1] += y_inc;
                    err_1 -= dx2;
                }
                if (err_2 > 0)
                {
                    point[2] += z_inc;
                    err_2 -= dx2;
                }
                err_1 += dy2;
                err_2 += dz2;
                point[0] += x_inc;
            }
        }
        else if ((m >= l) && (m >= n))
        {
            err_1 = dx2 - m;
            err_2 = dz2 - m;
            for (i = 0; i < m; i++)
            {
                points.Add(new MPoint(point[0], point[1], point[2]));

                if (err_1 > 0)
                {
                    point[0] += x_inc;
                    err_1 -= dy2;
                }
                if (err_2 > 0)
                {
                    point[2] += z_inc;
                    err_2 -= dy2;
                }
                err_1 += dx2;
                err_2 += dz2;
                point[1] += y_inc;
            }
        }
        else
        {
            err_1 = dy2 - n;
            err_2 = dx2 - n;
            for (i = 0; i < n; i++)
            {
                points.Add(new MPoint(point[0], point[1], point[2]));

                if (err_1 > 0)
                {
                    point[1] += y_inc;
                    err_1 -= dz2;
                }
                if (err_2 > 0)
                {
                    point[0] += x_inc;
                    err_2 -= dz2;
                }
                err_1 += dy2;
                err_2 += dx2;
                point[2] += z_inc;
            }
        }

        return points;
    }

    private void Swap<T>(ref T l, ref T r)
    {
        T temp = l;

        l = r;

        r = temp;
    }
}
public List<MPoint> RasterizePolygon(MFacet triangle)
    {
        var points = new List<MPoint>();

        Vector2 vertex0 = new Vector2(triangle.Vertices[0].X, triangle.Vertices[0].Y),
            vertex1 = new Vector2(triangle.Vertices[1].X, triangle.Vertices[1].Y),
            vertex2 = new Vector2(triangle.Vertices[2].X, triangle.Vertices[2].Y);        

        if (vertex0.Y == vertex1.Y && vertex0.Y == vertex2.Y) return new BresenhamLine().GetLine(triangle.Vertices[0], triangle.Vertices[2]);
                                                  // sort the vertices, vertex0, vertex1, vertex2 lower-to-upper
        if (vertex0.Y > vertex1.Y) Swap(ref vertex0, ref vertex1);
        if (vertex0.Y > vertex2.Y) Swap(ref vertex0, ref vertex2);
        if (vertex1.Y > vertex2.Y) Swap(ref vertex1, ref vertex2);

        int total_height = (int)(vertex2.Y - vertex0.Y);

        for (int i = 0; i < total_height; i++)
        {
            bool second_half = i > vertex1.Y - vertex0.Y || vertex1.Y == vertex0.Y;

            int segment_height = second_half ? (int)(vertex2.Y - vertex1.Y) : (int)(vertex1.Y - vertex0.Y);

            float alpha = (float)i / total_height;
            float beta = (float)(i - (second_half ? vertex1.Y - vertex0.Y : 0)) / segment_height; // be careful: with above conditions no division by zero here

            Vector2 A = vertex0 + (vertex2 - vertex0) * alpha;
            Vector2 B = second_half ? vertex1 + (vertex2 - vertex1) * beta : vertex0 + (vertex1 - vertex0) * beta;

            if (A.X > B.X) Swap(ref A, ref B);

            for (int j = (int)A.X; j <= B.X; j++)
            {
                points.Add(new MPoint(j, vertex0.Y + i, 1));

                if (j > B.X || (A.X < vertex0.X && A.X < vertex1.X && A.X < vertex2.X))
                    Swap(ref vertex0, ref vertex0);
            }
        }

        return points;
    }
                WriteableBitmap WBM = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgra32, null);

                byte[] pixels = new byte[width * height * 4];
                double perColour = (double)(max - min) / 254d;
                Color[] ca = Application.Current.Resources["HypsoColours"] as Color[];

                int ix = 0;
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        int elv = elevations[x, y];
                        int eff = elv - min;
                        int ptr = 0;
                        if (eff> 0)
                        {
                            ptr = (int)((elv - min) / perColour);
                        }
                        Color colour = ca[ptr];
                        pixels[ix] = colour.B;
                        ix++;
                        pixels[ix] = colour.G;
                        ix++;
                        pixels[ix] = colour.R;
                        ix++;
                        pixels[ix] = 255;
                        ix++;
                    }
                }
                WBM.WritePixels(new Int32Rect(0, 0, width, height), pixels, width * 4, 0);
                WBM.Freeze();
                return WBM;