home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / s / sndppr3w.zip / NORMAL.C < prev    next >
C/C++ Source or Header  |  1991-04-26  |  3KB  |  120 lines

  1. /* Normal.C
  2. ** 4/26/91
  3. ** mjs
  4. */
  5.  
  6. #include "sp.h"
  7.  
  8. /* Define these to reduce visual clutter    */
  9. #define X1 (t->p1->x)
  10. #define Y1 (t->p1->y)
  11. #define Z1 (t->p1->z)
  12. #define X2 (t->p2->x)
  13. #define Y2 (t->p2->y)
  14. #define Z2 (t->p2->z)
  15. #define X3 (t->p3->x)
  16. #define Y3 (t->p3->y)
  17. #define Z3 (t->p3->z)
  18.  
  19. /* Prototypes for local functions    */
  20. PROTO static void clear_sum(void);
  21. PROTO static void sum(Triangle *);
  22. PROTO static void avg_sum(Point *);
  23. PROTO static void sum_clist(CList *);
  24.  
  25. static real sum_x, sum_y, sum_z;    /* normal accumulators        */
  26. static int count;            /* count of all triangles...    */
  27.                     /*  that contain this point    */
  28.  
  29. /************************************************************************/
  30. /* From _Computer Graphics_, by Hearn & Baker, page 192
  31. ** "The equation for a plane surface can be expressed in the form:
  32. **
  33. **        Ax + By + Cz + D = 0
  34. **
  35. ** where (x,y,z) is any point on the plane.  The coefficients A,B,C,D are
  36. ** constants that can be calculated using values of three noncollinear points
  37. ** in the plane.  Typically, we use the coordinates of three successive vertices
  38. ** on a polygon boundary to find values for these cooefficients.
  39. **
  40. **   A =  y1(z2-z3)     + y2(z3-z1)     + y3(z1-z2)
  41. **   B =  z1(x2-x3)     + z2(x3-x1)     + z3(x1-x2)
  42. **   C =  x1(y2-y3)     + x2(y3-y1)     + x3(y1-y2)
  43. **   D = -x1(y2z3-y3z2) - x2(y3z1-y1z3) - x3(y1z2-y2z1)
  44. ** 
  45. ** "The vector N, normal to the surface of a plance described by the equation 
  46. ** Ax + By + Cz + D = 0, has Cartesian coordinates (A,B,C)"
  47. */
  48.  
  49. void calc_tri_normal(Triangle *t)
  50. {
  51.     if(debug) {
  52.         printf("1: %7.4f %7.4f %7.4f\n",X1,Y1,Z1);
  53.         printf("2: %7.4f %7.4f %7.4f\n",X2,Y2,Z2);
  54.         printf("3: %7.4f %7.4f %7.4f\n",X3,Y3,Z3);
  55.     }
  56.  
  57.     t->eq_a = Y1*(Z2-Z3) + Y2*(Z3-Z1) + Y3*(Z1-Z2);
  58.     t->eq_b = Z1*(X2-X3) + Z2*(X3-X1) + Z3*(X1-X2);
  59.     t->eq_c = X1*(Y2-Y3) + X2*(Y3-Y1) + X3*(Y1-Y2);
  60.  
  61.     if(debug) {
  62.         printf("%7.4f %7.4f %7.4f\n",t->eq_a,t->eq_b,t->eq_c);
  63.     }
  64.  
  65.     /* The D value not needed for our surface normal calc's, but
  66.     ** included here since it can be useful (for other programs)
  67.     ** for determining whether a point is on the "inside" or
  68.     ** "outside" of a plane.
  69.     */
  70. /*    t->pD = -X1*(Y2*Z3-Y3*Z2) - X2*(Y3*Z1-Y1*Z3) - X3*(Y1*Z2-Y2*Z1);*/
  71. }
  72.  
  73.  
  74. /************************************************************************/
  75. void calc_pt_normals()
  76. {
  77.     Point *p;
  78.  
  79.     p = p_root;
  80.     while(p != NULL) {
  81.         clear_sum();        /* clear accumulator        */
  82.         sum_clist(p->cl);    /* sum normals of all...    */
  83.                     /* "containing" triangles    */
  84.         avg_sum(p);        /* average and store pt normals    */
  85.         p = p->next;        /* step to next point in list    */
  86.     }
  87. }
  88.  
  89. void sum_clist(CList *cl)
  90. {
  91.     while(cl != NULL) {
  92.         sum(cl->tri);        /* add this tri's normals to sum*/
  93.         cl = cl->next;        /* step to next tri in list    */
  94.     }
  95. }
  96.  
  97. /************************************************************************/
  98. void clear_sum()
  99. {
  100.     sum_x = sum_y = sum_z = (real)0.0;
  101.     count = 0;
  102. }
  103.  
  104. void sum(Triangle *t)
  105. {
  106.     sum_x += t->eq_a;
  107.     sum_y += t->eq_b;
  108.     sum_z += t->eq_c;
  109.     count++;
  110. }
  111.  
  112. void avg_sum(Point *p)
  113. {
  114.     p->nx = sum_x / (real)count;
  115.     p->ny = sum_y / (real)count;
  116.     p->nz = sum_z / (real)count;
  117. }
  118.  
  119. /*** eof ****************************************************************/
  120.