Share via

how to translate matrix in .net.android?

mc 5,186 Reputation points
Mar 5, 2025, 7:06 AM

I want to use canvas in .net.android and want to draw cube on it.

I create custom view and rewrite ondraw

how to draw one cube using canvas?

if there is x,y,z and width height how to draw it?

.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,981 questions
0 comments No comments
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 80,606 Reputation points Microsoft External Staff
    Mar 6, 2025, 3:19 AM

    Hello,

    Firstly, if you want to draw cube in .NET for android, Use GLSurfaceView, it a better way to do it. I can be draw 2D or 3D cube and implement Dynamic Transformation simplely.

    However, if you want create custom view and rewrite ondraw.

    You can refer to the following code to draw the cube. I use Use 8 three-dimensional coordinate points to represent the vertices of the cube, each point contains x/y/z coordinates; Define 6 faces, each face consists of 4 vertex indices; Assign a different ARGB color value to each face.

    Normally, use Canvas to draw 2D cube, if want to draw 3D, we need to do following things: ‌Perspective projection formula‌: Calculate the scaling factor by _depth/(_depth - point‌:ml-citation{ref="5" data="citationList"}) to achieve a simple perspective effect. ‌Coordinate system conversion‌: Convert 3D coordinates to 2D screen coordinates, considering the center point of the View (centerX, century) as the projection reference .

    public class MyCanvasView : View
    {
         private readonly Paint _paint;
         private readonly float[][] _cubeVertices;
         private readonly int[][] _faces;
         private readonly int[] _faceColors;
         private readonly float _depth = 400f;
     
         public MyCanvasView(Context context) : base(context)
         {
             _paint = new Paint { AntiAlias = true };
             _paint.SetStyle(Paint.Style.Fill);
             // Define cube vertices (x, y, z)
             _cubeVertices = new float[][]
             {
                 new float[] { -100, -100, -100 }, // 0: Front top-left
                 new float[] {  100, -100, -100 }, // 1: Front top-right
                 new float[] {  100,  100, -100 }, // 2: Front bottom-right
                 new float[] { -100,  100, -100 }, // 3: Front bottom-left
                 new float[] { -100, -100,  100 }, // 4: Back top-left
                 new float[] {  100, -100,  100 }, // 5: Back top-right
                 new float[] {  100,  100,  100 }, // 6: Back bottom-right
                 new float[] { -100,  100,  100 }  // 7: Back bottom-left
             };
     
             // Define faces using 4 vertices each
             _faces = new int[][]
             {
                 new int[] { 0, 1, 2, 3 }, // Front
                 new int[] { 4, 5, 6, 7 }, // Back
                 new int[] { 0, 1, 5, 4 }, // Top
                 new int[] { 3, 2, 6, 7 }, // Bottom
                 new int[] { 0, 3, 7, 4 }, // Left
                 new int[] { 1, 2, 6, 5 }  // Right
             };
     
             // Assign unique colors to each face
             _faceColors = new int[]
             {
                 Color.Red, Color.Blue, Color.Green, Color.Yellow, Color.Cyan, Color.Magenta
             };
         }
     
         protected override void OnDraw(Canvas canvas)
         {
             base.OnDraw(canvas);
             canvas.DrawColor(Color.Black); // Background color
     
             int centerX = Width / 2;
             int centerY = Height / 2;
     
             // Project 3D points to 2D
             float[][] projected = new float[8][];
             for (int i = 0; i < 8; i++)
             {
                 projected[i] = ProjectPoint(_cubeVertices[i], centerX, centerY);
             }
     
             // Sort faces by depth for simple visibility handling
             List<Tuple<float, int>> faceDepths = new();
             for (int i = 0; i < _faces.Length; i++)
             {
                 float avgDepth = _faces[i].Select(idx => _cubeVertices[idx][2]).Average();
                 faceDepths.Add(new Tuple<float, int>(avgDepth, i));
             }
             faceDepths = faceDepths.OrderByDescending(f => f.Item1).ToList();
     
             // Draw faces back-to-front
             foreach (var (depth, faceIndex) in faceDepths)
             {
                 DrawFace(canvas, projected, _faces[faceIndex], _faceColors[faceIndex]);
             }
         }
     
         private void DrawFace(Canvas canvas, float[][] projected, int[] face, int color)
         {
             Android.Graphics.Path path = new Android.Graphics.Path();
             path.MoveTo(projected[face[0]][0], projected[face[0]][1]);
             for (int i = 1; i < face.Length; i++)
             {
                 path.LineTo(projected[face[i]][0], projected[face[i]][1]);
             }
             path.Close();
     
             _paint.Color = new Color(color);
             canvas.DrawPath(path, _paint);
         }
     
         private float[] ProjectPoint(float[] point, int centerX, int centerY)
         {
             float scale = _depth / (_depth - point[2]);
             float x = point[0] * scale + centerX;
             float y = point[1] * scale + centerY;
             return new float[] { x, y };
         }
    }
    

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.