home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics 16,000
/
graphics-16000.iso
/
msdos
/
utils
/
graphtal.lzh
/
Graphtal.Amiga
/
Triangle.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-19
|
3KB
|
129 lines
/*
* Triangle.C - methods for triangle manipulations.
*
* Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
* University of Berne, Switzerland
* Copyright (C) 1989, 1991, Craig E. Kolb
* All rights reserved.
*
* This software may be freely copied, modified, and redistributed
* provided that this copyright notice is preserved on all copies.
*
* You may not distribute this software, in whole or in part, as part of
* any commercial product without the express consent of the authors.
*
* There is no warranty or other guarantee of fitness of this software
* for any purpose. It is provided solely "as is".
*
*/
#include "Triangle.h"
//___________________________________________________________ Triangle
Triangle::Triangle(const Vector& p1, const Vector& p2, const Vector& p3)
: v1(p1), v2(p2), v3(p3)
{
e1 = v2 - v1; // create edges
e2 = v3 - v1;
/*
* calculate triangle normal
*/
Vector nNotNormalized = n = e1*e2;
D = v1^n;
/*
* find dominant part of normal vector
*/
real absNx = fabs(nNotNormalized[0]);
real absNy = fabs(nNotNormalized[1]);
real absNz = fabs(nNotNormalized[2]);
real scale;
if (absNx > absNy && absNx > absNz) {
index1 = 1;
index2 = 2;
scale = 1/nNotNormalized[0];
}
else if (absNy > absNz) {
index1 = 2;
index2 = 0;
scale = 1/nNotNormalized[1];
}
else {
index1 = 0;
index2 = 1;
scale = 1/nNotNormalized[2];
}
e1 *= scale;
e2 *= scale;
}
GeoObject* Triangle::create(const Vector& p1, const Vector& p2, const Vector& p3)
{
if (equal(((p2-p1)*(p3-p1)).sqr(), 0))
return NULL;
return new Triangle(p1, p2, p3);
}
/*
* Compute the intersection between a ray and a triangle using barycentric
* coordinates. The original algorithm was discribed by John M. Snyder and
* Alan H. Barr in Computer Graphics (SIGGRAPH 87), pp. 119-126. This
* algorithm is a optimized version adapted from Craig Kolbs rayshade.
*/
int Triangle::intersect(const Ray& ray, real minDist, real& maxDist)
{
intersectionTests++;
/*
* calculate ray/plane intersection
*/
real t = n^ray.getDir();
if (fabs(t) < minDist)
return FALSE;
t = (D - (ray.getOrig()^n))/t;
if (t < minDist || t > maxDist)
return FALSE;
real h1 = ray.getOrig()[index1] + t*ray.getDir()[index1];
real h2 = ray.getOrig()[index2] + t*ray.getDir()[index2];
real g = e1[index1]*(h2 - v1[index2]) - e1[index2]*(h1 - v1[index1]);
if (g < 0 || g > 1)
return FALSE;
real b = e2[index2]*(h1 - v1[index1]) - e2[index1]*(h2 - v1[index2]);
if (b < 0 || b > 1)
return FALSE;
if (b+g > 1 )
return FALSE;
maxDist = t;
intersections++;
return TRUE;
}
Vector Triangle::normal(const Vector&) const
{
return n;
}
PolygonList* Triangle::tesselate(const BoundingBox&)
{
Polygon* p = new Polygon(v1, v2, v3);
p->transform(*trans);
PolygonList* polys = new PolygonList(1);
polys->append(p);
return polys;
}