Changes in src/Line.cpp [5589858:6f646d]
- File:
-
- 1 edited
-
src/Line.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Line.cpp
r5589858 r6f646d 11 11 12 12 #include "vector.hpp" 13 #include "log.hpp"14 #include "verbose.hpp"15 #include "gslmatrix.hpp"16 #include "info.hpp"17 #include "Exceptions/LinearDependenceException.hpp"18 #include "Exceptions/SkewException.hpp"19 #include "Plane.hpp"20 13 21 using namespace std; 22 23 Line::Line(const Vector &_origin, const Vector &_direction) : 14 Line::Line(Vector &_origin, Vector &_direction) : 15 origin(new Vector(_origin)), 24 16 direction(new Vector(_direction)) 25 17 { 26 18 direction->Normalize(); 27 origin.reset(new Vector(_origin.partition(*direction).second));28 19 } 29 30 Line::Line(const Line &src) :31 origin(new Vector(*src.origin)),32 direction(new Vector(*src.direction))33 {}34 20 35 21 Line::~Line() … … 38 24 39 25 double Line::distance(const Vector &point) const{ 40 // get any vector from line to point 41 Vector helper = point - *origin; 42 // partition this vector along direction 43 // the residue points from the line to the point 44 return helper.partition(*direction).second.Norm(); 26 return fabs(point.ScalarProduct(*direction) - origin->ScalarProduct(*direction)); 45 27 } 46 28 47 29 Vector Line::getClosestPoint(const Vector &point) const{ 48 // get any vector from line to point 49 Vector helper = point - *origin; 50 // partition this vector along direction 51 // add only the part along the direction 52 return *origin + helper.partition(*direction).first; 30 double factor = point.ScalarProduct(*direction) - origin->ScalarProduct(*direction); 31 return (point - (factor * (*direction))); 53 32 } 54 55 Vector Line::getDirection() const{56 return *direction;57 }58 59 Vector Line::getOrigin() const{60 return *origin;61 }62 63 vector<Vector> Line::getPointsOnLine() const{64 vector<Vector> res;65 res.reserve(2);66 res.push_back(*origin);67 res.push_back(*origin+*direction);68 return res;69 }70 71 /** Calculates the intersection of the two lines that are both on the same plane.72 * This is taken from Weisstein, Eric W. "Line-Line Intersection." From MathWorld--A Wolfram Web Resource. http://mathworld.wolfram.com/Line-LineIntersection.html73 * \param *out output stream for debugging74 * \param *Line1a first vector of first line75 * \param *Line1b second vector of first line76 * \param *Line2a first vector of second line77 * \param *Line2b second vector of second line78 * \return true - \a this will contain the intersection on return, false - lines are parallel79 */80 Vector Line::getIntersection(const Line& otherLine) const{81 Info FunctionInfo(__func__);82 83 pointset line1Points = getPointsOnLine();84 85 Vector Line1a = line1Points[0];86 Vector Line1b = line1Points[1];87 88 pointset line2Points = otherLine.getPointsOnLine();89 90 Vector Line2a = line2Points[0];91 Vector Line2b = line2Points[1];92 93 Vector res;94 95 auto_ptr<GSLMatrix> M = auto_ptr<GSLMatrix>(new GSLMatrix(4,4));96 97 M->SetAll(1.);98 for (int i=0;i<3;i++) {99 M->Set(0, i, Line1a[i]);100 M->Set(1, i, Line1b[i]);101 M->Set(2, i, Line2a[i]);102 M->Set(3, i, Line2b[i]);103 }104 105 //Log() << Verbose(1) << "Coefficent matrix is:" << endl;106 //for (int i=0;i<4;i++) {107 // for (int j=0;j<4;j++)108 // cout << "\t" << M->Get(i,j);109 // cout << endl;110 //}111 if (fabs(M->Determinant()) > MYEPSILON) {112 Log() << Verbose(1) << "Determinant of coefficient matrix is NOT zero." << endl;113 throw SkewException(__FILE__,__LINE__);114 }115 116 Log() << Verbose(1) << "INFO: Line1a = " << Line1a << ", Line1b = " << Line1b << ", Line2a = " << Line2a << ", Line2b = " << Line2b << "." << endl;117 118 119 // constuct a,b,c120 Vector a = Line1b - Line1a;121 Vector b = Line2b - Line2a;122 Vector c = Line2a - Line1a;123 Vector d = Line2b - Line1b;124 Log() << Verbose(1) << "INFO: a = " << a << ", b = " << b << ", c = " << c << "." << endl;125 if ((a.NormSquared() < MYEPSILON) || (b.NormSquared() < MYEPSILON)) {126 res.Zero();127 Log() << Verbose(1) << "At least one of the lines is ill-defined, i.e. offset equals second vector." << endl;128 throw LinearDependenceException(__FILE__,__LINE__);129 }130 131 // check for parallelity132 Vector parallel;133 double factor = 0.;134 if (fabs(a.ScalarProduct(b)*a.ScalarProduct(b)/a.NormSquared()/b.NormSquared() - 1.) < MYEPSILON) {135 parallel = Line1a - Line2a;136 factor = parallel.ScalarProduct(a)/a.Norm();137 if ((factor >= -MYEPSILON) && (factor - 1. < MYEPSILON)) {138 res = Line2a;139 Log() << Verbose(1) << "Lines conincide." << endl;140 return res;141 } else {142 parallel = Line1a - Line2b;143 factor = parallel.ScalarProduct(a)/a.Norm();144 if ((factor >= -MYEPSILON) && (factor - 1. < MYEPSILON)) {145 res = Line2b;146 Log() << Verbose(1) << "Lines conincide." << endl;147 return res;148 }149 }150 Log() << Verbose(1) << "Lines are parallel." << endl;151 res.Zero();152 throw LinearDependenceException(__FILE__,__LINE__);153 }154 155 // obtain s156 double s;157 Vector temp1, temp2;158 temp1 = c;159 temp1.VectorProduct(b);160 temp2 = a;161 temp2.VectorProduct(b);162 Log() << Verbose(1) << "INFO: temp1 = " << temp1 << ", temp2 = " << temp2 << "." << endl;163 if (fabs(temp2.NormSquared()) > MYEPSILON)164 s = temp1.ScalarProduct(temp2)/temp2.NormSquared();165 else166 s = 0.;167 Log() << Verbose(1) << "Factor s is " << temp1.ScalarProduct(temp2) << "/" << temp2.NormSquared() << " = " << s << "." << endl;168 169 // construct intersection170 res = a;171 res.Scale(s);172 res += Line1a;173 Log() << Verbose(1) << "Intersection is at " << res << "." << endl;174 175 return res;176 }177 178 /** Rotates the vector by an angle of \a alpha around this line.179 * \param rhs Vector to rotate180 * \param alpha rotation angle in radian181 */182 Vector Line::rotateVector(const Vector &rhs, double alpha) const{183 Vector helper = rhs;184 185 // translate the coordinate system so that the line goes through (0,0,0)186 helper -= *origin;187 188 // partition the vector into a part that gets rotated and a part that lies along the line189 pair<Vector,Vector> parts = helper.partition(*direction);190 191 // we just keep anything that is along the axis192 Vector res = parts.first;193 194 // the rest has to be rotated195 Vector a = parts.second;196 // we only have to do the rest, if we actually could partition the vector197 if(!a.IsZero()){198 // construct a vector that is orthogonal to a and direction and has length |a|199 Vector y = a;200 // direction is normalized, so the result has length |a|201 y.VectorProduct(*direction);202 203 res += cos(alpha) * a + sin(alpha) * y;204 }205 206 // translate the coordinate system back207 res += *origin;208 return res;209 }210 211 Plane Line::getOrthogonalPlane(const Vector &origin) const{212 return Plane(getDirection(),origin);213 }214 215 Line makeLineThrough(const Vector &x1, const Vector &x2){216 if(x1==x2){217 throw LinearDependenceException(__FILE__,__LINE__);218 }219 return Line(x1,x1-x2);220 }
Note:
See TracChangeset
for help on using the changeset viewer.
