The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

Triangle

Triangles in 3D space

PhilipRBrenan@yahoo.com, 2004, Perl License

Synopsis

Example t/triangle.t

 #_ Triangle ___________________________________________________________
 # Test 3d triangles    
 # philiprbrenan@yahoo.com, 2004, Perl License    
 #______________________________________________________________________
 
 use Math::Zap::Vector;
 use Math::Zap::Vector2;
 use Math::Zap::Triangle;
 use Test::Simple tests=>25;
  
 $t = triangle
  (vector( 0,  0,  0), 
   vector( 0,  0,  4), 
   vector( 4,  0,  0),
  );
  
 $u = triangle
  (vector( 0,  0,  0), 
   vector( 0,  1,  4), 
   vector( 4,  1,  0),
  );
 
 $T = triangle
  (vector( 0,  1,  0), 
   vector( 0,  1,  1), 
   vector( 1,  1,  0),
  );
 
 $c = vector(1, 1, 1);
 
 #_ Triangle ___________________________________________________________
 # Distance to plane
 #______________________________________________________________________
 
 ok($t->distance($c)   == 1, 'Distance to plane');
 ok($T->distance($c)   == 0, 'Distance to plane');
 ok($t->distance(2*$c) == 2, 'Distance to plane');
 ok($t->distanceToPlaneAlongLine(vector(0,-1,0), vector(0,1,0)) == 1, 'Distance to plane towards a point');
 ok($T->distanceToPlaneAlongLine(vector(0,-1,0), vector(0,1,0)) == 2, 'Distance to plane towards a point');
 
 #_ Triangle ___________________________________________________________
 # Permute the points of a triangle
 #______________________________________________________________________
 
 ok($t->permute                   == $t, 'Permute 1');
 ok($t->permute->permute          == $t, 'Permute 2');
 ok($t->permute->permute->permute == $t, 'Permute 3');
 
 #_ Triangle ___________________________________________________________
 # Intersection of a line with a plane defined by a triangle
 #______________________________________________________________________
 
 #ok($t->intersection($c, vector(1,  -1,  1)) == vector(1, 0, 1), 'Intersection of line with plane');
 #ok($t->intersection($c, vector(-1, -1, -1)) == vector(0, 0, 0), 'Intersection of line with plane');
 
 #_ Triangle ___________________________________________________________
 # Test whether a point is in front or behind a plane relative to another
 # point
 #______________________________________________________________________
  
 ok($t->frontInBehind($c, vector(1,  0.5,  1)) == +1, 'Front');
 ok($t->frontInBehind($c, vector(1,    0,  1)) ==  0, 'In');
 ok($t->frontInBehind($c, vector(1, -0.5,  1)) == -1, 'Behind');
 
 #_ Triangle ___________________________________________________________
 # Parallel
 #______________________________________________________________________
  
 ok($t->parallel($T) == 1, 'Parallel');
 ok($t->parallel($u) == 0, 'Not Parallel');
 
 #_ Triangle ___________________________________________________________
 # Coplanar
 #______________________________________________________________________
  
 #ok($t->coplanar($t) == 1, 'Coplanar');
 #ok($t->coplanar($u) == 0, 'Not coplanar');
 #ok($t->coplanar($T) == 0, 'Not coplanar');
 
 #_ Triangle ___________________________________________________________
 # Project one triangle onto another
 #______________________________________________________________________
 
 $p = vector(0, 2, 0);
 $s = $t->project($T, $p);
 
 ok($s == triangle
  (vector(0,   0,   2),
   vector(0.5, 0,   2),
   vector(0,   0.5, 2),
  ), 'Projection of corner 3');
 
 #_ Triangle ___________________________________________________________
 # Convert space to plane coordinates and vice versa
 #______________________________________________________________________
 
 ok($t->convertSpaceToPlane(vector(2, 2, 2))   == vector(0.5,0.5,2), 'Space to Plane');
 ok($t->convertPlaneToSpace(vector2(0.5, 0.5)) == vector(2, 0, 2),   'Plane to Space');
 
 #_ Triangle ___________________________________________________________
 # Divide 
 #______________________________________________________________________
 
 $it = triangle          # Intersects t
  (vector(  0, -1,  2), 
   vector(  0,  2,  2), 
   vector(  3,  2,  2),
  );
 
 @d = $t->divide($it);
 
 ok($d[0] == triangle(vector(0, -1, 2), vector(0, 0, 2), vector(1, 0, 2)));
 ok($d[1] == triangle(vector(0,  2, 2), vector(0, 0, 2), vector(1, 0, 2)));
 ok($d[2] == triangle(vector(0,  2, 2), vector(1, 0, 2), vector(3, 2, 2)));
 
 $it = triangle          # Intersects t
  (vector(  3,  2,  2),
   vector(  0,  2,  2), 
   vector(  0, -1,  2), 
  );
 
 @d = $t->divide($it);
 
 ok($d[0] == triangle(vector(0, -1, 2), vector(0, 0, 2), vector(1, 0, 2)));
 ok($d[1] == triangle(vector(3,  2, 2), vector(1, 0, 2), vector(0, 0, 2)));
 ok($d[2] == triangle(vector(3,  2, 2), vector(0, 0, 2), vector(0, 2, 2)));
 
 $it = triangle          # Intersects t
  (vector(  3,  2,  2),
   vector(  0, -1,  2), 
   vector(  0,  2,  2), 
  );
 
 @d = $t->divide($it);
 
 ok($d[0] == triangle(vector(0, -1, 2), vector(1, 0, 2), vector(0, 0, 2)));
 ok($d[1] == triangle(vector(3,  2, 2), vector(1, 0, 2), vector(0, 0, 2)));
 ok($d[2] == triangle(vector(3,  2, 2), vector(0, 0, 2), vector(0, 2, 2)));

Description

Triangles in 3D space

Definitions:

Space coordinates = 3d space

Plane coordinates = a triangle in 3d space defines a 2d plane with a natural coordinate system: the origin is the first point of the triangle, the (x,y) units of this plane are the sides from the triangles first point to its other points.

Constructors

new

Create a triangle from 3 vectors specifying the coordinates of each corner in space coordinates.

triangle

Create a triangle from 3 vectors specifying the coordinates of each corner in space coordinates - synonym for "new".

Methods

narrow

Narrow (colinear) triangle?

check

Check its a triangle

is

Test its a triangle

components

Components of a triangle

clone

Create a triangle from another triangle

permute

Cyclically permute the points of a triangle

center

Center

add

Add a vector to a triangle

subtract

Subtract a vector from a triangle

print

Print triangle

accuracy

# Get/Set accuracy for comparisons

distance

Shortest distance from plane defined by triangle t to point p

intersectionInPlane

Intersect line between two points with plane defined by triangle and return the intersection in plane coordinates. Identical logic as per intersection(). Note: no checks (yet) for line parallel to plane.

distanceToPlaneAlongLine

Distance to plane defined by triangle t going from a to b, or undef if the line is parallel to the plane

convertSpaceToPlane

Convert space to plane coordinates

convertPlaneToSpace

Convert splane to space coordinates

frontInBehind

Determine whether a test point b as viewed from a view point a is in front of(1), in(0), or behind(-1) a plane defined by a triangle t. Identical logic as per intersection(), except this time we use the z component to determine the relative position of the point b. Note: no checks (yet) for line parallel to plane.

frontInBehindZ

Determine whether a test point b as viewed from a view point a is in front of(1), in(0), or behind(-1) a plane defined by a triangle t. Identical logic as per intersection(), except this time we use the z component to determine the relative position of the point b. Note: no checks (yet) for line parallel to plane.

parallel

Are two triangle parallel? I.e. do they define planes that are parallel? If they are parallel, their normals will have zero cross product

divide

Divide triangle b by a: split b into triangles each of which is not intersected by a. Triangles are easy to draw in 3d except when they intersect: If they do not intersect, we can always draw one on top of the other and obtain the correct result; If they do intersect, they have to be split along the line of intersection into a sub triangle and a quadralateral: which can be be split again to obtain a result consisting of only triangles. The splitting can be done once: Each new view point only requires the correct ordering of the non intersecting triangles.

project

Project onto the plane defined by triangle t the image of a triangle triangle T as viewed from a view point p. Return the coordinates of the projection of T onto t using the plane coordinates induced by t. The projection coordinates are (of course) 2d in the projection plane, however they are returned as the x,y components of a 3d vector with the z component set to the multiple of the distance from the view point to the corresponding corner of T required to reach t. If z > 1, this corner of T is in front the plane of t, if z < 1 this corner of T is behind the plane of t. The logic is the same as intersection().

split

Split a triangle into 4 sub triangles unless the sub triangles would be too small

triangulate

Triangulate

equals

Compare two triangles for equality

Operators

Operator overloads

add

Add operator.

subtract

Subtract operator.

equals

Equals operator.

print

Print a triangle

Exports

Export "triangle"

Credits

Author

philiprbrenan@yahoo.com

philiprbrenan@yahoo.com, 2004

License

Perl License.