#C#で立体を描くプログラム
立体を描くライブラリはたくさんありますが、今回はそれらは一切使いません。
「極力ライブラリや人の作ったものに頼らない」という考えでやっています。が、高級なことができない・・・。
##立体を描くクラス
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)
{
g.Clear(Color.Black);
Point[] p = { point_culc(x_theta, y_theta, z_theta, x1, y1, z1),
point_culc(x_theta, y_theta, z_theta, x2, y1, z1),
point_culc(x_theta, y_theta, z_theta, x2, y2, z1),
point_culc(x_theta, y_theta, z_theta, x1, y2, z1)};
g.DrawPolygon(Pens.White, p);
Point[] p1 = { point_culc(x_theta, y_theta, z_theta, x2, y1, z1),
point_culc(x_theta, y_theta, z_theta, x2, y2, z1),
point_culc(x_theta, y_theta, z_theta, x2, y2, z2),
point_culc(x_theta, y_theta, z_theta, x2, y1, z2)};
g.DrawPolygon(Pens.White, p1);
Point[] p2 = { point_culc(x_theta, y_theta, z_theta, x1, y1, z1),
point_culc(x_theta, y_theta, z_theta, x1, y2, z1),
point_culc(x_theta, y_theta, z_theta, x1, y2, z2),
point_culc(x_theta, y_theta, z_theta, x1, y1, z2)};
g.DrawPolygon(Pens.White, p2);
Point[] p3 = { point_culc(x_theta, y_theta, z_theta, x1, y1, z2),
point_culc(x_theta, y_theta, z_theta, x2, y1, z2),
point_culc(x_theta, y_theta, z_theta, x2, y2, z2),
point_culc(x_theta, y_theta, z_theta, x1, y2, z2)};
g.DrawPolygon(Pens.White, p3);
Point[] p4 = { point_culc(x_theta, y_theta, z_theta, x1, y1, z1),
point_culc(x_theta, y_theta, z_theta, x2, y1, z1),
point_culc(x_theta, y_theta, z_theta, x2, y1, z2),
point_culc(x_theta, y_theta, z_theta, x1, y1, z2)};
g.DrawPolygon(Pens.White, p4);
Point[] p5 = { point_culc(x_theta, y_theta, z_theta, x1, y2, z1),
point_culc(x_theta, y_theta, z_theta, x2, y2, z1),
point_culc(x_theta, y_theta, z_theta, x2, y2, z2),
point_culc(x_theta, y_theta, z_theta, x1, y2, z2)};
g.DrawPolygon(Pens.White, p5);
g.DrawLine(Pens.Red,
point_culc(x_theta, y_theta, z_theta, 100, 0, 0),
point_culc(x_theta, y_theta, z_theta, 0, 0, 0)
);
g.DrawLine(Pens.Green,
point_culc(x_theta, y_theta, z_theta, 0, 100, 0),
point_culc(x_theta, y_theta, z_theta, 0, 0, 0)
);
g.DrawLine(Pens.Yellow,
point_culc(x_theta, y_theta, z_theta, 0, 0, 100),
point_culc(x_theta, y_theta, z_theta, 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>
///
/// </summary>
/// <param name="rotx">X軸回転角度</param>
/// <param name="roty">Y軸回転角度</param>
/// <param name="rotz">Z軸回転角度</param>
/// <param name="x">X座標</param>
/// <param name="y">Y座標</param>
/// <param name="z">Z座標</param>
private Point point_culc(double rotx, double roty, double rotz, double x, double y, double z)
{
//X軸周りで回転
double X_x = x * 1;
double Y_x = y * Math.Cos(rotx * (Math.PI / 180)) - z * Math.Sin(rotx * (Math.PI / 180));
double Z_x = y * Math.Sin(rotx * (Math.PI / 180)) + z * Math.Cos(rotx * (Math.PI / 180));
//Y軸周りで回転
double X_y = X_x * Math.Cos(roty * (Math.PI / 180)) + Z_x * Math.Sin(roty * (Math.PI / 180));
double Y_y = Y_x * 1;
double Z_y = -X_x * Math.Sin(roty * (Math.PI / 180)) + Z_x * Math.Cos(roty * (Math.PI / 180));
//Z軸周りで回転
double X_z = X_y * Math.Cos(rotz * (Math.PI / 180)) - Y_y * Math.Sin(rotz * (Math.PI / 180));
double Y_z = X_y * Math.Sin(rotz * (Math.PI / 180)) + Y_y * Math.Cos(rotz * (Math.PI / 180));
double Z_z = Z_y * 1;
return new Point((int)(X_z + x_adj), (int)(Y_z + y_adj));
}
}
}
3D描画するクラスです。
コンストラクタは、描画するためのPictureBox
を引数に取っています。
void cuboid(double x1, double y1, double z1, double x2, double y2, double z2)
cuboid
関数は、直方体の対角線上にある2点の座標を引数に取ります。
実行すれば、PictureBox
に直方体を描くことができます。
void camera_change(double rotx,double roty,double rotz)
void camera_step(double rotx, double roty, double rotz)
camera_change
関数とcamera_step
関数は視点を変える関数です。X,Y,Z軸の回転角度を引数に取ります。
camera_change
関数は、指定された回転角度にします。
camera_step
関数は、現在の回転角度から指定された回転角度分だけ回転させます。
##実行結果