• 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/

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

  • 相关阅读:
    NoSQL数据库 continue posting...
    CAP 理论
    Clojure Web 开发 (一)
    HttpClient 4.0.x Tips
    zZ Java中String和Byte[]之间的那些事
    使用nhibernate出现Could not find the dialect in the configuration
    eclipse导入项目出现Project has no default.properties file! Edit the project properties to set one.
    今天开通此博~
    美国白蛾入侵北京 GIS兵法破解危局
    HTML5 存取Json
  • 原文地址:https://www.cnblogs.com/standby/p/4150147.html
Copyright © 2020-2023  润新知