CannibalSmith (cannibalsmith) rakstīja koderi kopienā, @ 2008-10-29 13:31:00 |
|
|||
public class Vector { public double x, y, z; public Vector(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } public static Vector operator *(Vector u, Matrix v) { Vector w = new Vector(); w.x = u.x * v.a + u.y * v.d * u.z * v.g + 1 * v.l; w.y = u.x * v.b + u.y * v.e + u.z * v.i + 1 * v.m; w.z = u.x * v.c + u.y * v.f + u.z * v.j + 1 * v.n; double h = u.x * v.p + u.y * v.q + u.z * v.r + 1 * v.s; w.x /= h; w.y /= h; w.z /= h; return w; } } public class Matrix { public double a, b, c, p, d, e, f, q, g, i, j, r, l, m, n, s; public Matrix() { a = 1; e = 1; j = 1; s = 1; } public static Matrix operator *(Matrix u, Matrix v) { Matrix w = new Matrix(); w.a = u.a * v.a + u.b * v.d + u.c * v.g + u.p * v.l; w.b = u.a * v.b + u.b * v.e + u.c * v.i + u.p * v.m; w.c = u.a * v.c + u.b * v.f + u.c * v.j + u.p * v.n; w.p = u.a * v.p + u.b * v.q + u.c * v.r + u.p * v.s; w.d = u.d * v.a + u.e * v.d + u.f * v.g + u.q * v.l; w.e = u.d * v.b + u.e * v.e + u.f * v.i + u.q * v.m; w.f = u.d * v.c + u.e * v.f + u.f * v.j + u.q * v.n; w.q = u.d * v.p + u.e * v.q + u.f * v.r + u.q * v.s; w.g = u.g * v.a + u.i * v.d + u.j * v.g + u.r * v.l; w.i = u.g * v.b + u.i * v.e + u.j * v.i + u.r * v.m; w.j = u.g * v.c + u.i * v.f + u.j * v.j + u.r * v.n; w.r = u.g * v.p + u.i * v.q + u.j * v.r + u.r * v.s; w.l = u.l * v.a + u.m * v.d + u.n * v.g + u.s * v.l; w.m = u.l * v.b + u.m * v.e + u.n * v.i + u.s * v.m; w.n = u.l * v.c + u.m * v.f + u.n * v.j + u.s * v.n; w.s = u.l * v.p + u.m * v.q + u.n * v.r + u.s * v.s; return w; } public static Matrix RotateX(double angle) { Matrix w = new Matrix(); w.e = Math.Cos(angle); w.f = Math.Sin(angle); w.i = -Math.Sin(angle); w.j = Math.Cos(angle); return w; } public static Matrix RotateY(double angle) { Matrix w = new Matrix(); w.a = Math.Cos(angle); w.c = -Math.Sin(angle); w.g = Math.Sin(angle); w.j = Math.Cos(angle); return w; } public static Matrix RotateZ(double angle) { Matrix w = new Matrix(); w.a = Math.Cos(angle); w.b = Math.Sin(angle); w.d = -Math.Sin(angle); w.e = Math.Cos(angle); return w; } public static Matrix Translate(double x, double y, double z) { Matrix w = new Matrix(); w.l = x; w.m = y; w.n = z; return w; } public static Matrix Scale(double x, double y, double z) { Matrix w = new Matrix(); w.a = x; w.e = y; w.j = z; return w; } } public class Node { Matrix transform; Node parent; Listchildren; public Node() { transform = new Matrix(); children = new List (); } public Node(Node parent) : this() { Parent = parent; } public virtual void Render(Graphics graphics, Matrix transform) { foreach (Node i in children) { i.Render(graphics, i.transform * transform); } } public List Children { get { return children; } } public Node Parent { get { return parent; } set { if (parent != null) { parent.children.Remove(this); } if (value != null) { value.children.Add(this); } parent = value; } } public Matrix Transform { get { return transform; } set { transform = value; } } } public class Mesh : Node { List vertices; Brush brush; public Mesh() : this(null) { } public Mesh(Node parent) : base(parent) { vertices = new List (); brush = Brushes.White; } public override void Render(Graphics graphics, Matrix transform) { base.Render(graphics, transform); foreach (Vector i in vertices) { Vector j = i * transform; if (j.z > 0.1) { float size = (float)(0.05 / j.z); graphics.FillRectangle(brush, (float)(j.x / j.z) - size / 2, (float)(j.y / j.z) - size / 2, size, size); } } } public Brush Brush { get { return brush; } set { brush = value; } } public List Vertices { get { return vertices; } } } public class Camera : Node { public Camera() { } public Camera(Node parent) : base(parent) { } public void Render(Graphics graphics) { float w = graphics.VisibleClipBounds.Width / 2; float h = graphics.VisibleClipBounds.Height / 2; graphics.Transform = new System.Drawing.Drawing2D.Matrix(h, 0, 0, -h, w, h); Matrix transform = new Matrix(); Node i; for (i = this; i.Parent != null; i = i.Parent) { transform = i.Transform * transform; } i.Render(graphics, transform); } } public partial class Window : Form { Node root; Camera camera; Mesh cube; Mesh cube2; Mesh cube3; Mesh ground; public Window() { InitializeComponent(); SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true); root = new Node(); camera = new Camera(root); camera.Transform = Matrix.Translate(0, -2, 0); ground = new Mesh(root); ground.Brush = Brushes.Green; for (double i = -10; i <= 10; i += 1) { for (double j = -10; j <= 10; j += 0.05) { ground.Vertices.Add(new Vector(i, 0, j)); ground.Vertices.Add(new Vector(j, 0, i)); } } cube = new Mesh(root); cube.Transform = Matrix.Scale(0.5, 0.5, 0.5) * Matrix.Translate(2, 0.5, 3.5); for (double i = -1; i <= 1; i += 0.1) { cube.Vertices.Add(new Vector(i, -1, -1)); cube.Vertices.Add(new Vector(-1, i, -1)); cube.Vertices.Add(new Vector(-1, -1, i)); cube.Vertices.Add(new Vector(i, 1, -1)); cube.Vertices.Add(new Vector(1, i, -1)); cube.Vertices.Add(new Vector(-1, 1, i)); cube.Vertices.Add(new Vector(1, 1, i)); cube.Vertices.Add(new Vector(1, -1, i)); cube.Vertices.Add(new Vector(-1, i, 1)); cube.Vertices.Add(new Vector(i, -1, 1)); cube.Vertices.Add(new Vector(i, 1, 1)); cube.Vertices.Add(new Vector(1, i, 1)); } cube2 = new Mesh(root); cube2.Vertices = cube.Vertices; cube2.Transform = Matrix.Scale(0.5, 0.5, 0.5) * Matrix.Translate(0, 0.5, 3.5); cube3 = new Mesh(root); cube3.Vertices = cube.Vertices; cube3.Transform = Matrix.Scale(0.5, 0.5, 0.5) * Matrix.Translate(-2, 0.5, 3.5); } void Window_Paint(object sender, PaintEventArgs e) { camera.Render(e.Graphics); } void timer1_Tick(object sender, EventArgs e) { cube.Transform = Matrix.RotateZ(0.05) * cube.Transform; cube2.Transform = Matrix.RotateY(0.05) * cube2.Transform; cube3.Transform = Matrix.RotateX(0.05) * cube3.Transform; Invalidate(); } }
Nopūsties: