00001
00002 #ifndef vgl_lineseg_test_txx_
00003 #define vgl_lineseg_test_txx_
00004
00005
00006
00007
00008 #include "vgl_lineseg_test.h"
00009 #include <vgl/vgl_tolerance.h>
00010 #include <vgl/vgl_triangle_test.h>
00011 #include <vcl_cmath.h>
00012
00013 template <class T>
00014 bool vgl_lineseg_test_line(T x1, T y1, T x2, T y2, T x3, T y3, T x4, T y4)
00015 {
00016 T a = vgl_triangle_test_discriminant(x1, y1, x2, y2, x3, y3);
00017 T b = vgl_triangle_test_discriminant(x1, y1, x2, y2, x4, y4);
00018
00019
00020 return (a<=0 && b>=0) || (a>=0 && b<=0);
00021 }
00022
00023
00024
00025 template <class T>
00026 static inline
00027 bool inbetween(T x1, T y1, T x2, T y2, T x3, T y3)
00028 {
00029 return (x1-x3)*(x2-x3)<=0 && (y1-y3)*(y2-y3)<=0;
00030 }
00031
00032 template <class T>
00033 bool vgl_lineseg_test_lineseg(T x1, T y1, T x2, T y2, T x3, T y3, T x4, T y4)
00034 {
00035
00036
00037
00038 double px1 = x1;
00039 double py1 = y1;
00040 double px2 = x2;
00041 double py2 = y2;
00042 double px3 = x3;
00043 double py3 = y3;
00044 double px4 = x4;
00045 double py4 = y4;
00046
00047 px1 = (px1 + px1*1e4) - px1*1e4;
00048 py1 = (py1 + py1*1e4) - py1*1e4;
00049 px2 = (px2 + px2*1e4) - px2*1e4;
00050 py2 = (py2 + py2*1e4) - py2*1e4;
00051 px3 = (px3 + px3*1e4) - px3*1e4;
00052 py3 = (py3 + py3*1e4) - py3*1e4;
00053 px4 = (px4 + px4*1e4) - px4*1e4;
00054 py4 = (py4 + py4*1e4) - py4*1e4;
00055
00056
00057
00058
00059
00060 double a = vgl_triangle_test_discriminant(px1, py1, px2, py2, px3, py3);
00061 double b = vgl_triangle_test_discriminant(px1, py1, px2, py2, px4, py4);
00062 double c = vgl_triangle_test_discriminant(px3, py3, px4, py4, px1, py1);
00063 double d = vgl_triangle_test_discriminant(px3, py3, px4, py4, px2, py2);
00064
00065
00066 a = (vcl_abs(a) < 1e-12) ? 0 : a;
00067 b = (vcl_abs(b) < 1e-12) ? 0 : b;
00068 c = (vcl_abs(c) < 1e-12) ? 0 : c;
00069 d = (vcl_abs(d) < 1e-12) ? 0 : d;
00070
00071 return
00072 ( ( (a<=0 && b>0) || (a>=0 && b<0) || (a<0 && b>=0) || (a>0 && b<=0) ) &&
00073 ( (c<=0 && d>0) || (c>=0 && d<0) || (c<0 && d>=0) || (c>0 && d<=0) ) )
00074 ||
00075 (
00076 a == 0 && b == 0 && c == 0 && d == 0 &&
00077 ( inbetween(px1, py1, px2, py2, px3, py3) ||
00078 inbetween(px1, py1, px2, py2, px4, py4) ||
00079 inbetween(px3, py3, px4, py4, px1, py1) ||
00080 inbetween(px3, py3, px4, py4, px2, py2) )
00081 );
00082 }
00083
00084
00085
00086
00087 template <class T>
00088 bool vgl_lineseg_test_point(vgl_point_2d<T> const& p,
00089 vgl_line_segment_2d<T> const& lseg)
00090 {
00091 vgl_point_2d<T> p1 = lseg.point1(), p2 = lseg.point2();
00092 T x1 = p1.x(), y1 = p1.y(),
00093 x2 = p2.x(), y2 = p2.y(),
00094 xp = p.x(), yp = p.y();
00095
00096 T d1p = (xp-x1)*(xp-x1) + (yp-y1)*(yp-y1);
00097 T d2p = (xp-x2)*(xp-x2) + (yp-y2)*(yp-y2);
00098 T d12 = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
00099 double diff = vcl_sqrt(d1p) + vcl_sqrt(d2p) - vcl_sqrt(d12);
00100
00101 return diff <= vgl_tolerance<double>::position;
00102 }
00103
00104
00105
00106 #undef VGL_LINESEG_TEST_INSTANTIATE
00107 #define VGL_LINESEG_TEST_INSTANTIATE(T) \
00108 template bool vgl_lineseg_test_line(T, T, T, T, T, T, T, T); \
00109 template bool vgl_lineseg_test_lineseg(T, T, T, T, T, T, T, T)
00110
00111 #endif // vgl_lineseg_test_txx_