मुझे लिखने योग्य बिटमैप के साथ एक समस्या का सामना करना पड़ा है। मैं एक 3 डी क्यूब रेंडर करने की कोशिश कर रहा हूं। लेकिन जब पिक्सल को लिखने योग्य बिटमैप पर लिखा जा रहा है, तो उनमें से एक हिस्सा बस शिफ्ट हो जाता है।

आरंभिक घन:

Initialized cube

और वह क्या हो रहा है, जब मैं इसे x के साथ 45 डिग्री घुमाने की कोशिश कर रहा हूं। cube, x के साथ 45 डिग्री घुमाया गया

Y को छोड़कर सभी प्रकार के घूर्णन के लिए समस्या प्रकट होती है (z के साथ 10 डिग्री घूर्णन) cube, z के साथ 10 डिग्री घुमाया गया

मैंने सामान्य बिटमैप और सेटपिक्सेल() विधि के साथ समान बिंदुओं का परीक्षण किया है। क्यूब को 45 डिग्री के साथ तीन अक्ष पर घुमाने के बाद मुझे यही मिलता है। मुझे यहां कोई समस्या नहीं दिख रही है

enter image description here

मुझे लगता है कि समस्या मेरे लिखने योग्य बिटमैप पिक्सेल सेटिंग एल्गोरिदम के साथ हो सकती है (शायद पिक्सेल ऑफ़सेट के साथ समस्या?)

ग्रे बैकग्राउंड वाली दूसरी इमेज:

Second image with grey background

मैं x के साथ 45 डिग्री घुमाए गए घन से क्या उम्मीद कर रहा हूं। लाल रेखा - किनारा। पाठ - पहलू मैं क्या उम्मीद कर रहा हूं


लिखने योग्य बिटमैप ड्राइंग एल्गोरिदम:

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;
    }
0
Dmitry 24 नवम्बर 2018, 17:13

1 उत्तर

सबसे बढ़िया उत्तर

मैं ऊंचाई के 2d सरणी को एक हाइपोमेट्रिक चित्र में बदलने के लिए लिखने योग्य बिटमैप का उपयोग करता हूं। रंग ऊंचाई का प्रतिनिधित्व करता है। मैं एक 2d सरणी के साथ काम करने की सलाह देता हूं जो आपके दृश्य का प्रतिनिधित्व करता है और बस उसी के माध्यम से पुनरावृति करता है। bgra32 के लिए प्रति पिक्सेल 4 बाइट्स हैं।

                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;
1
Andy 24 नवम्बर 2018, 18:46