home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Snippets / NewRotation 1.0.2 / NewRotation.c < prev    next >
Encoding:
Text File  |  1995-12-01  |  12.2 KB  |  427 lines  |  [TEXT/CWIE]

  1. // NewRotation
  2. // version 1.0.2
  3. // by Ken Long <kenlong@netcom.com>
  4. // updated for CW7 on 951201
  5.  
  6. // ------------------------------------------------------------------- //
  7. // Another public domain C example source demo, brought back from      //
  8. // the dead at:  itty bitty bytes™ - by Kenneth A. Long!               //
  9. // Made to run in Think C™ on 2 June 1994.                             //
  10. // Uses no resource file - just add MacTraps and ANSI libraries.       //
  11. // The original of this file was found on ftp.cso.uiuc.edu in mac/MUG. //
  12. // ------------------------------------------------------------------- //
  13. // Update, 22 September 1994, to include Offscreen GWorld, key
  14. // controls and eliminate flicker.
  15. // kenlong@netcom.com
  16. // ------------------------------------------------------------------- //
  17.  
  18. #include <stdio.h>    
  19. #include <math.h>
  20. #include <qdoffscreen.h>
  21.  
  22. #define kLeft                0    
  23. #define kTop                0    
  24. #define kRight                qd.screenBits.bounds.right    
  25. #define kBottom                qd.screenBits.bounds.bottom   
  26. #define kNumberOfFaces        9
  27. #define kNumberOfVertices    9
  28. #define kNumberOfSets        20
  29. #define kSolid                1
  30. #define kSolidLight            0
  31. #define kWireFrame            2
  32.  
  33. #define X                    0    
  34. #define Y                    1
  35. #define Z                    2 
  36. #define LX                    80
  37. #define LY                    40
  38. #define LZ                    60    
  39.  
  40. short vertex [kNumberOfVertices] [3] = 
  41. {            
  42.     {            0,         0,       LZ / 2 }, 
  43.     {       LX / 2,         0,           LZ },     
  44.     {           LX,         0,       LZ / 2 }, 
  45.     {       LX / 2,         0,            0 }, 
  46.     {      LX / 2,        LY,       LZ / 4 },     
  47.     { 3 * LX / 4,        LY,       LZ / 2 },     
  48.     {      LX / 2,        LY, 3 * LZ / 4},     
  49.     {      LX / 4,        LY,       LZ / 2 }, 
  50.     {      LX / 2, -LY / 2,       LZ / 2 }
  51. };    
  52.  
  53. short  face [kNumberOfFaces] [5] = 
  54. {     
  55.     {0, 1, 6, 7, 0}, 
  56.     {1, 2, 5, 6, 1}, 
  57.     {2, 3, 4, 5, 2}, 
  58.     {7, 4, 3, 0, 7}, 
  59.     {7, 6, 5, 4, 7}, 
  60.     {0, 3, 8, 0}, 
  61.     {8, 1, 0, 8}, 
  62.     {8, 2, 1, 8}, 
  63.     {8, 3, 2, 8}
  64. };
  65.         
  66. short  xr = 200, yr = 160, zr = 0, dxo = 50, dyo = 30, dzo = -50;    
  67. PolyHandle  face_poly [kNumberOfSets] [kNumberOfFaces];
  68. short visible [kNumberOfSets] [kNumberOfFaces];    
  69. short light [kNumberOfSets] [kNumberOfFaces];    
  70. short drawflag;
  71.  
  72. Rect option_rect, display_rect;
  73.  
  74. WindowPtr    newWindow;                           
  75. Rect        windowBounds;
  76.  
  77. //• GWorld goodies.
  78. GWorldPtr        gOffscreenGWorld;    
  79. Rect            gOnscreenRect;    // The "projection screen" area in the window
  80. Rect            gOffscreenRect;
  81.  
  82. //• MBar hide/show stuff.
  83. RgnHandle        mBarRgn, GrayRgn;
  84. short            *mBarHeightPtr;
  85. short            oldMBarHeight;
  86.  
  87. GWorldPtr Create_A_GWorld (Rect *theRect);
  88. void New_Window (void);
  89. void main (void);
  90. void Compute_Rotation_Data (short axis);
  91. void Rotate_Object (void);
  92.  
  93. void HideMenuBar (void) 
  94. {
  95.     Rect    mBarRect;
  96.  
  97.     GrayRgn = GetGrayRgn ();
  98.     mBarHeightPtr = (short *)  0x0BAA;
  99.     oldMBarHeight = *mBarHeightPtr;
  100.     *mBarHeightPtr = 0;
  101.     mBarRect = qd.screenBits.bounds;
  102.     mBarRect.bottom = mBarRect.top + oldMBarHeight;
  103.     mBarRgn = NewRgn ();
  104.     RectRgn (mBarRgn, &mBarRect);
  105.     UnionRgn (GrayRgn, mBarRgn, GrayRgn);
  106.     PaintOne (0L, mBarRgn);
  107. }
  108.  
  109. void ShowMenuBar (void) 
  110. {
  111.     *mBarHeightPtr = oldMBarHeight;
  112.     DiffRgn (GrayRgn, mBarRgn, GrayRgn);
  113.     DisposeRgn (mBarRgn);
  114. }
  115.  
  116. GWorldPtr Create_A_GWorld (Rect *theRect)
  117. {
  118.     CGrafPtr    currentPort;
  119.     GDHandle    currentGDevice;
  120.     GWorldPtr   offScreen;
  121.     QDErr       result;
  122.  
  123.     GetGWorld (¤tPort, ¤tGDevice);
  124.     
  125.     if ((result = NewGWorld (&offScreen, 0, theRect, nil, nil, 0L)) != noErr)
  126.         if ((result = NewGWorld (&offScreen, 0, theRect, nil, nil, useTempMem)) != noErr)
  127.             return (nil);
  128.             
  129.     SetGWorld (offScreen, nil);
  130.  
  131.     ClipRect (&offScreen->portRect);    
  132.     
  133.     if (LockPixels (GetGWorldPixMap (offScreen)))
  134.     {
  135.         ForeColor (blackColor);
  136.         BackColor (whiteColor);
  137.         EraseRect (&offScreen->portRect);
  138.         UnlockPixels (GetGWorldPixMap (offScreen));
  139.     }
  140.  
  141.     SetGWorld (currentPort, currentGDevice);
  142.     return offScreen;
  143. }
  144.  
  145. void New_Window (void)
  146. {
  147.     SetRect (&windowBounds, kLeft, kTop, kRight, kBottom);
  148.     
  149.     newWindow = NewWindow (0L, &windowBounds, "\p3D Display", true, noGrowDocProc, (WindowPtr) - 1L, true, 0);
  150.     SetPort (newWindow);
  151.  
  152.     SetRect (&gOnscreenRect, kLeft, kTop + 20, kRight, kBottom + 20);
  153.     SetRect (&gOffscreenRect, kLeft, kTop + 20, kRight, kBottom + 20);
  154.  
  155.     gOffscreenGWorld = (GWorldPtr) Create_A_GWorld (&gOffscreenRect);
  156. }
  157.  
  158. void main ()                        
  159. {    
  160.     EventRecord the_event;
  161.     Point mousepoint;
  162.     GrafPtr the_port;
  163.     short i, j;
  164.     register short  this_set, next_set;
  165.     Rect temp_rect;
  166.     
  167.     InitGraf (&qd.thePort);     
  168.     InitFonts ();    
  169.     InitWindows ();    
  170.     InitCursor ();
  171.     
  172.     HideMenuBar ();
  173.     HideCursor ();
  174.     New_Window ();
  175.     
  176.     Compute_Rotation_Data (X);
  177.       drawflag = kSolidLight;
  178.     
  179.  
  180.     for (;;)
  181.     {    
  182.         GetNextEvent (everyEvent, &the_event);
  183.         if (the_event.what == keyDown)
  184.         {    
  185.             switch (the_event.message & charCodeMask)
  186.             {
  187.                 case 'Q':
  188.                 case 'q':
  189.                     ExitToShell ();
  190.                 break;
  191.  
  192.                 case 'x':
  193.                 case 'X':
  194.                     Compute_Rotation_Data (0);
  195.                 break;
  196.  
  197.                 case 'y':
  198.                 case 'Y':
  199.                     Compute_Rotation_Data (1);
  200.                 break;
  201.  
  202.                 case 'z':
  203.                 case 'Z':
  204.                     Compute_Rotation_Data (2);
  205.                 break;
  206.  
  207.                 case 'f':
  208.                 case 'F':
  209.                         if (++drawflag == 3)     
  210.                             drawflag = 0;
  211.                 break;
  212.             }
  213.         }
  214.         Rotate_Object ();
  215.     }
  216.     ShowCursor ();
  217.     ShowMenuBar ();
  218. }
  219.  
  220. void Compute_Rotation_Data (short axis)
  221. {
  222.     register short this_set, i, j;
  223.     short  basev [kNumberOfVertices] [3];
  224.     short v [kNumberOfVertices] [3];
  225.     short p_vx [kNumberOfVertices], p_vy [kNumberOfVertices];
  226.     short ax, ay, az, bx, by, bz;
  227.     
  228.     Rect count_rect;                
  229.     short v0, v1, v2;
  230.     float sin_table, cos_table; 
  231.     #define D_THETA  6.283185 / kNumberOfSets
  232.     
  233.     SetRect (&count_rect, 0, 21, 512, 342);    
  234.     EraseRect (&count_rect);
  235.     TextSize (18); 
  236.     TextFace (bold); 
  237.     TextFont (geneva); 
  238.     PenNormal ();
  239.     MoveTo (30, 50);    
  240.     DrawString ("\pComputation of Rotation Data");
  241.     MoveTo (30, 80);    
  242.     DrawString ("\pCounting Down...");
  243.         
  244.     for (i = 0; i < kNumberOfVertices; ++i)    
  245.     {    
  246.         basev [i] [X] = vertex [i] [X]  + dxo;    
  247.         basev [i] [Y] = vertex [i] [Y]  + dyo;    
  248.         basev [i] [Z] = vertex [i] [Z]    + dzo;
  249.     }
  250.     
  251.     for (this_set = 0; this_set < kNumberOfSets; ++this_set)    
  252.     { 
  253.         sin_table  =  sin (D_THETA * this_set);    
  254.         cos_table = cos (D_THETA * this_set);    
  255.         
  256.         for (i = 0; i < kNumberOfVertices; ++i)    
  257.         {    
  258.             switch (axis)    
  259.             {    
  260.                 case Z:    
  261.                     v [i] [X] = basev [i] [X] * 
  262.                               cos_table - basev [i] [Y] *
  263.                               sin_table;
  264.                               
  265.                     v [i] [Y] = basev [i] [X] *
  266.                               sin_table + basev [i] [Y] *
  267.                               cos_table;
  268.                               
  269.                     v [i] [Z] = basev [i] [Z];
  270.                 break;
  271.                 
  272.                 case Y:    
  273.                     v [i] [X] = basev [i] [X] * 
  274.                               cos_table + basev [i] [Z] * sin_table;
  275.                               
  276.                     v [i] [Y] = basev [i] [Y];
  277.                     v [i] [Z] = -basev [i] [X] * 
  278.                               sin_table + basev [i] [Z] * cos_table;
  279.                 break;
  280.                 
  281.                 case X:    
  282.                     v [i] [X] = basev [i] [X];
  283.                     v [i] [Y] = basev [i] [Y] * 
  284.                               sin_table +  basev [i] [Z] * cos_table;
  285.                     v [i] [Z] = -basev [i] [Y] * 
  286.                               cos_table +  basev [i] [Z] * sin_table;
  287.                     break;
  288.             }
  289.         }
  290.         for (i = 0; i < kNumberOfFaces; ++i)
  291.         {    
  292.             v0 = face [i] [0];        
  293.             v1 = face [i] [1];    
  294.             v2 = face [i] [2];    
  295.             ay = v [v2] [Y] -  v [v1] [Y];    
  296.             by = v [v0] [Y] -  v [v1] [Y];
  297.             az =  v [v2] [Z] -  v [v1] [Z];    
  298.             bz =  v [v0] [Z] -  v [v1] [Z];
  299.         
  300.             light [this_set] [i] = (ay * bz - az * by) > 0 ?0 :1;    
  301.         }        
  302.         for (i = 0; i < kNumberOfVertices; ++i)
  303.         {    
  304.             p_vx [i] = xr + .86603 * (v [i] [X] + v [i] [Z]);
  305.             p_vy [i] = yr +  v [i] [Y] + (v [i] [X] - v [i] [Z])/2;
  306.         }    
  307.         for (i = 0; i < kNumberOfFaces; ++i)
  308.         {    
  309.             v0 = face [i] [0];        
  310.             v1 = face [i] [1];    
  311.             v2 = face [i] [2];    
  312.             ax = p_vx [v2] -  p_vx [v1];    
  313.             bx = p_vx [v0] -  p_vx [v1];
  314.             ay = p_vy [v2] -  p_vy [v1];    
  315.             by = p_vy [v0] -  p_vy [v1];
  316.         
  317.             visible [this_set] [i] =     (ax * by - ay * bx) < 0 ?1 :0;
  318.         }
  319.         for (i = 0; i < kNumberOfFaces; ++i)
  320.         {    
  321.             face_poly [this_set] [i] = OpenPoly ();
  322.                 MoveTo (p_vx [face [i] [0]], p_vy [face [i] [0]] );
  323.                 for (j = 1; j < kNumberOfVertices; ++j)
  324.                 {    
  325.                     LineTo (p_vx [face [i] [j]], p_vy [face [i] [j]] );
  326.                     if (face [i] [j] == face [i] [0] )    
  327.                         break;
  328.                 }
  329.                 ClosePoly ();
  330.         }
  331.         SetRect (&count_rect, 200, 50, 250, 80);
  332.         EraseRect (&count_rect);
  333.         MoveTo (200, 80);
  334.         i = (kNumberOfSets-this_set); 
  335.         if (i > 99)    
  336.             DrawChar (48 + i / 100);    
  337.         else    
  338.             DrawChar (' '); 
  339.         
  340.         if (i > 99)  
  341.         { 
  342.             i %= 100;      
  343.             DrawChar (48 + i / 10);  
  344.             i %= 10 ;  
  345.         }    
  346.         else
  347.             {    
  348.                 if (i>9)    
  349.                 {
  350.                     DrawChar (48 + i / 10);    
  351.                     i %= 10;  
  352.                 } 
  353.                 else  
  354.                     DrawChar (' '); 
  355.         }    
  356.         DrawChar (48 + i);
  357.     }
  358.     Draw_Option_Bar ();
  359. }    
  360.  
  361. Draw_Option_Bar ()
  362. {
  363.     TextSize (12);    
  364.     SetRect (&option_rect, 0, 0, 20, 420);    
  365.     
  366.     MoveTo (5, 16);    
  367.     DrawString ("\p Q - Quits, X - 'X' axis, Y - 'Y' axis, Z - 'Z' axis and F is Frame.");
  368. }
  369.     
  370. void Rotate_Object ()
  371. {    
  372.     long                ticksNow;
  373.     GWorldPtr            windowGW;
  374.     GDHandle            windowGD;
  375.     PixMapHandle        thePixMap;
  376.  
  377.     register             short i;    
  378.     static short             set = 0;
  379.     register PolyHandle *poly;
  380.     
  381.     poly = &face_poly [set] [0];
  382.     
  383.     GetGWorld (&windowGW, &windowGD);     // Save whatever we had before
  384.  
  385.     SetGWorld (gOffscreenGWorld, nil);
  386.  
  387.     if (LockPixels (thePixMap = GetGWorldPixMap (gOffscreenGWorld)))
  388.     {
  389.         EraseRect (&gOffscreenGWorld->portRect);
  390.         if (drawflag == kSolidLight)  
  391.         {    
  392.             for (i=0;i<kNumberOfFaces;++i)    
  393.             {    
  394.                 if (visible [set] [i] ==1) 
  395.                 {    
  396.                     if (light [set] [i] ==1)     
  397.                         FillPoly (* (poly + i), &qd.ltGray);
  398.                         FramePoly (* (poly + i)); 
  399.                 }    
  400.             }
  401.         }
  402.         else 
  403.             if (drawflag == kSolid)  
  404.             {    
  405.                 for (i = 0; i < kNumberOfFaces; ++i)    
  406.                     if (visible [set] [i] ==1)    
  407.                         FramePoly (* (poly + i)); 
  408.             }
  409.             else     
  410.                 for (i = 0; i < kNumberOfFaces; ++i)    
  411.                     FramePoly (* (poly + i)); 
  412.         
  413.         if (++set == kNumberOfSets)    
  414.             set = 0;
  415.  
  416.         SetGWorld (windowGW, windowGD);
  417.  
  418.         CopyBits ((BitMap*) *thePixMap, 
  419.                 & ((GrafPtr) newWindow)->portBits, 
  420.                   &gOffscreenRect, 
  421.                   &gOnscreenRect, srcCopy, nil);
  422.         
  423.         UnlockPixels (thePixMap);
  424.     }
  425.     SetGWorld (windowGW, windowGD);
  426. }
  427.