Effective implementation of algorithms (Master Thesis)
Effective and error-free implementation of algorithms
|
00001 #ifndef H_GEOMETRY_TWO_D_DISTANCE 00002 #define H_GEOMETRY_TWO_D_DISTANCE 00003 00004 #include "math/rational/rational.h" 00005 #include "linesegment.h" 00006 00007 namespace geometry { 00008 namespace two_d { 00009 00015 template<typename T> 00016 T sqrDistancePointPoint(Point<T> p1, Point<T> p2) { 00017 Point<T> p = p1 - p2; 00018 return p.dot(p); 00019 } 00020 00026 template<typename T> 00027 long double distancePointPoint(Point<T> p1, Point<T> p2) { 00028 Point<long double> p = p1 - p2; 00029 return sqrt(p.dot(p)); 00030 } 00031 00037 template<typename T> 00038 math::rational::Rational<T> sqrDistancePointLine(Point<T> p, LineSegment<T> line) { 00039 Point<T> lineVector = line.end - line.begin; 00040 Point<T> relativeP = p - line.begin; 00041 00042 T pp = relativeP.dot(relativeP); 00043 T lp = relativeP.dot(lineVector); 00044 T ll = lineVector.dot(lineVector); 00045 00046 math::rational::Rational<T> result(lp); 00047 return math::rational::Rational<T>(pp) - math::rational::Rational<T>(lp, ll) * 00048 math::rational::Rational<T>(lp); 00049 } 00050 00060 template<typename T> 00061 long double distancePointLine(Point<T> p, LineSegment<T> line) { 00062 Point<long double> lineVector(line.end - line.begin); 00063 Point<long double> relativeP(p - line.begin); 00064 00065 long double pp = relativeP.dot(relativeP); 00066 long double lp = relativeP.dot(lineVector); 00067 long double ll = lineVector.dot(lineVector); 00068 00069 return sqrt(pp - lp * lp / ll); 00070 } 00071 00077 template<typename T> 00078 math::rational::Rational<T> sqrDistancePointLineSegment(Point<T> p, LineSegment<T> line) { 00079 Point<T> lineVector = line.end - line.begin; 00080 Point<T> relativeP = p - line.begin; 00081 00082 T lp = relativeP.dot(lineVector); 00083 T ll = lineVector.dot(lineVector); 00084 if (lp <= 0) { 00085 return sqrDistancePointPoint(p, line.begin); 00086 } 00087 if (lp >= ll) { 00088 return sqrDistancePointPoint(p, line.end); 00089 } 00090 00091 return sqrDistancePointLine(p, line); 00092 } 00093 00103 template<typename T> 00104 long double distancePointLineSegment(Point<T> p, LineSegment<T> line) { 00105 Point<long double> lineVector = line.end - line.begin; 00106 Point<long double> relativeP = p - line.begin; 00107 00108 long double lp = relativeP.dot(lineVector); 00109 long double ll = lineVector.dot(lineVector); 00110 if (lp <= 0) { 00111 return distancePointPoint(p, line.begin); 00112 } 00113 if (lp >= ll) { 00114 return distancePointPoint(p, line.end); 00115 } 00116 00117 return distancePointLine(p, line); 00118 } 00119 00120 } // namespace two_w 00121 } // namespace geometry 00122 #endif