using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace WindowsFormsApplication4
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
static double angle = 0.1;
private Point[] XYZpersp;
//Tramsform OX:
double[,] transformMatrix = new double[4, 4] {
{1,0,0,0},
{0,Math.Cos(angle), -Math.Sin(angle),0},
{0,Math.Sin(angle),Math.Cos(angle),0},
{0,0,0,1}};
//Tramsform OY:
double[,] transformMatrix1 = new double[4, 4] {
{Math.Cos(angle),0,Math.Sin(angle),0},
{0,1,0,0},
{-Math.Sin(angle),0,Math.Cos(angle),0},
{0,0,0,1}};
//Tramsform OZ:
double[,] transformMatrix2 = new double[4, 4] {
{Math.Cos(angle),-Math.Sin(angle),0,0},
{Math.Sin(angle),Math.Cos(angle),0,0},
{0,0,1,0},
{0,0,0,1}};
//Projection matrix:
double[,] protectionMatrix = new double[4,4] {
{0.5, 0, 0, 0.00346},
{0,1,0,0},
{0.866, 0,0,-0.002},
{0,10,0,1}};
double[,] vp = new double[3, 4]{
{1,0,0,0},
{0,1,0,0},
{0,0,1,0}};
double[,] cube = new double[8, 4] {
{0,0,0,1},
{0,50,0,1},
{50,50,0,1},
{50,0,0,1},
{0,0,50,1},
{0,50,50,1},
{50,50,50,1},
{50,0,50,1}};
private Point[] getPoints(double[,] cube)
{
Point[] ps = new Point[8];
for (int i = 0; i < cube.GetLength(0); ++i)
{
ps[i] = new Point((int)cube[i, 0], (int)cube[i, 1]);
}
return ps;
}
private double[,] multiplyMatrix(double[,] a, double[,] b)
{
double[,] res = new double[a.GetLength(0), a.GetLength(1)];
for (int row = 0; row < a.GetLength(0); row++)
{
for (int col = 0; col < a.GetLength(1); col++)
{
for (int inner = 0; inner < a.GetLength(1); inner++)
{
res[row, col] += a[row, inner] * b[inner, col];
}
}
}
return res;
}
private void multiplyTrMatrix(double[,] m1, double [,] m2)
{
double[,] res = new double[8, 4];
for (int row = 0; row < 8; row++)
{
for (int col = 0; col < 4; col++)
{
for (int inner = 0; inner < 4; inner++)
{
res[row, col] += m1[row, inner] * m2[inner, col];
}
}
}
cube = res;
}
private void reDraw()
{
Graphics g = pictureBox1.CreateGraphics();
g.Clear(SystemColors.Window);
g.TranslateTransform(this.ClientRectangle.Width / 4, this.ClientRectangle.Height / 2);
g.SmoothingMode = SmoothingMode.HighQuality;
Point[] ps = getPoints(cube);
GraphicsPath path = new GraphicsPath();
XYZpersp = getPoints(multiplyMatrix(vp, protectionMatrix));
Point center = getCenterWeight(ps);
g.DrawLine(new Pen(new SolidBrush(Color.Green), 1), XYZpersp[0], center);
g.DrawString("X", new Font("Verdana", 10), new SolidBrush(Color.Black), XYZpersp[0]);
g.DrawLine(new Pen(new SolidBrush(Color.Red), 1), XYZpersp[1], center);
g.DrawString("Y", new Font("Verdana", 10), new SolidBrush(Color.Black), XYZpersp[1]);
g.DrawLine(new Pen(new SolidBrush(Color.Blue), 1), XYZpersp[2], center);
g.DrawString("Z", new Font("Verdana", 10), new SolidBrush(Color.Black), XYZpersp[2]);
path.AddPolygon(new Point[4] {
ps[4],
ps[0],
ps[1],
ps[5]
});
path.AddPolygon(new Point[4] {
ps[2],
ps[3],
ps[7],
ps[6]
});
path.AddPolygon(new Point[4] {
ps[2],
ps[3],
ps[0],
ps[1]
});
path.AddPolygon(new Point[4] {
ps[6],
ps[5],
ps[4],
ps[7]
});
path.AddPolygon(new Point[4] {
ps[2],
ps[6],
ps[5],
ps[1]
});
path.AddPolygon(new Point[4] {
ps[3],
ps[7],
ps[4],
ps[0]
});
g.FillPolygon(new LinearGradientBrush(
new Point(ps[4].X,ps[0].Y),
new Point(ps[1].X,ps[5].Y),
Color.Red,
Color.BlueViolet),
new Point[4] {
ps[4],
ps[0],
ps[1],
ps[5]
});
g.FillPolygon(new LinearGradientBrush(
new Point(ps[2].X, ps[3].Y),
new Point(ps[7].X, ps[6].Y),
Color.Red,
Color.BlueViolet),
new Point[4] {
ps[2],
ps[3],
ps[7],
ps[6]
});
g.FillPolygon(new LinearGradientBrush(
new Point(ps[2].X, ps[3].Y),
new Point(ps[0].X, ps[1].Y),
Color.Red,
Color.BlueViolet),
new Point[4] {
ps[2],
ps[3],
ps[0],
ps[1]
});
g.FillPolygon(new LinearGradientBrush(
new Point(ps[6].X, ps[5].Y),
new Point(ps[4].X, ps[7].Y),
Color.Red,
Color.BlueViolet),
new Point[4] {
ps[6],
ps[5],
ps[4],
ps[7]
});
g.FillPolygon(new LinearGradientBrush(
new Point(ps[2].X, ps[6].Y),
new Point(ps[5].X, ps[1].Y),
Color.Red,
Color.BlueViolet),
new Point[4] {
ps[2],
ps[6],
ps[5],
ps[1]
});
g.FillPolygon(new LinearGradientBrush(
new Point(ps[3].X, ps[7].Y),
new Point(ps[4].X, ps[0].Y),
Color.Red,
Color.BlueViolet),
new Point[4] {
ps[3],
ps[7],
ps[4],
ps[0]
});
}
private Point getCenterWeight(Point[] ps)
{
double sumX = 0, sumY = 0;
for (int i = 0; i < ps.Length; ++i)
{
sumX += ps[i].X;
sumY += ps[i].Y;
}
return new Point((int)(sumX / ps.Length), (int)(sumY / ps.Length));
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
multiplyTrMatrix(cube,transformMatrix);
reDraw();
timer1.Enabled = !timer1.Enabled;
}
private void button2_Click(object sender, EventArgs e)
{
multiplyTrMatrix(cube,transformMatrix1);
reDraw();
timer2.Enabled = !timer2.Enabled;
}
private void button3_Click(object sender, EventArgs e)
{
multiplyTrMatrix(cube, protectionMatrix);
reDraw();
}
private void pictureBox1_Click(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
multiplyTrMatrix(cube, transformMatrix);
reDraw();
}
private void timer2_Tick(object sender, EventArgs e)
{
multiplyTrMatrix(cube, transformMatrix1);
reDraw();
}
private void timer3_Tick(object sender, EventArgs e)
{
multiplyTrMatrix(cube, transformMatrix2);
reDraw();
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
private void button4_Click(object sender, EventArgs e)
{
}
}
}