您的位置:首页 > 编程语言 > C#

C# 实现立体图形变换(vs2008)

2014-05-16 23:14 246 查看
using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Drawing.Drawing2D;

namespace ConbinedTransformation

{

public partial class Form1 : Form

{

int flag = 0;

///立方体初始顶点坐标

float[,] Cube1 = { { -1, -0.5f, -1 }, { 1, -0.5f, -1 }, { 1, -0.5f, 1 }, { -1, -0.5f, 1 },

{ -1,  0.5f, -1 }, { 1,  0.5f, -1 }, { 1,  0.5f, 1 }, { -1,  0.5f, 1 } };

float[,] Cube2 = { { -1, -0.5f, -1 }, { 1, -0.5f, -1 }, { 1, -0.5f, 1 }, { -1, -0.5f, 1 },

{ -1,  0.5f, -1 }, { 1,  0.5f, -1 }, { 1,  0.5f, 1 }, { -1,  0.5f, 1 } };

Vector4[] tCube1 = new Vector4[8];   //变换后的Cube1顶点坐标

Vector4[] tCube2 = new Vector4[8];

float translationx, rotationy;//瞬时运动参数,平移、转角

float xstep, rstep;        //单位时间移动、转动步长

float cx, cy, cz;          //照相机位置

float dx, dy, dz;         //照相机方向

float upx, upy, upz;      //照相机上方

float ux, uy, uz, vx, vy, vz, nx, ny, nz;    //照相机坐标系

float zp;               //视平面位置

float wxl, wxr, wyb, wyt;  //窗口参数

float vxl, vxr, vyb, vyt;    //视区参数

Graphics g;

public Form1()

{

InitializeComponent();

g = CreateGraphics();

g.SmoothingMode = SmoothingMode.AntiAlias;

//图形运动参数,平移、转动、平移步长,转动步长为10度

translationx = 0;

rotationy = 0;

xstep = 0.2f;

rstep = 10;

cx = 2; cy = 5; cz = 12;      //照相机位置

dx = -cx; dy = -cy; dz = -cz; //照相机方向

upx = 0; upy = 1; upz = 0;    //照相机上方参考向量

zp = cz;                      //投影面位置

wxl = -5; wxr = 5; wyb = -3; wyt = 3;   //窗口参数

vxl = 0; vxr = 640; vyb = 0; vyt = 480; //视区参数

float d;  //单位化视线向量

d = (float)Math.Sqrt(dx * dx   dy * dy   dz * dz);

///照相机坐标系第3轴,N = (dx,dy,dz)

nx = dx / d;

ny = dy / d;

nz = dz / d;

///照相机坐标系第1轴,U = N * UP

ux = (ny * upz - nz * upy);

uy = (nz * upx - nx * upz);

uz = (nx * upy - ny * upx);

///照相机坐标系第2轴,V = U * N

vx = (uy * nz - uz * ny);

vy = (uz * nx - ux * nz);

vz = (ux * ny - uy * nx);

}

private void DrawString()

{

String str;

str = "点击鼠标: (暂停/继续)";

g.DrawString(str, new Font("宋体", 16, FontStyle.Regular), Brushes.Black, 300, 30);

}

private void Form1_Load(object sender, EventArgs e)

{

}

private void timer1_Tick(object sender, EventArgs e)

{

doConbinedTransformation();

DrawString();

}

private void doConbinedTransformation()

{

int i;

Matrix4x4 M = new Matrix4x4();

for (i = 0; i < 8; i )

{

tCube1[i] = new Vector4(Cube1[i, 0], Cube1[i, 1], Cube1[i, 2], 1);

tCube2[i] = new Vector4(Cube2[i, 0], Cube2[i, 1], Cube2[i, 2], 1);

}

translationx  = xstep;

if ((translationx >= 5) || (translationx <= -5)) xstep = -xstep;

rotationy  = rstep;

if (rotationy > 360) rotationy -= 360;

//Cube1的变换

//平移x

M.identity();

M.e14 = translationx;

M.e24 = 0.5f;

for (i = 0; i < 8; i )

tCube1[i] = M * tCube1[i];

//照相机变换

M.identity();

M.e14 = cx;

M.e24 = cy;

M.e34 = cz;

for (i = 0; i < 8; i )

tCube1[i] = M * tCube1[i];

M.identity();

M.e11 = ux; M.e12 = uy; M.e13 = uz;

M.e21 = vx; M.e22 = vy; M.e23 = vz;

M.e31 = nx; M.e32 = ny; M.e33 = nz;

for (i = 0; i < 8; i )

tCube1[i] = M * tCube1[i];

//投影变换

for (i = 0; i < 8; i )

{

M.identity();

M.e11 = -zp / tCube1[i].z;

M.e22 = -zp / tCube1[i].z;

M.e33 = zp;

tCube1[i] = M * tCube1[i];

}

//视窗变换

M.identity();

M.e11 = (vxr - vxl) / (wxr - wxl);

M.e22 = (vyt - vyb) / (wyt - wyb);

M.e14 = vxl - (vxr - vxl) / (wxr - wxl) * wxl;

M.e24 = vyb - (vyt - vyb) / (wyt - wyb) * wyb;

for (i = 0; i < 8; i )

tCube1[i] = M * tCube1[i];

//Cube2的变换/////////////////

//////////////////////////////

//y轴转动

M.identity();

M.e11 = (float)Math.Cos(rotationy * 3.14159 / 180.0);

M.e33 = (float)Math.Cos(rotationy * 3.14159 / 180.0);

M.e13 = (float)Math.Sin(rotationy * 3.14159 / 180.0);

M.e31 = -(float)Math.Sin(rotationy * 3.14159 / 180.0);

for (i = 0; i < 8; i )

tCube2[i] = M * tCube2[i];

//平移x

M.identity();

M.e14 = translationx;

M.e24 = -0.5f;

for (i = 0; i < 8; i )

tCube2[i] = M * tCube2[i];

//照相机变换

M.identity();

M.e14 = cx;

M.e24 = cy;

M.e34 = cz;

for (i = 0; i < 8; i )

tCube2[i] = M * tCube2[i];

M.identity();

M.e11 = ux; M.e12 = uy; M.e13 = uz;

M.e21 = vx; M.e22 = vy; M.e23 = vz;

M.e31 = nx; M.e32 = ny; M.e33 = nz;

for (i = 0; i < 8; i )

tCube2[i] = M * tCube2[i];

//投影变换

for (i = 0; i < 8; i )

{

M.identity();

M.e11 = -zp / tCube2[i].z;

M.e22 = -zp / tCube2[i].z;

M.e33 = zp;

tCube2[i] = M * tCube2[i];

}

//视窗变换

M.identity();

M.e11 = (vxr - vxl) / (wxr - wxl);

M.e22 = (vyt - vyb) / (wyt - wyb);

M.e14 = vxl - (vxr - vxl) / (wxr - wxl) * wxl;

M.e24 = vyb - (vyt - vyb) / (wyt - wyb) * wyb;

for (i = 0; i < 8; i )

tCube2[i] = M * tCube2[i];

//绘图

g.Clear(Color.White);

g.DrawLine(Pens.Red, tCube1[0].x, tCube1[0].y, tCube1[1].x, tCube1[1].y);

g.DrawLine(Pens.Red, tCube1[1].x, tCube1[1].y, tCube1[2].x, tCube1[2].y);

g.DrawLine(Pens.Red, tCube1[2].x, tCube1[2].y, tCube1[3].x, tCube1[3].y);

g.DrawLine(Pens.Red, tCube1[3].x, tCube1[3].y, tCube1[0].x, tCube1[0].y);

g.DrawLine(Pens.Red, tCube1[4].x, tCube1[4].y, tCube1[5].x, tCube1[5].y);

g.DrawLine(Pens.Red, tCube1[5].x, tCube1[5].y, tCube1[6].x, tCube1[6].y);

g.DrawLine(Pens.Red, tCube1[6].x, tCube1[6].y, tCube1[7].x, tCube1[7].y);

g.DrawLine(Pens.Red, tCube1[7].x, tCube1[7].y, tCube1[4].x, tCube1[4].y);

g.DrawLine(Pens.Red, tCube1[0].x, tCube1[0].y, tCube1[4].x, tCube1[4].y);

g.DrawLine(Pens.Red, tCube1[1].x, tCube1[1].y, tCube1[5].x, tCube1[5].y);

g.DrawLine(Pens.Red, tCube1[2].x, tCube1[2].y, tCube1[6].x, tCube1[6].y);

g.DrawLine(Pens.Red, tCube1[3].x, tCube1[3].y, tCube1[7].x, tCube1[7].y);

g.DrawLine(Pens.Blue, tCube2[0].x, tCube2[0].y, tCube2[1].x, tCube2[1].y);

g.DrawLine(Pens.Blue, tCube2[1].x, tCube2[1].y, tCube2[2].x, tCube2[2].y);

g.DrawLine(Pens.Blue, tCube2[2].x, tCube2[2].y, tCube2[3].x, tCube2[3].y);

g.DrawLine(Pens.Blue, tCube2[3].x, tCube2[3].y, tCube2[0].x, tCube2[0].y);

g.DrawLine(Pens.Blue, tCube2[4].x, tCube2[4].y, tCube2[5].x, tCube2[5].y);

g.DrawLine(Pens.Blue, tCube2[5].x, tCube2[5].y, tCube2[6].x, tCube2[6].y);

g.DrawLine(Pens.Blue, tCube2[6].x, tCube2[6].y, tCube2[7].x, tCube2[7].y);

g.DrawLine(Pens.Blue, tCube2[7].x, tCube2[7].y, tCube2[4].x, tCube2[4].y);

g.DrawLine(Pens.Blue, tCube2[0].x, tCube2[0].y, tCube2[4].x, tCube2[4].y);

g.DrawLine(Pens.Blue, tCube2[1].x, tCube2[1].y, tCube2[5].x, tCube2[5].y);

g.DrawLine(Pens.Blue, tCube2[2].x, tCube2[2].y, tCube2[6].x, tCube2[6].y);

g.DrawLine(Pens.Blue, tCube2[3].x, tCube2[3].y, tCube2[7].x, tCube2[7].y);

}

private void Form1_MouseClick(object sender, MouseEventArgs e)

{

switch (flag)

{

case 0:

this.timer1.Enabled = false;

flag = 1;

break;

case 1:

this.timer1.Enabled = true;

flag = 0;

break;

}

}

private void Form1_Paint(object sender, PaintEventArgs e)

{

}

}

/////////////////////////  数学类 Vecto3

public class Vector4

{

public static float pi = 3.14159265f;

public static float tol = 0.000000000000001f;  // float type tolerance

public float x;

public float y;

public float z;

public float w;

public Vector4()

{

x = 0; y = 0; z = 0; w = 1;

}

public Vector4(float xi, float yi, float zi, float wi)

{

x = xi;

y = yi;

z = zi;

w = wi;

}

public float Magnitude()

{

return (float)Math.Sqrt(x * x   y * y   z * z);

}

public void Normalize()

{

if (w != 1)

{

x /= w;

y /= w;

z /= w;

w = 1;

}

}

}

////////////////// 矩阵类

public class Matrix4x4

{

// elements eij: i -> row, j -> column

public float e11, e12, e13, e14, e21, e22, e23, e24, e31, e32, e33, e34, e41, e42, e43, e44;

public Matrix4x4()

{

e11 = 1; e12 = 0; e13 = 0; e14 = 0;

e21 = 0; e22 = 1; e23 = 0; e24 = 0;

e31 = 0; e32 = 0; e33 = 1; e34 = 0;

e41 = 0; e42 = 0; e43 = 0; e44 = 1;

}

public Matrix4x4(float r1c1, float r1c2, float r1c3, float r1c4,

float r2c1, float r2c2, float r2c3, float r2c4,

float r3c1, float r3c2, float r3c3, float r3c4,

float r4c1, float r4c2, float r4c3, float r4c4)

{

e11 = r1c1; e12 = r1c2; e13 = r1c3; e14 = r1c4;

e21 = r2c1; e22 = r2c2; e23 = r2c3; e24 = r2c4;

e31 = r3c1; e32 = r3c2; e33 = r3c3; e34 = r3c4;

e41 = r4c1; e42 = r4c2; e43 = r4c3; e44 = r4c4;

}

public void identity()

{

e11 = 1; e12 = 0; e13 = 0; e14 = 0;

e21 = 0; e22 = 1; e23 = 0; e24 = 0;

e31 = 0; e32 = 0; e33 = 1; e34 = 0;

e41 = 0; e42 = 0; e43 = 0; e44 = 1;

}

public Matrix4x4 Transpose()

{

return new Matrix4x4(e11, e21, e31, e41, e12, e22, e32, e42, e13, e23, e33, e43, e41, e42, e43, e44);

}

public static Matrix4x4 operator *(Matrix4x4 m1, Matrix4x4 m2)

{

return new Matrix4x4(m1.e11 * m2.e11   m1.e12 * m2.e21   m1.e13 * m2.e31   m1.e14 * m2.e41,

m1.e11 * m2.e12   m1.e12 * m2.e22   m1.e13 * m2.e32   m1.e14 * m2.e42,

m1.e11 * m2.e13   m1.e12 * m2.e23   m1.e13 * m2.e33   m1.e14 * m2.e43,

m1.e11 * m2.e14   m1.e12 * m2.e24   m1.e13 * m2.e34   m1.e14 * m2.e44,

m1.e21 * m2.e11   m1.e22 * m2.e21   m1.e23 * m2.e31   m1.e24 * m2.e41,

m1.e21 * m2.e12   m1.e22 * m2.e22   m1.e23 * m2.e32   m1.e24 * m2.e42,

m1.e21 * m2.e13   m1.e22 * m2.e23   m1.e23 * m2.e33   m1.e24 * m2.e43,

m1.e21 * m2.e14   m1.e22 * m2.e24   m1.e23 * m2.e34   m1.e24 * m2.e44,

m1.e31 * m2.e11   m1.e32 * m2.e21   m1.e33 * m2.e31   m1.e34 * m2.e41,

m1.e31 * m2.e12   m1.e32 * m2.e22   m1.e33 * m2.e32   m1.e34 * m2.e42,

m1.e31 * m2.e13   m1.e32 * m2.e23   m1.e33 * m2.e33   m1.e34 * m2.e43,

m1.e31 * m2.e14   m1.e32 * m2.e24   m1.e33 * m2.e34   m1.e34 * m2.e44,

m1.e41 * m2.e11   m1.e42 * m2.e21   m1.e43 * m2.e31   m1.e44 * m2.e41,

m1.e41 * m2.e12   m1.e42 * m2.e22   m1.e43 * m2.e32   m1.e44 * m2.e42,

m1.e41 * m2.e13   m1.e42 * m2.e23   m1.e43 * m2.e33   m1.e44 * m2.e43,

m1.e41 * m2.e14   m1.e42 * m2.e24   m1.e43 * m2.e34   m1.e44 * m2.e44

);

}

public static Vector4 operator *(Matrix4x4 m, Vector4 u)

{

return new Vector4(m.e11 * u.x   m.e12 * u.y   m.e13 * u.z   m.e14 * u.w,

m.e21 * u.x   m.e22 * u.y   m.e23 * u.z   m.e24 * u.w,

m.e31 * u.x   m.e32 * u.y   m.e33 * u.z   m.e34 * u.w,

m.e41 * u.x   m.e42 * u.y   m.e43 * u.z   m.e44 * u.w);

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: