Задача: Вращение 3D объекта
Исходник: Вращение 3D объекта, язык: C++ [code #126, hits: 11094]
автор: - [добавлен: 17.05.2006]
  1. #include <graphics.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <conio.h>
  5. #include <math.h>
  6. #include <dos.h>
  7. #define Pi 3.1415926536
  8. enum Action{move,draw};
  9. struct Point3D
  10. {
  11. float x;
  12. float y;
  13. float z;
  14. Action action;
  15. };
  16. // this function initializes graphics mode
  17. // it will work only if you're using Borland C++ compiler & BGI drivers
  18. // if you're using another compiler you should overwrite body of this function
  19. void init_gr(void)
  20. {
  21. /* request autodetection */
  22. int gdriver = DETECT, gmode, errorcode;
  23. /* initialize graphics mode */
  24. initgraph(&gdriver, &gmode, "");
  25. /* read result of initialization */
  26. errorcode = graphresult();
  27. if (errorcode != grOk) /* an error occurred */
  28. {
  29. printf("Graphics error: %s\n", grapherrormsg(errorcode));
  30. printf("Press any key to halt:");
  31. getch();
  32. exit(1); /* return with error code */
  33. }
  34. }
  35. // this function shuts graphics mode down
  36. // it will work only if you're using Borland C++ compiler & BGI drivers
  37. // if you're using another compiler you should overwrite body of this function
  38. void end_gr(void)
  39. {
  40. closegraph();
  41. }
  42. // this function moves CP to (x,y) position
  43. // it will work only if you're using Borland C++ compiler & BGI drivers
  44. // if you're using another compiler you should overwrite body of this function
  45. void MoveTo(int x, int y)
  46. {
  47. moveto(x,y);
  48. }
  49. // this function draws a line to (x,y) position
  50. // it will work only if you're using Borland C++ compiler & BGI drivers
  51. // if you're using another compiler you should overwrite body of this function
  52. void LineTo(int x, int y)
  53. {
  54. lineto(x,y);
  55. }
  56. void draw3Dobject(Point3D *object, int N, float rho, float theta,
  57. float phi, float dist_to_screen, int xshift, int yshift)
  58. {
  59. int x,y;
  60. float xe,ye,ze,costh,sinph,cosph,sinth,v11,v12,v13,v21,v22,v32,v33,v23,v43;
  61. // calculating coefficients
  62. costh=cos(theta);
  63. sinth=sin(theta);
  64. cosph=cos(phi);
  65. sinph=sin(phi);
  66. v11=-sinth; v12=-cosph*costh; v13=-sinph*costh;
  67. v21=costh; v22=-cosph*sinth; v23=-sinph*sinth;
  68. v32=sinph; v33=-cosph;
  69. v43=rho;
  70. for (int i=0;i<N;i++)
  71. {
  72. // calculating eye coordinates
  73. xe=v11*(object+i)->x+v21*(object+i)->y;
  74. ye=v12*(object+i)->x+v22*(object+i)->y+v32*(object+i)->z;
  75. ze=v13*(object+i)->x+v23*(object+i)->y+v33*(object+i)->z+v43;
  76. // calculating screen coordinates
  77. x=dist_to_screen*xe/ze+xshift;
  78. y=dist_to_screen*ye/ze+yshift;
  79.  
  80. // drawing
  81. if((object+i)->action==move)
  82. MoveTo(x,y);
  83. else
  84. LineTo(x,y);
  85. }
  86. }
  87. void RotateX(Point3D *object, int n, float angle)
  88. {
  89. float cosa,sina,y,z;
  90. cosa=cos(angle);
  91. sina=sin(angle);
  92. for(int i=0;i<n;i++)
  93. {
  94. y=(object+i)->y*cosa-(object+i)->z*sina;
  95. z=(object+i)->y*sina+(object+i)->z*cosa;
  96. (object+i)->y=y;
  97. (object+i)->z=z;
  98. }
  99. }
  100. void RotateY(Point3D *object, int n, float angle)
  101. {
  102. float cosa,sina,x,z;
  103. cosa=cos(angle);
  104. sina=sin(angle);
  105. for(int i=0;i<n;i++)
  106. {
  107. x=(object+i)->x*cosa+(object+i)->z*sina;
  108. z=-(object+i)->x*sina+(object+i)->z*cosa;
  109. (object+i)->x=x;
  110. (object+i)->z=z;
  111. }
  112. }
  113. void RotateZ(Point3D *object, int n, float angle)
  114. {
  115. float cosa,sina,x,y;
  116. cosa=cos(angle);
  117. sina=sin(angle);
  118. for(int i=0;i<n;i++)
  119. {
  120. x=(object+i)->x*cosa-(object+i)->y*sina;
  121. y=(object+i)->x*sina+(object+i)->y*cosa;
  122. (object+i)->x=x;
  123. (object+i)->y=y;
  124. }
  125. }
  126. int main(void)
  127. {
  128. Point3D thetr[]={{100,100,100,move},
  129. {100,200,100,draw},
  130. {200,100,100,draw},
  131. {100,100,100,draw},
  132. {100,100,200,draw},
  133. {200,100,100,draw},
  134. {100,100,200,move},
  135. {100,200,100,draw}};
  136. Point3D cube[]={{-50,-50,-50,move},
  137. {-50,50,-50,draw},
  138. {-50,50,50,draw},
  139. {50,50,50,draw},
  140. {50,50,-50,draw},
  141. {50,-50,-50,draw},
  142. {50,-50,50,draw},
  143. {-50,-50,50,draw},
  144. {-50,50,50,draw},
  145. {-50,-50,50,move},
  146. {-50,-50,-50,draw},
  147. {50,-50,-50,draw},
  148. {50,50,-50,move},
  149. {-50,50,-50,draw},
  150. {50,-50,50,move},
  151. {50,50,50,draw}};
  152. int N=sizeof(thetr)/sizeof(Point3D);
  153. int M=sizeof(cube)/sizeof(Point3D);
  154. float rho=1500,theta=Pi/4,phi=-3*Pi/4,dist_to_screen=700;
  155. int xshift=300, yshift=150,xshift1=200,yshift1=200;
  156. // initializing graphics mode
  157. init_gr();
  158. /* examples */
  159. while (!kbhit())
  160. {
  161. RotateX(cube,M,Pi/24);
  162. RotateY(cube,M,Pi/24);
  163. RotateZ(cube,M,Pi/24);
  164. RotateY(thetr,N,Pi/30);
  165. setcolor(12);
  166. draw3Dobject(thetr,N,rho,theta,phi,dist_to_screen,xshift,yshift);
  167. draw3Dobject(cube,M,rho,theta,phi,dist_to_screen,xshift1,yshift1);
  168. setcolor(0);
  169. delay(35);
  170. draw3Dobject(thetr,N,rho,theta,phi,dist_to_screen,xshift,yshift);
  171. draw3Dobject(cube,M,rho,theta,phi,dist_to_screen,xshift1,yshift1);
  172. }
  173. /* clean up */
  174. getch();
  175. end_gr();
  176. return 0;
  177. }
//////////////////////////////////////////////////////////////////////////////
//
// Rotating 3D object
// (c) Johna Smith, 1996
//
// Method description:
// Given: vector X, angle a
// To rotate this vector about axe X we should apply the following
// operation: X'=X*Rx, where Rx - is matrix of rotation
// [ 1 0 0 0 ]
// [ 0 cos a sin a 0 ]
// Rx=[ 0 -sin a cos a 0 ]
// [ 0 0 0 1 ]
// Applying this operation to every point of the given object we
// rotate it.
//
//////////////////////////////////////////////////////////////////////////////

+добавить реализацию