home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / msdos / utils / graphtal.lzh / Graphtal.Amiga / Triangle.C < prev    next >
C/C++ Source or Header  |  1992-11-19  |  3KB  |  129 lines

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