core/vgl/vgl_triangle_3d.h
Go to the documentation of this file.
00001 #ifndef VGL_TRIANGLE_3D_H_
00002 #define VGL_TRIANGLE_3D_H_
00003 //:
00004 // \file
00005 // \brief Some helpful functions when working with triangles
00006 // \author Kieran O'Mahony
00007 // \date 21 June 2007
00008 
00009 #include <vcl_algorithm.h>
00010 #include <vcl_utility.h>
00011 #include <vcl_cmath.h>
00012 
00013 #include <vgl/vgl_line_segment_3d.h>
00014 #include <vgl/vgl_point_3d.h>
00015 
00016 enum vgl_triangle_3d_intersection_t
00017 {
00018   None=0,
00019   Skew,
00020   Coplanar
00021 };
00022 
00023 //: Check for coincident edges of triangles a and b
00024 //  \return a vector of the coincident edges
00025 vcl_vector<vcl_pair<unsigned,unsigned> > vgl_triangle_3d_coincident_edges(
00026   const vgl_point_3d<double>& a_p1,
00027   const vgl_point_3d<double>& a_p2,
00028   const vgl_point_3d<double>& a_p3,
00029   const vgl_point_3d<double>& b_p1,
00030   const vgl_point_3d<double>& b_p2,
00031   const vgl_point_3d<double>& b_p3);
00032 
00033 //: Check if the given point is inside the triangle
00034 //  The triangle is represented by its vertices \a p1, \a p2, \a p3
00035 //  \return true if point is inside
00036 bool vgl_triangle_3d_test_inside(
00037   const vgl_point_3d<double>& i_pnt,
00038   const vgl_point_3d<double>& p1,
00039   const vgl_point_3d<double>& p2,
00040   const vgl_point_3d<double>& p3);
00041 
00042 //: Check if the given point is inside the triangle
00043 //  The triangle is represented by its vertices \a p1, \a p2, \a p3
00044 //  \return true if point is inside
00045 //  \param coplanar_tolerance is used to dismiss points because they are
00046 //    outside the plane. This doesn't widen the triangle, just thickens it.
00047 bool vgl_triangle_3d_test_inside(const vgl_point_3d<double>& i_pnt,
00048                                  const vgl_point_3d<double>& p1,
00049                                  const vgl_point_3d<double>& p2,
00050                                  const vgl_point_3d<double>& p3,
00051                                  double coplanar_tolerance );
00052 
00053 //: Check if point \a i_pnt is inside the triangle
00054 //  The triangle is represented by its vertices \a p1, \a p2, \a p3
00055 //  \return true if point is inside
00056 //  \note this method uses the less efficient 'angles' method which requires 3 calls to acos()
00057 bool vgl_triangle_3d_test_inside_simple(
00058   const vgl_point_3d<double>& i_pnt,
00059   const vgl_point_3d<double>& p1,
00060   const vgl_point_3d<double>& p2,
00061   const vgl_point_3d<double>& p3 );
00062 
00063 
00064 //: Compute the intersection point between the line segment and triangle
00065 //  The triangle is represented by its vertices \a p1, \a p2, \a p3
00066 //  \return true if line intersects triangle
00067 vgl_triangle_3d_intersection_t vgl_triangle_3d_line_intersection(
00068   const vgl_line_segment_3d<double>& line,
00069   const vgl_point_3d<double>& p1,
00070   const vgl_point_3d<double>& p2,
00071   const vgl_point_3d<double>& p3,
00072   vgl_point_3d<double>& i_pnt,
00073   bool ignore_coplanar = false);
00074 
00075 //: Compute if the given triangles a and b intersect
00076 //  The triangles are represented by their respective vertices \a a_p1, \a a_p2, \a a_p3
00077 //  and \a b_p1, \a b_p2, \a b_p3
00078 //  \return intersection type
00079 vgl_triangle_3d_intersection_t vgl_triangle_3d_triangle_intersection(
00080   const vgl_point_3d<double>& a_p1,
00081   const vgl_point_3d<double>& a_p2,
00082   const vgl_point_3d<double>& a_p3,
00083   const vgl_point_3d<double>& b_p1,
00084   const vgl_point_3d<double>& b_p2,
00085   const vgl_point_3d<double>& b_p3);
00086 
00087 //: Compute the intersection line of the given triangles
00088 //  \see vgl_triangle_3d_triangle_intersection()
00089 //  \note an intersection line is not computed for a coplanar intersection
00090 vgl_triangle_3d_intersection_t vgl_triangle_3d_triangle_intersection(
00091   const vgl_point_3d<double>& a_p1,
00092   const vgl_point_3d<double>& a_p2,
00093   const vgl_point_3d<double>& a_p3,
00094   const vgl_point_3d<double>& b_p1,
00095   const vgl_point_3d<double>& b_p2,
00096   const vgl_point_3d<double>& b_p3,
00097   vgl_line_segment_3d<double>& i_line);
00098 
00099 //: compute the intersection line of the given triangles
00100 //  \see vgl_triangle_3d_triangle_intersection()
00101 //  \note an intersection line is not computed for a coplanar intersection
00102 //  \retval i_line_point1_edge A number [0-5] indicating which edge of the two triangles
00103 //   point1 of i_line lies on. 0 indicates [a_p1,a_p2], 1 - [a_p2,a_p3], 2 - [a_p3,a_p1],
00104 //   3 - [b_p1,b_p2], 4 - [b_p2,b_p3], 5 - [b_p3,b_p1]
00105 //  \retval i_line_point2_edge. As i_line_point1_edge, but for the other end of the intersection.
00106 //  \note if i_line_point1_edge==i_line_point2_edge, this indicates that due to coplanarity, or
00107 //  some other corner case, there were more than two edges involved in the intersection
00108 //  boundaries. The returned edge is one of those edges.
00109 vgl_triangle_3d_intersection_t vgl_triangle_3d_triangle_intersection(
00110   const vgl_point_3d<double>& a_p1,
00111   const vgl_point_3d<double>& a_p2,
00112   const vgl_point_3d<double>& a_p3,
00113   const vgl_point_3d<double>& b_p1,
00114   const vgl_point_3d<double>& b_p2,
00115   const vgl_point_3d<double>& b_p3,
00116   vgl_line_segment_3d<double>& i_line,
00117   unsigned &i_line_point1_edge,
00118   unsigned &i_line_point2_edge);
00119 
00120 //: Compute the line of intersection of the given triangle and plane
00121 //  The triangle is represented by its vertices \a p1, \a p2, \a p3
00122 //  \return intersection type
00123 //  \note an intersection line is not defined (NaN) for a coplanar intersection
00124 vgl_triangle_3d_intersection_t vgl_triangle_3d_plane_intersection(
00125   const vgl_point_3d<double>& p1,
00126   const vgl_point_3d<double>& p2,
00127   const vgl_point_3d<double>& p3,
00128   const vgl_plane_3d<double>& i_plane,
00129   vgl_line_segment_3d<double>& i_line);
00130 
00131 //: Compute the longest side of the given triangle
00132 //  The triangle is represented by its vertices \a p1, \a p2, \a p3
00133 //  \return length of the longest side
00134 inline double vgl_triangle_3d_longest_side(
00135   const vgl_point_3d<double>& p1,
00136   const vgl_point_3d<double>& p2,
00137   const vgl_point_3d<double>& p3)
00138 {
00139   double side_length_max = vcl_max( (p2 - p1).sqr_length(), (p3 - p2).sqr_length());
00140   side_length_max = vcl_max( side_length_max, (p1 - p3).sqr_length());
00141   return vcl_sqrt(side_length_max);
00142 }
00143 
00144 //: Compute the shortest side of the given triangle
00145 //  The triangle is represented by its vertices \a p1, \a p2, \a p3
00146 //  \return length of the longest side
00147 inline double vgl_triangle_3d_shortest_side(
00148   const vgl_point_3d<double>& p1,
00149   const vgl_point_3d<double>& p2,
00150   const vgl_point_3d<double>& p3)
00151 {
00152   double side_length_min = vcl_min( (p2 - p1).sqr_length(), (p3 - p2).sqr_length());
00153   side_length_min = vcl_min( side_length_min, (p1 - p3).sqr_length());
00154   return vcl_sqrt(side_length_min);
00155 }
00156 
00157 //: Compute the closest point on a triangle to a reference point
00158 //  The triangle is represented by its vertices \a p1, \a p2, \a p3.
00159 //  \param q The reference point.
00160 //  \return The closest point on the triangle. This may be inside the triangle, or it may be a point on one of the triangle edges.
00161 vgl_point_3d<double> vgl_triangle_3d_closest_point(
00162   const vgl_point_3d<double>& q,
00163   const vgl_point_3d<double>& p1,
00164   const vgl_point_3d<double>& p2,
00165   const vgl_point_3d<double>& p3);
00166 
00167 //: Compute the distance to the closest point on a triangle from a reference point.
00168 //  The triangle is represented by its vertices \a p1, \a p2, \a p3.
00169 //  \param q The reference point.
00170 //  \return The distance to the closest point on the triangle. (The closest point may be inside the triangle, or it may be a point on one of the triangle edges.)
00171 double vgl_triangle_3d_distance(
00172   const vgl_point_3d<double>& q,
00173   const vgl_point_3d<double>& p1,
00174   const vgl_point_3d<double>& p2,
00175   const vgl_point_3d<double>& p3);
00176 
00177 //: Check if the two triangles are coplanar
00178 //  The triangles are represented by their respective vertices \a a_p1, \a a_p2, \a a_p3
00179 //  and \a b_p1, \a b_p2, \a b_p3
00180 bool vgl_triangle_3d_triangle_coplanar(
00181   const vgl_point_3d<double>& a_p1,
00182   const vgl_point_3d<double>& a_p2,
00183   const vgl_point_3d<double>& a_p3,
00184   const vgl_point_3d<double>& b_p1,
00185   const vgl_point_3d<double>& b_p2,
00186   const vgl_point_3d<double>& b_p3);
00187 
00188 
00189 //=======================================================================
00190 //: Compute the area of a triangle
00191 //  The triangle is represented by its vertices \a p1, \a p2, \a p3
00192 double vgl_triangle_3d_area(
00193   const vgl_point_3d<double> &p0,
00194   const vgl_point_3d<double> &p1,
00195   const vgl_point_3d<double> &p2 );
00196 
00197 //=======================================================================
00198 //: Compute the aspect ratio of a triangle
00199 //  The triangle is represented by its vertices \a p1, \a p2, \a p3
00200 double vgl_triangle_3d_aspect_ratio(
00201   const vgl_point_3d<double> &p0,
00202   const vgl_point_3d<double> &p1,
00203   const vgl_point_3d<double> &p2 );
00204 
00205 #endif // VGL_TRIANGLE_3D_H_