home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c100 / 2.ddi / RAYTRACE.ZIP / RAYTRACE.CPP next >
Encoding:
C/C++ Source or Header  |  1990-08-15  |  4.6 KB  |  193 lines

  1. /* RAYTRACE.CPP */
  2.  
  3. #include <stdlib.h>
  4. #include <graphics.h>
  5. #include <math.h>
  6. #include <stdio.h>
  7. #include <conio.h>
  8.  
  9. #include "RAYTRACE.HPP"
  10.  
  11. #define    WIDTH        640
  12. #define    HEIGHT    350
  13.  
  14. inline void plot(int x,int y,int c)
  15. {
  16.     putpixel( x , (HEIGHT-1)-y , c );
  17. }
  18.  
  19. int PlanePattern( unsigned int x, unsigned int y, int light )
  20. {
  21.     /* Put code for different plane patterns in here */
  22.             return ((x + y) % 8 )+ 8 * light ;
  23. //            return (x % 8 ) ^ ( y % 8 ) + 8 * light ;
  24. //            return (( x * x + y * y ) & 8 ) + 8 * light ;
  25. }
  26.  
  27.  
  28. RAY::RAY(double x, double y, double z, double vx, double vy, double vz)
  29. {
  30.     this->ox = x ;
  31.     this->oy = y ;
  32.     this->oz = z ;
  33.     this->dx = vx ;
  34.     this->dy = vy ;
  35.     this->dz = vz ;
  36. }
  37.  
  38. SPHERE::SPHERE( double x, double y, double z, double r)
  39. {
  40.     this->cx = x ;
  41.     this->cy = y ;
  42.     this->cz = z ;
  43.     this->r2 = r*r ;
  44. }
  45.  
  46. double SPHERE::Intersect ( RAY ray )
  47. {
  48.     double a, b, c, t1, t2, t3, close, farther;
  49.     a = ray.dx * ray.dx + ray.dy * ray.dy + ray.dz * ray.dz ;
  50.     close = farther = -1 ;
  51.     if (a) {
  52.         b = 2.0 * ((ray.ox - this->cx) * ray.dx
  53.                     + (ray.oy - this->cy) * ray.dy
  54.                     + (ray.oz - this->cz) * ray.dz );
  55.         c =  (ray.ox - this->cx) * ( ray.ox - this->cx )
  56.             + (ray.oy - this->cy) * ( ray.oy - this->cy )
  57.             + (ray.oz - this->cz) * ( ray.oz - this->cz ) - this->r2 ;
  58.         t1 = b * b - 4.0 * a * c ;
  59.         if (t1>0){
  60.             t2 = sqrt(t1);
  61.             t3 = 2.0 * a ;
  62.             close = -( b + t2 ) / t3 ;
  63.             farther = -( b - t2 ) / t3 ;
  64.             }
  65.         }
  66.     return (double)((close < farther) ? close : farther);
  67. }
  68.  
  69. void SPHERE::Reflect(RAY iray, double time, RAY &rray)
  70. {
  71.     VECTOR normal;                        /*  Used for readability        */
  72.     double ndotn;                        /*  Used for readability        */
  73.     double idotn;                        /*  Used for readability        */
  74.     double idotn_div_ndotn_x2;        /*  Used for optimization        */
  75.  
  76.     rray.ox = iray.dx * time + iray.ox;        /* find the point of            */
  77.     rray.oy = iray.dy * time + iray.oy;        /* intersection between        */
  78.     rray.oz = iray.dz * time + iray.oz;        /* iray and sphere.            */
  79.  
  80.     normal.dx = rray.ox - this->cx;            /* find the ray normal        */
  81.     normal.dy = rray.oy - this->cy;            /* to the sphere at the        */
  82.     normal.dz = rray.oz - this->cz;            /* intersection                */
  83.  
  84.     ndotn = (normal.dx * normal.dx +
  85.                 normal.dy * normal.dy +
  86.                 normal.dz * normal.dz );
  87.     idotn = (normal.dx * iray.dx +
  88.                 normal.dy * iray.dy +
  89.                 normal.dz * iray.dz );
  90.     idotn_div_ndotn_x2 = ( 2.0 * (idotn) / ndotn );
  91.  
  92.     rray.dx = iray.dx - idotn_div_ndotn_x2 * normal.dx ;
  93.     rray.dy = iray.dy - idotn_div_ndotn_x2 * normal.dy ;
  94.     rray.dz = iray.dz - idotn_div_ndotn_x2 * normal.dz ;
  95. }
  96.  
  97. PLANE::PLANE(double x, double y, double z, double vx, double vy, double vz)
  98. {
  99.     this->nx = vx ;
  100.     this->ny = vy ;
  101.     this->nz = vz ;
  102.  
  103.     this->px = x ;
  104.     this->py = y ;
  105.     this->pz = z ;
  106. }
  107.  
  108. int PLANE::Pattern(RAY ray, double time, int light)
  109. {
  110.     return PlanePattern((unsigned)(time * ray.dz + ray.oz),
  111.                               (unsigned)(time * ray.dx + ray.ox ),light);
  112. }
  113.  
  114. double PLANE::Intersect(RAY ray)
  115. {
  116.     double p1, p2, p3;
  117.  
  118.     p1 = this->px * this->ny + this->py * this->ny + this->pz * this->nz ;
  119.     p2 = ray.ox * this->nx + ray.oy * this->ny + ray.oz * this->nz ;
  120.     p3 = ray.dx * this->nx + ray.dy * this->ny + ray.dz * this->nz ;
  121.     return (double)((p1-p2)/p3);
  122. }
  123.  
  124. int trace(double x, double y)
  125. {
  126.     static PLANE plane( -8.0 , 0.0 , 0.0 ,   0.0 , 1.0 , 0.001 );
  127.     static SPHERE sphere( 0.0 , 0.0 , 5.0 , 1.0 );
  128.     RAY ray(0.0,0.0,0.0,(x-(double)WIDTH / 2.0 ) * .75 ,
  129.         y - (double)HEIGHT / 2.0 , HEIGHT);
  130.     double time1 , time2 ;
  131.  
  132.     time1 = sphere.Intersect(ray);
  133.     time2 = plane.Intersect(ray);
  134.  
  135.     if (time1>0.0 && (time2 <0.0 || time2 > time1)){        /* Circle in fore */
  136.         sphere.Reflect(ray,time1,ray);
  137.         time2 = plane.Intersect(ray);
  138.         if (time2>0.0)
  139.             return plane.Pattern(ray,time2,0);
  140.         else
  141.             return 1 ;
  142.         }
  143.     else
  144.         if (time2 > 0.0)
  145.             return plane.Pattern(ray,time2,1);
  146.  
  147.     return 0;
  148. }
  149.  
  150. void draw()
  151. {
  152.     int x,y ;
  153.     for( x=0 ; x < WIDTH && !kbhit(); x++ )
  154.         for (y = 0 ; y < HEIGHT ; y ++ )
  155.             plot( x , y , trace((double)x,(double)y));
  156. }
  157.  
  158. void init_graphics()
  159. {
  160.     /* request auto detection */
  161.     int gdriver = DETECT, gmode, errorcode;
  162.  
  163.    /* initialize graphics mode */
  164.     initgraph(&gdriver, &gmode, "");
  165.  
  166.     /* read result of initialization */
  167.     errorcode = graphresult();
  168.  
  169.    if (errorcode != grOk)  /* an error occurred */
  170.    {
  171.       printf("Graphics error: %s\n", grapherrormsg(errorcode));
  172.       printf("Press any key to halt:");
  173.       getch();
  174.       exit(1);             /* return with error code */
  175.    }
  176.  
  177.     setgraphmode(EGAHI);
  178. }
  179.  
  180. void exit_graphics(){
  181.     closegraph();
  182. }
  183.  
  184. main()
  185. {
  186.     init_graphics();
  187.     draw();
  188.     getch();
  189.     exit_graphics();
  190. }
  191.  
  192.  
  193.