home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / graphtal / triangle.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-22  |  2.8 KB  |  127 lines

  1. /*
  2.  * Triangle.C - methods for triangle manipulations.
  3.  *
  4.  * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
  5.  * All rights reserved.
  6.  *
  7.  * This software may be freely copied, modified, and redistributed
  8.  * provided that this copyright notice is preserved on all copies.
  9.  *
  10.  * You may not distribute this software, in whole or in part, as part of
  11.  * any commercial product without the express consent of the authors.
  12.  *
  13.  * There is no warranty or other guarantee of fitness of this software
  14.  * for any purpose.  It is provided solely "as is".
  15.  *
  16.  */
  17.  
  18. #include "Triangle.h"
  19.  
  20. //___________________________________________________________ Triangle
  21.  
  22. Triangle::Triangle(const Vector& p1, const Vector& p2, const Vector& p3)
  23. : v1(p1), v2(p2), v3(p3)
  24. {
  25.   e1 = v2 - v1;  // create edges
  26.   e2 = v3 - v1;
  27.  
  28.   /*
  29.    * calculate triangle normal
  30.    */
  31.   Vector nNotNormalized = n = e1*e2;
  32.  
  33.   D = v1^n;
  34.  
  35.   /*
  36.    *  find dominant part of normal vector
  37.    */
  38.   real absNx = fabs(nNotNormalized[0]);
  39.   real absNy = fabs(nNotNormalized[1]);
  40.   real absNz = fabs(nNotNormalized[2]);
  41.   real scale;
  42.   
  43.   if (absNx > absNy && absNx > absNz) {
  44.     index1 = 1;
  45.     index2 = 2;
  46.     scale = 1/nNotNormalized[0];
  47.   }
  48.   else if (absNy > absNz) {
  49.     index1 = 2;
  50.     index2 = 0;
  51.     scale = 1/nNotNormalized[1];
  52.   }
  53.   else {
  54.     index1 = 0;
  55.     index2 = 1;
  56.     scale = 1/nNotNormalized[2];
  57.   }
  58.  
  59.   e1 *= scale;
  60.   e2 *= scale;
  61. }
  62.  
  63. GeoObject* Triangle::create(const Vector& p1, const Vector& p2, const Vector& p3)
  64. {
  65.   if (equal(((p2-p1)*(p3-p1)).sqr(), 0))
  66.     return NULL;
  67.     
  68.   return new Triangle(p1, p2, p3);
  69. }
  70.  
  71. /*
  72.  * Compute the intersection between a ray and a triangle using barycentric
  73.  * coordinates. The original algorithm was discribed by John M. Snyder and 
  74.  * Alan H. Barr in Computer Graphics (SIGGRAPH 87), pp. 119-126. This 
  75.  * algorithm is a optimized version adapted from Craig Colbs rayshade.
  76.  */
  77.  
  78. int Triangle::intersect(const Ray& ray, real minDist, real& maxDist)
  79. {
  80.   intersectionTests++;
  81.  
  82.   /*
  83.    * calculate ray/plane intersection
  84.    */
  85.   real t = n^ray.getDir();
  86.   if (fabs(t) < minDist)
  87.     return FALSE;
  88.  
  89.   t = (D - (ray.getOrig()^n))/t;
  90.  
  91.   if (t < minDist || t > maxDist)
  92.    return FALSE;
  93.  
  94.   real h1 = ray.getOrig()[index1] + t*ray.getDir()[index1];
  95.   real h2 = ray.getOrig()[index2] + t*ray.getDir()[index2];
  96.  
  97.   real g = e1[index1]*(h2 - v1[index2]) - e1[index2]*(h1 - v1[index1]);
  98.   if (g < 0 || g > 1)
  99.     return FALSE;
  100.  
  101.   real b = e2[index2]*(h1 - v1[index1]) - e2[index1]*(h2 - v1[index2]);
  102.   if (b < 0 || b > 1)
  103.     return FALSE;
  104.  
  105.   if (b+g > 1 )
  106.     return FALSE;
  107.  
  108.   maxDist = t;
  109.   intersections++;
  110.   return TRUE;
  111. }
  112.  
  113. Vector Triangle::normal(const Vector&) const
  114. {
  115.   return n;
  116. }
  117.  
  118. PolygonList* Triangle::tesselate(const BoundingBox&)
  119. {
  120.   Polygon* p = new Polygon(v1, v2, v3);
  121.   p->transform(*trans);
  122.   PolygonList* polys = new PolygonList(1);
  123.   polys->append(p);
  124.  
  125.   return polys;
  126. }
  127.