home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / graphic / csg_rt / sphere.c < prev    next >
C/C++ Source or Header  |  1993-01-11  |  5KB  |  213 lines

  1. /*
  2.  
  3. SPHERE.C  Sphere logic
  4.               2      2      2  2
  5. Defined solid for :- (x-a) +(y-b) +(z-c) -d <=0
  6.  
  7. */
  8.  
  9. /*...sincludes:0:*/
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <stddef.h>
  13. #include <malloc.h>
  14. #include <memory.h>
  15. #include <math.h>
  16. #include "standard.h"
  17. #include "rt.h"
  18. #include "vector.h"
  19. #include "sil.h"
  20. #define    _SPHERE_
  21. #include "sphere.h"
  22.  
  23. /*...vrt\46\h:0:*/
  24. /*...vvector\46\h:0:*/
  25. /*...vsil\46\h:0:*/
  26. /*...vsphere\46\h:0:*/
  27. /*...e*/
  28.  
  29. /*...screate_sphere      \45\ create any general sphere:0:*/
  30. SPHERE    *create_sphere(double r)
  31.     {
  32.     SPHERE    *sphere;
  33.  
  34.     if ( (sphere = malloc(sizeof(SPHERE))) == NULL )
  35.         return ( NULL );
  36.  
  37.     sphere -> a = 0.0;
  38.     sphere -> b = 0.0;
  39.     sphere -> c = 0.0;
  40.     sphere -> d = r;
  41.     return ( sphere );
  42.     }
  43. /*...e*/
  44. /*...scopy_sphere        \45\ make a copy of a sphere:0:*/
  45. SPHERE    *copy_sphere(SPHERE *sphere)
  46.     {
  47.     SPHERE    *copy;
  48.  
  49.     if ( (copy = malloc(sizeof(SPHERE))) == NULL )
  50.         return ( NULL );
  51.  
  52.     memcpy(copy, sphere, sizeof(SPHERE));
  53.     return ( copy );
  54.     }
  55. /*...e*/
  56. /*...sdestroy_sphere     \45\ destroy a sphere:0:*/
  57. void    destroy_sphere(SPHERE *sphere)
  58.     {
  59.     free(sphere);
  60.     }
  61. /*...e*/
  62.  
  63. /*...strans_x_sphere     \45\ translate by amount in x direction:0:*/
  64. void    trans_x_sphere(SPHERE *sphere, double t)
  65.     {
  66.     sphere -> a += t;
  67.     }
  68. /*...e*/
  69. /*...strans_y_sphere     \45\ translate by amount in y direction:0:*/
  70. void    trans_y_sphere(SPHERE *sphere, double t)
  71.     {
  72.     sphere -> b += t;
  73.     }
  74. /*...e*/
  75. /*...strans_z_sphere     \45\ translate by amount in z direction:0:*/
  76. void    trans_z_sphere(SPHERE *sphere, double t)
  77.     {
  78.     sphere -> c += t;
  79.     }
  80. /*...e*/
  81. /*...sscale_sphere       \45\ scale a sphere equally in all directions:0:*/
  82. /*
  83. The idea is to make the sphere 'factor' times bigger.
  84. Just multiply d by the scale factor.
  85. */
  86.  
  87. void    scale_sphere(SPHERE *sphere, double factor)
  88.     {
  89.     sphere -> d *= factor;
  90.     }
  91. /*...e*/
  92. /*...srot_x_sphere       \45\ rotate about x axis by given angle:0:*/
  93. void    rot_x_sphere(SPHERE *sphere, double angle)
  94.     {
  95.     double    b  = sphere -> b;
  96.     double    c  = sphere -> c;
  97.     double    ca = cos(angle);
  98.     double    sa = sin(angle);
  99.  
  100.     sphere -> b = b * ca - c * sa;
  101.     sphere -> c = b * sa + c * ca;
  102.     }
  103. /*...e*/
  104. /*...srot_y_sphere       \45\ rotate about y axis by given angle:0:*/
  105. void    rot_y_sphere(SPHERE *sphere, double angle)
  106.     {
  107.     double    c  = sphere -> c;
  108.     double    a  = sphere -> a;
  109.     double    ca = cos(angle);
  110.     double    sa = sin(angle);
  111.  
  112.     sphere -> c = c * ca - a * sa;
  113.     sphere -> a = c * sa + a * ca;
  114.     }
  115. /*...e*/
  116. /*...srot_z_sphere       \45\ rotate about z axis by given angle:0:*/
  117. void    rot_z_sphere(SPHERE *sphere, double angle)
  118.     {
  119.     double    a  = sphere -> a;
  120.     double    b  = sphere -> b;
  121.     double    ca = cos(angle);
  122.     double    sa = sin(angle);
  123.  
  124.     sphere -> a = a * ca - b * sa;
  125.     sphere -> b = a * sa + b * ca;
  126.     }
  127. /*...e*/
  128.  
  129. /*...sisects_reqd_sphere \45\ max number of isects we will generate:0:*/
  130. int    isects_reqd_sphere(SPHERE *sphere)
  131.     {
  132.     sphere=sphere; /* Suppress 'unref arg' compiler warning */
  133.  
  134.     return ( 2 );
  135.     }
  136. /*...e*/
  137. /*...sintersect_sphere   \45\ determine intersection range of t:0:*/
  138. /*
  139.  
  140. Any point along the line we are interested in is of the form p + tq.
  141.                                  ~    ~
  142.          2      2      2  2
  143. Given:    (x-a) +(y-b) +(z-c) -d =0
  144.  
  145. Subs:    x = x +tx        y = y +ty        z = z +tz
  146.          p   q             p   q             p   q
  147.  
  148.       2  2  2  2                      2  2  2  2
  149. Gives:    (x +y +z )t - 2(ix +jy +kz )t + (i +j +k -d ) = 0
  150.       q  q  q         q   q   q
  151.  
  152. Where:    i = (a-x ), j = (b-y ), k = (c-z )
  153.             p           p           p
  154.  
  155. */
  156.  
  157. /*...svalue_of_sphere:0:*/
  158. static double value_of_sphere(void *shapeinfo, VECTOR v)
  159.     {
  160.     SPHERE    *sphere = (SPHERE *) shapeinfo;
  161.     double    i = v.x - sphere -> a;
  162.     double    j = v.y - sphere -> b;
  163.     double    k = v.z - sphere -> c;
  164.  
  165.     return ( i * i + j * j + k * k - sphere -> d * sphere -> d );
  166.     }
  167. /*...e*/
  168.  
  169. void    intersect_sphere(SPHERE *sphere, VECTOR p, VECTOR q, SIL *sil)
  170.     {
  171.     double    i  = sphere -> a - p.x;
  172.     double    j  = sphere -> b - p.y;
  173.     double    k  = sphere -> c - p.z;
  174.     double    qa = q.x * q.x + q.y * q.y + q.z * q.z;
  175.     double    xx = -(i * q.x + j * q.y + k * q.z);
  176.     double    qb = xx + xx;
  177.     double    qc = i * i + j * j + k * k - sphere -> d * sphere -> d;
  178.  
  179.     intersect_quadratic_t(qa, qb, qc, p, q,
  180.                   (void *) sphere, value_of_sphere, sil);
  181.     }
  182. /*...e*/
  183. /*...snormal_to_sphere   \45\ find normal of surface at a given point:0:*/
  184. /*
  185.  
  186. Use partial derivatives to find normal at a given point.
  187. We will ignore the multiple of 2 on all components, producing a half length,
  188. but correctly pointing vector, which is fair enough, as it will be normalised
  189. later anyhow.
  190.  
  191.          2      2      2  2
  192. Given:    (x-a) +(y-b) +(z-c) +d =0
  193.  
  194. d/dx:    2(x-a)
  195.  
  196. d/dy:    2(y-b)
  197.  
  198. d/dz:    2(z-c)
  199.  
  200. */
  201.  
  202. VECTOR    normal_to_sphere(SPHERE *sphere, VECTOR p)
  203.     {
  204.     VECTOR    normal;
  205.  
  206.     normal.x = p.x - sphere -> a;
  207.     normal.y = p.y - sphere -> b;
  208.     normal.z = p.z - sphere -> c;
  209.  
  210.     return ( normal );
  211.     }
  212. /*...e*/
  213.