A simple program to draw a solid in C # ~ Part 2 ~

5 minute read

Simple program for drawing solids in C #
The program I posted in the previous article was wrong, so I fixed it.

I think you can easily do it by using a library, but after all this is all your own work!

Class to draw a solid

G3D.cs


using System;
using System.Drawing;
using System.Windows.Forms;

namespace _3D
{
    class G3D
    {
        private Bitmap canvas;
        private Graphics g;
        private PictureBox pictureBox;
        private double x_adj, y_adj;
        private double x_theta = 0, y_theta = 0, z_theta = 0;

        public G3D(PictureBox p)
        {
            pictureBox = p;
            canvas = new Bitmap(p.Width, p.Height);
            g = Graphics.FromImage(canvas);
            x_adj = p.Width / 2;
            y_adj = p.Height / 2;
        }

        public void cuboid(double x1, double y1, double z1, double x2, double y2, double z2, double x_rot_theta, double y_rot_theta, double z_rot_theta)
        {
            double x_rot = x_theta;
            double y_rot = y_theta;
            double z_rot = z_theta;

            Point[] p = { point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta,x1, y1, z1),
                 point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x2, y1, z1),
                 point_culc(x_rot, y_rot, z_rot,  x_rot_theta,y_rot_theta,z_rot_theta,x2, y2, z1),
                 point_culc(x_rot, y_rot, z_rot,  x_rot_theta,y_rot_theta,z_rot_theta,x1, y2, z1) };

            g.DrawPolygon(Pens.White, p);

            Point[] p1 = { point_culc(x_rot, y_rot, z_rot,  x_rot_theta,y_rot_theta,z_rot_theta,x2, y1, z1),
                 point_culc(x_rot, y_rot, z_rot,  x_rot_theta,y_rot_theta,z_rot_theta,x2, y2, z1),
                 point_culc(x_rot, y_rot, z_rot,  x_rot_theta,y_rot_theta,z_rot_theta,x2, y2, z2),
                 point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x2, y1, z2) };

            g.DrawPolygon(Pens.White, p1);

            Point[] p2 = { point_culc(x_rot, y_rot, z_rot,  x_rot_theta,y_rot_theta,z_rot_theta,x1, y1, z1),
                 point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x1, y2, z1),
                 point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x1, y2, z2),
                 point_culc(x_rot, y_rot, z_rot,  x_rot_theta,y_rot_theta,z_rot_theta,x1, y1, z2)};

            g.DrawPolygon(Pens.White, p2);

            Point[] p3 = { point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x1, y1, z2),
                 point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x2, y1, z2),
                 point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x2, y2, z2),
                 point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x1, y2, z2)};

            g.DrawPolygon(Pens.White, p3);

            Point[] p4 = { point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x1, y1, z1),
                 point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x2, y1, z1),
                 point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x2, y1, z2),
                 point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x1, y1, z2)};

            g.DrawPolygon(Pens.White, p4);

            Point[] p5 = { point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x1, y2, z1),
                 point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x2, y2, z1),
                 point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x2, y2, z2),
                 point_culc(x_rot, y_rot, z_rot, x_rot_theta,y_rot_theta,z_rot_theta, x1, y2, z2)};

            g.DrawPolygon(Pens.White, p5);

            g.DrawLine(Pens.DarkRed,
                point_culc(x_theta, y_theta, z_theta, x_rot_theta, y_rot_theta, z_rot_theta, ((x1 + x2) / 2) + 50, (y1 + y2) / 2, (z1 + z2) / 2),
                point_culc(x_theta, y_theta, z_theta, x_rot_theta, y_rot_theta, z_rot_theta, (x1 + x2) / 2, (y1 + y2) / 2, (z1 + z2) / 2)
                );
            g.DrawLine(Pens.DarkGreen,
                point_culc(x_theta, y_theta, z_theta, x_rot_theta, y_rot_theta, z_rot_theta, (x1 + x2) / 2, ((y1 + y2) / 2) + 50, (z1 + z2) / 2),
                point_culc(x_theta, y_theta, z_theta, x_rot_theta, y_rot_theta, z_rot_theta, (x1 + x2) / 2, (y1 + y2) / 2, (z1 + z2) / 2)
                );
            g.DrawLine(Pens.LightYellow,
                point_culc(x_theta, y_theta, z_theta, x_rot_theta, y_rot_theta, z_rot_theta, (x1 + x2) / 2, (y1 + y2) / 2, ((z1 + z2) / 2) + 50),
                point_culc(x_theta, y_theta, z_theta, x_rot_theta, y_rot_theta, z_rot_theta, (x1 + x2) / 2, (y1 + y2) / 2, (z1 + z2) / 2)
                );
        }

        public void clear()
        {
            g.Clear(Color.Black);
        }

        public void draw()
        {
            g.DrawLine(Pens.Red,
                point_culc(x_theta, y_theta, z_theta, 0, 0, 0, 100, 0, 0),
                point_culc(x_theta, y_theta, z_theta, 0, 0, 0, 0, 0, 0)
                );
            g.DrawLine(Pens.Green,
                point_culc(x_theta, y_theta, z_theta, 0, 0, 0, 0, 100, 0),
                point_culc(x_theta, y_theta, z_theta, 0, 0, 0, 0, 0, 0)
                );
            g.DrawLine(Pens.Yellow,
                point_culc(x_theta, y_theta, z_theta, 0, 0, 0, 0, 0, 100),
                point_culc(x_theta, y_theta, z_theta, 0, 0, 0, 0, 0, 0)
                );

            pictureBox.Image = canvas;
        }

        public void camera_change(double rotx,double roty,double rotz)
        {
            x_theta = rotx;
            y_theta = roty;
            z_theta = rotz;
            theta_lim(ref x_theta);
            theta_lim(ref y_theta);
            theta_lim(ref z_theta);
        }

        public void camera_step(double rotx, double roty, double rotz)
        {
            x_theta += rotx;
            y_theta += roty;
            z_theta += rotz;
            theta_lim(ref x_theta);
            theta_lim(ref y_theta);
            theta_lim(ref z_theta);
        }

        private void theta_lim(ref double t)
        {
            if (t > 360)
            {
                t -= 360;
            }
            if (t < 0)
            {
                t = 360 + t;
            }
        }
        /// <summary>
        ///Point calculation after rotation
        /// </summary>
        /// <param name="rotx">Rotation angle around the X axis (viewpoint)</param>
        /// <param name="roty">Rotation angle around the Y axis (viewpoint)</param>
        /// <param name="rotz">Rotation angle around the Z axis (viewpoint)</param>
        /// <param name="f_rotx">Rotation angle (figure) around the X axis</param>
        /// <param name="f_roty">Rotation angle around the Y axis (figure)</param>
        /// <param name="f_rotz">Rotation angle around Z axis (figure)</param>
        /// <param name="x">X coordinate</param>
        /// <param name="y">Y coordinate</param>
        /// <param name="z">Z coordinate</param>
        /// <returns></returns>
        private Point point_culc(double rotx, double roty, double rotz, double f_rotx, double f_roty, double f_rotz, double x, double y, double z)
        {
            double rad = Math.PI / 180;

            //Rotation of shapes

            //Rotate around the X axis
            double X_x = x * 1;
            double Y_x = y * Math.Cos(f_rotx * rad) - z * Math.Sin(f_rotx * rad);
            double Z_x = y * Math.Sin(f_rotx * rad) + z * Math.Cos(f_rotx * rad);

            //Rotate around the Y axis
            double X_y = X_x * Math.Cos(f_roty * rad) + Z_x * Math.Sin(f_roty * rad);
            double Y_y = Y_x * 1;
            double Z_y = -X_x * Math.Sin(f_roty * rad) + Z_x * Math.Cos(f_roty * rad);

            //Rotate around the Z axis
            double X_z = X_y * Math.Cos(f_rotz * rad) - Y_y * Math.Sin(f_rotz * rad);
            double Y_z = X_y * Math.Sin(f_rotz * rad) + Y_y * Math.Cos(f_rotz * rad);
            double Z_z = Z_y * 1;

            //Rotation of viewpoint
            double X_ = Math.Cos(roty * rad) * Math.Cos(rotz * rad) * X_z
                - Math.Cos(roty * rad) * Math.Sin(rotz * rad) * Y_z
                + Math.Sin(roty * rad) * Z_z;
            double Y_ = (Math.Sin(rotx * rad) * Math.Sin(roty * rad) * Math.Cos(rotz * rad) + Math.Cos(rotx * rad) * Math.Sin(rotz * rad)) * X_z
                + (-Math.Sin(rotx * rad) * Math.Sin(roty * rad) * Math.Sin(rotz * rad) + Math.Cos(rotx * rad) * Math.Cos(rotz * rad)) * Y_z
                - Math.Sin(rotx * rad) * Math.Cos(roty * rad) * Z_z;


            return new Point((int)(X_ + x_adj), (int)(Y_ + y_adj));
        }
    }
}

This time, we made it possible to rotate the viewpoint and the figure itself.

Last time, I only rotated the viewpoint, but to change the viewpoint, I have to rotate the 3D coordinates themselves.
For example, if you rotate it around the X axis, the Y and Z axes will also tilt.
The program there was a little bad, so I fixed it.

The program that calculates the coordinates when the figure itself is rotated is the same as the program that calculates the coordinates when the previous viewpoint is rotated.
It seems that I misunderstood that point.

Execution result

無題.png

The red, green, and yellow in the middle represent the X-axis, Y-axis, and Z-axis in three-dimensional space.
The small red, green, and yellow colors represent the original X-axis, Y-axis, and Z-axis of the displayed solid.
Since not only the viewpoint but also the solid itself is rotated, the orientations of the three axes in the three-dimensional space and the original three axes of the solid do not match.

Tags:

Updated: