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

  1 using System;
  2 
  3 using System.Collections.Generic;
  4 
  5 using System.ComponentModel;
  6 
  7 using System.Data;
  8 
  9 using System.Drawing;
 10 
 11 using System.Linq;
 12 
 13 using System.Text;
 14 
 15 using System.Windows.Forms;
 16 
 17 using System.Drawing.Drawing2D;
 18 
 19  
 20 
 21  
 22 
 23 namespace ConbinedTransformation
 24 
 25 {
 26 
 27     public partial class Form1 : Form
 28 
 29     {
 30 
 31         int flag = 0;
 32 
 33         ///立方体初始顶点坐标
 34 
 35         float[,] Cube1 = { { -1, -0.5f, -1 }, { 1, -0.5f, -1 }, { 1, -0.5f, 1 }, { -1, -0.5f, 1 },
 36 
 37                    { -1,  0.5f, -1 }, { 1,  0.5f, -1 }, { 1,  0.5f, 1 }, { -1,  0.5f, 1 } };
 38 
 39         float[,] Cube2 = { { -1, -0.5f, -1 }, { 1, -0.5f, -1 }, { 1, -0.5f, 1 }, { -1, -0.5f, 1 },
 40 
 41                    { -1,  0.5f, -1 }, { 1,  0.5f, -1 }, { 1,  0.5f, 1 }, { -1,  0.5f, 1 } };
 42 
 43         Vector4[] tCube1 = new Vector4[8];   //变换后的Cube1顶点坐标
 44 
 45         Vector4[] tCube2 = new Vector4[8];
 46 
 47         float translationx, rotationy;//瞬时运动参数,平移、转角
 48 
 49         float xstep, rstep;        //单位时间移动、转动步长
 50 
 51         float cx, cy, cz;          //照相机位置
 52 
 53         float dx, dy, dz;         //照相机方向
 54 
 55         float upx, upy, upz;      //照相机上方
 56 
 57         float ux, uy, uz, vx, vy, vz, nx, ny, nz;    //照相机坐标系
 58 
 59         float zp;               //视平面位置
 60 
 61         float wxl, wxr, wyb, wyt;  //窗口参数
 62 
 63         float vxl, vxr, vyb, vyt;    //视区参数
 64 
 65         Graphics g;
 66 
 67  
 68 
 69         public Form1()
 70 
 71         {
 72 
 73             InitializeComponent();
 74 
 75             g = CreateGraphics();
 76 
 77             g.SmoothingMode = SmoothingMode.AntiAlias;
 78 
 79  
 80 
 81             //图形运动参数,平移、转动、平移步长,转动步长为10度
 82 
 83             translationx = 0;
 84 
 85             rotationy = 0;
 86 
 87             xstep = 0.2f;
 88 
 89             rstep = 10;
 90 
 91  
 92 
 93             cx = 2; cy = 5; cz = 12;      //照相机位置
 94 
 95             dx = -cx; dy = -cy; dz = -cz; //照相机方向
 96 
 97             upx = 0; upy = 1; upz = 0;    //照相机上方参考向量
 98 
 99             zp = cz;                      //投影面位置
100 
101  
102 
103             wxl = -5; wxr = 5; wyb = -3; wyt = 3;   //窗口参数
104 
105             vxl = 0; vxr = 640; vyb = 0; vyt = 480; //视区参数
106 
107  
108 
109             float d;  //单位化视线向量
110 
111             d = (float)Math.Sqrt(dx * dx   dy * dy   dz * dz);
112 
113  
114 
115             ///照相机坐标系第3轴,N = (dx,dy,dz)
116 
117             nx = dx / d;
118 
119             ny = dy / d;
120 
121             nz = dz / d;
122 
123  
124 
125             ///照相机坐标系第1轴,U = N * UP
126 
127             ux = (ny * upz - nz * upy);
128 
129             uy = (nz * upx - nx * upz);
130 
131             uz = (nx * upy - ny * upx);
132 
133  
134 
135             ///照相机坐标系第2轴,V = U * N
136 
137             vx = (uy * nz - uz * ny);
138 
139             vy = (uz * nx - ux * nz);
140 
141             vz = (ux * ny - uy * nx);
142 
143  
144 
145         }
146 
147  
148 
149         private void DrawString()
150 
151         {
152 
153             String str;
154 
155             str = "点击鼠标: (暂停/继续)";
156 
157             g.DrawString(str, new Font("宋体", 16, FontStyle.Regular), Brushes.Black, 300, 30);
158 
159         }
160 
161  
162 
163         private void Form1_Load(object sender, EventArgs e)
164 
165         {
166 
167  
168 
169         }
170 
171  
172 
173         private void timer1_Tick(object sender, EventArgs e)
174 
175         {
176 
177             doConbinedTransformation();
178 
179             DrawString();
180 
181         }
182 
183  
184 
185         private void doConbinedTransformation()
186 
187         {
188 
189             int i;
190 
191             Matrix4x4 M = new Matrix4x4();
192 
193  
194 
195             for (i = 0; i < 8; i )
196 
197             {
198 
199                 tCube1[i] = new Vector4(Cube1[i, 0], Cube1[i, 1], Cube1[i, 2], 1);
200 
201                 tCube2[i] = new Vector4(Cube2[i, 0], Cube2[i, 1], Cube2[i, 2], 1);
202 
203             }
204 
205  
206 
207             translationx  = xstep;
208 
209             if ((translationx >= 5) || (translationx <= -5)) xstep = -xstep;
210 
211             rotationy  = rstep;
212 
213             if (rotationy > 360) rotationy -= 360;
214 
215  
216 
217             //Cube1的变换
218 
219             //平移x
220 
221             M.identity();
222 
223             M.e14 = translationx;
224 
225             M.e24 = 0.5f;
226 
227             for (i = 0; i < 8; i )
228 
229                 tCube1[i] = M * tCube1[i];
230 
231  
232 
233             //照相机变换
234 
235             M.identity();
236 
237             M.e14 = cx;
238 
239             M.e24 = cy;
240 
241             M.e34 = cz;
242 
243             for (i = 0; i < 8; i )
244 
245                 tCube1[i] = M * tCube1[i];
246 
247  
248 
249             M.identity();
250 
251             M.e11 = ux; M.e12 = uy; M.e13 = uz;
252 
253             M.e21 = vx; M.e22 = vy; M.e23 = vz;
254 
255             M.e31 = nx; M.e32 = ny; M.e33 = nz;
256 
257             for (i = 0; i < 8; i )
258 
259                 tCube1[i] = M * tCube1[i];
260 
261  
262 
263             //投影变换
264 
265             for (i = 0; i < 8; i )
266 
267             {
268 
269                 M.identity();
270 
271                 M.e11 = -zp / tCube1[i].z;
272 
273                 M.e22 = -zp / tCube1[i].z;
274 
275                 M.e33 = zp;
276 
277  
278 
279                 tCube1[i] = M * tCube1[i];
280 
281             }
282 
283             //视窗变换
284 
285             M.identity();
286 
287             M.e11 = (vxr - vxl) / (wxr - wxl);
288 
289             M.e22 = (vyt - vyb) / (wyt - wyb);
290 
291             M.e14 = vxl - (vxr - vxl) / (wxr - wxl) * wxl;
292 
293             M.e24 = vyb - (vyt - vyb) / (wyt - wyb) * wyb;
294 
295             for (i = 0; i < 8; i )
296 
297                 tCube1[i] = M * tCube1[i];
298 
299  
300 
301             //Cube2的变换/////////////////
302 
303             //////////////////////////////
304 
305             //y轴转动
306 
307  
308 
309             M.identity();
310 
311             M.e11 = (float)Math.Cos(rotationy * 3.14159 / 180.0);
312 
313             M.e33 = (float)Math.Cos(rotationy * 3.14159 / 180.0);
314 
315             M.e13 = (float)Math.Sin(rotationy * 3.14159 / 180.0);
316 
317             M.e31 = -(float)Math.Sin(rotationy * 3.14159 / 180.0);
318 
319             for (i = 0; i < 8; i )
320 
321                 tCube2[i] = M * tCube2[i];
322 
323  
324 
325             //平移x
326 
327             M.identity();
328 
329             M.e14 = translationx;
330 
331             M.e24 = -0.5f;
332 
333  
334 
335             for (i = 0; i < 8; i )
336 
337                 tCube2[i] = M * tCube2[i];
338 
339  
340 
341             //照相机变换
342 
343             M.identity();
344 
345             M.e14 = cx;
346 
347             M.e24 = cy;
348 
349             M.e34 = cz;
350 
351             for (i = 0; i < 8; i )
352 
353                 tCube2[i] = M * tCube2[i];
354 
355  
356 
357             M.identity();
358 
359             M.e11 = ux; M.e12 = uy; M.e13 = uz;
360 
361             M.e21 = vx; M.e22 = vy; M.e23 = vz;
362 
363             M.e31 = nx; M.e32 = ny; M.e33 = nz;
364 
365             for (i = 0; i < 8; i )
366 
367                 tCube2[i] = M * tCube2[i];
368 
369  
370 
371             //投影变换
372 
373             for (i = 0; i < 8; i )
374 
375             {
376 
377                 M.identity();
378 
379                 M.e11 = -zp / tCube2[i].z;
380 
381                 M.e22 = -zp / tCube2[i].z;
382 
383                 M.e33 = zp;
384 
385  
386 
387                 tCube2[i] = M * tCube2[i];
388 
389             }
390 
391             //视窗变换
392 
393             M.identity();
394 
395             M.e11 = (vxr - vxl) / (wxr - wxl);
396 
397             M.e22 = (vyt - vyb) / (wyt - wyb);
398 
399             M.e14 = vxl - (vxr - vxl) / (wxr - wxl) * wxl;
400 
401             M.e24 = vyb - (vyt - vyb) / (wyt - wyb) * wyb;
402 
403             for (i = 0; i < 8; i )
404 
405                 tCube2[i] = M * tCube2[i];
406 
407  
408 
409             //绘图
410 
411             g.Clear(Color.White);
412 
413  
414 
415             g.DrawLine(Pens.Red, tCube1[0].x, tCube1[0].y, tCube1[1].x, tCube1[1].y);
416 
417             g.DrawLine(Pens.Red, tCube1[1].x, tCube1[1].y, tCube1[2].x, tCube1[2].y);
418 
419             g.DrawLine(Pens.Red, tCube1[2].x, tCube1[2].y, tCube1[3].x, tCube1[3].y);
420 
421             g.DrawLine(Pens.Red, tCube1[3].x, tCube1[3].y, tCube1[0].x, tCube1[0].y);
422 
423  
424 
425             g.DrawLine(Pens.Red, tCube1[4].x, tCube1[4].y, tCube1[5].x, tCube1[5].y);
426 
427             g.DrawLine(Pens.Red, tCube1[5].x, tCube1[5].y, tCube1[6].x, tCube1[6].y);
428 
429             g.DrawLine(Pens.Red, tCube1[6].x, tCube1[6].y, tCube1[7].x, tCube1[7].y);
430 
431             g.DrawLine(Pens.Red, tCube1[7].x, tCube1[7].y, tCube1[4].x, tCube1[4].y);
432 
433  
434 
435             g.DrawLine(Pens.Red, tCube1[0].x, tCube1[0].y, tCube1[4].x, tCube1[4].y);
436 
437             g.DrawLine(Pens.Red, tCube1[1].x, tCube1[1].y, tCube1[5].x, tCube1[5].y);
438 
439             g.DrawLine(Pens.Red, tCube1[2].x, tCube1[2].y, tCube1[6].x, tCube1[6].y);
440 
441             g.DrawLine(Pens.Red, tCube1[3].x, tCube1[3].y, tCube1[7].x, tCube1[7].y);
442 
443  
444 
445             g.DrawLine(Pens.Blue, tCube2[0].x, tCube2[0].y, tCube2[1].x, tCube2[1].y);
446 
447             g.DrawLine(Pens.Blue, tCube2[1].x, tCube2[1].y, tCube2[2].x, tCube2[2].y);
448 
449             g.DrawLine(Pens.Blue, tCube2[2].x, tCube2[2].y, tCube2[3].x, tCube2[3].y);
450 
451             g.DrawLine(Pens.Blue, tCube2[3].x, tCube2[3].y, tCube2[0].x, tCube2[0].y);
452 
453  
454 
455             g.DrawLine(Pens.Blue, tCube2[4].x, tCube2[4].y, tCube2[5].x, tCube2[5].y);
456 
457             g.DrawLine(Pens.Blue, tCube2[5].x, tCube2[5].y, tCube2[6].x, tCube2[6].y);
458 
459             g.DrawLine(Pens.Blue, tCube2[6].x, tCube2[6].y, tCube2[7].x, tCube2[7].y);
460 
461             g.DrawLine(Pens.Blue, tCube2[7].x, tCube2[7].y, tCube2[4].x, tCube2[4].y);
462 
463  
464 
465             g.DrawLine(Pens.Blue, tCube2[0].x, tCube2[0].y, tCube2[4].x, tCube2[4].y);
466 
467             g.DrawLine(Pens.Blue, tCube2[1].x, tCube2[1].y, tCube2[5].x, tCube2[5].y);
468 
469             g.DrawLine(Pens.Blue, tCube2[2].x, tCube2[2].y, tCube2[6].x, tCube2[6].y);
470 
471             g.DrawLine(Pens.Blue, tCube2[3].x, tCube2[3].y, tCube2[7].x, tCube2[7].y);
472 
473  
474 
475         }
476 
477  
478 
479         private void Form1_MouseClick(object sender, MouseEventArgs e)
480 
481         {
482 
483             switch (flag)
484 
485             {
486 
487                 case 0:
488 
489                     this.timer1.Enabled = false;
490 
491                     flag = 1;
492 
493                     break;
494 
495                 case 1:
496 
497                     this.timer1.Enabled = true;
498 
499                     flag = 0;
500 
501                     break;
502 
503             }
504 
505         }
506 
507  
508 
509         private void Form1_Paint(object sender, PaintEventArgs e)
510 
511         {
512 
513  
514 
515         }
516 
517  
518 
519     }
520 
521  
522 
523     /////////////////////////  数学类 Vecto3
524 
525     public class Vector4
526 
527     {
528 
529         public static float pi = 3.14159265f;
530 
531         public static float tol = 0.000000000000001f;  // float type tolerance 
532 
533  
534 
535         public float x;
536 
537         public float y;
538 
539         public float z;
540 
541         public float w;
542 
543  
544 
545         public Vector4()
546 
547         {
548 
549             x = 0; y = 0; z = 0; w = 1;
550 
551         }
552 
553  
554 
555         public Vector4(float xi, float yi, float zi, float wi)
556 
557         {
558 
559             x = xi;
560 
561             y = yi;
562 
563             z = zi;
564 
565             w = wi;
566 
567         }
568 
569  
570 
571         public float Magnitude()
572 
573         {
574 
575             return (float)Math.Sqrt(x * x   y * y   z * z);
576 
577         }
578 
579         public void Normalize()
580 
581         {
582 
583             if (w != 1)
584 
585             {
586 
587                 x /= w;
588 
589                 y /= w;
590 
591                 z /= w;
592 
593                 w = 1;
594 
595             }
596 
597         }
598 
599  
600 
601     }
602 
603     ////////////////// 矩阵类
604 
605     public class Matrix4x4
606 
607     {
608 
609         // elements eij: i -> row, j -> column
610 
611         public float e11, e12, e13, e14, e21, e22, e23, e24, e31, e32, e33, e34, e41, e42, e43, e44;
612 
613  
614 
615         public Matrix4x4()
616 
617         {
618 
619             e11 = 1; e12 = 0; e13 = 0; e14 = 0;
620 
621             e21 = 0; e22 = 1; e23 = 0; e24 = 0;
622 
623             e31 = 0; e32 = 0; e33 = 1; e34 = 0;
624 
625             e41 = 0; e42 = 0; e43 = 0; e44 = 1;
626 
627         }
628 
629         public Matrix4x4(float r1c1, float r1c2, float r1c3, float r1c4,
630 
631                     float r2c1, float r2c2, float r2c3, float r2c4,
632 
633                     float r3c1, float r3c2, float r3c3, float r3c4,
634 
635                     float r4c1, float r4c2, float r4c3, float r4c4)
636 
637         {
638 
639             e11 = r1c1; e12 = r1c2; e13 = r1c3; e14 = r1c4;
640 
641             e21 = r2c1; e22 = r2c2; e23 = r2c3; e24 = r2c4;
642 
643             e31 = r3c1; e32 = r3c2; e33 = r3c3; e34 = r3c4;
644 
645             e41 = r4c1; e42 = r4c2; e43 = r4c3; e44 = r4c4;
646 
647         }
648 
649         public void identity()
650 
651         {
652 
653             e11 = 1; e12 = 0; e13 = 0; e14 = 0;
654 
655             e21 = 0; e22 = 1; e23 = 0; e24 = 0;
656 
657             e31 = 0; e32 = 0; e33 = 1; e34 = 0;
658 
659             e41 = 0; e42 = 0; e43 = 0; e44 = 1;
660 
661         }
662 
663         public Matrix4x4 Transpose()
664 
665         {
666 
667             return new Matrix4x4(e11, e21, e31, e41, e12, e22, e32, e42, e13, e23, e33, e43, e41, e42, e43, e44);
668 
669         }
670 
671  
672 
673         public static Matrix4x4 operator *(Matrix4x4 m1, Matrix4x4 m2)
674 
675         {
676 
677             return new Matrix4x4(m1.e11 * m2.e11   m1.e12 * m2.e21   m1.e13 * m2.e31   m1.e14 * m2.e41,
678 
679                                  m1.e11 * m2.e12   m1.e12 * m2.e22   m1.e13 * m2.e32   m1.e14 * m2.e42,
680 
681                                  m1.e11 * m2.e13   m1.e12 * m2.e23   m1.e13 * m2.e33   m1.e14 * m2.e43,
682 
683                                  m1.e11 * m2.e14   m1.e12 * m2.e24   m1.e13 * m2.e34   m1.e14 * m2.e44,
684 
685  
686 
687                                  m1.e21 * m2.e11   m1.e22 * m2.e21   m1.e23 * m2.e31   m1.e24 * m2.e41,
688 
689                                  m1.e21 * m2.e12   m1.e22 * m2.e22   m1.e23 * m2.e32   m1.e24 * m2.e42,
690 
691                                  m1.e21 * m2.e13   m1.e22 * m2.e23   m1.e23 * m2.e33   m1.e24 * m2.e43,
692 
693                                  m1.e21 * m2.e14   m1.e22 * m2.e24   m1.e23 * m2.e34   m1.e24 * m2.e44,
694 
695  
696 
697                                  m1.e31 * m2.e11   m1.e32 * m2.e21   m1.e33 * m2.e31   m1.e34 * m2.e41,
698 
699                                  m1.e31 * m2.e12   m1.e32 * m2.e22   m1.e33 * m2.e32   m1.e34 * m2.e42,
700 
701                                  m1.e31 * m2.e13   m1.e32 * m2.e23   m1.e33 * m2.e33   m1.e34 * m2.e43,
702 
703                                  m1.e31 * m2.e14   m1.e32 * m2.e24   m1.e33 * m2.e34   m1.e34 * m2.e44,
704 
705  
706 
707                                  m1.e41 * m2.e11   m1.e42 * m2.e21   m1.e43 * m2.e31   m1.e44 * m2.e41,
708 
709                                  m1.e41 * m2.e12   m1.e42 * m2.e22   m1.e43 * m2.e32   m1.e44 * m2.e42,
710 
711                                  m1.e41 * m2.e13   m1.e42 * m2.e23   m1.e43 * m2.e33   m1.e44 * m2.e43,
712 
713                                  m1.e41 * m2.e14   m1.e42 * m2.e24   m1.e43 * m2.e34   m1.e44 * m2.e44
714 
715                                  );
716 
717         }
718 
719  
720 
721         public static Vector4 operator *(Matrix4x4 m, Vector4 u)
722 
723         {
724 
725             return new Vector4(m.e11 * u.x   m.e12 * u.y   m.e13 * u.z   m.e14 * u.w,
726 
727                                m.e21 * u.x   m.e22 * u.y   m.e23 * u.z   m.e24 * u.w,
728 
729                                m.e31 * u.x   m.e32 * u.y   m.e33 * u.z   m.e34 * u.w,
730 
731                                m.e41 * u.x   m.e42 * u.y   m.e43 * u.z   m.e44 * u.w);
732 
733         }
734 
735     }
736 
737 }
作者:Standby一生热爱名山大川、草原沙漠,还有妹子
出处:http://www.cnblogs.com/standby/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文地址:https://www.cnblogs.com/standby/p/4150147.html