Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Line.cpp

    r5589858 r6f646d  
    1111
    1212#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"
    2013
    21 using namespace std;
    22 
    23 Line::Line(const Vector &_origin, const Vector &_direction) :
     14Line::Line(Vector &_origin, Vector &_direction) :
     15  origin(new Vector(_origin)),
    2416  direction(new Vector(_direction))
    2517{
    2618  direction->Normalize();
    27   origin.reset(new Vector(_origin.partition(*direction).second));
    2819}
    29 
    30 Line::Line(const Line &src) :
    31   origin(new Vector(*src.origin)),
    32   direction(new Vector(*src.direction))
    33 {}
    3420
    3521Line::~Line()
     
    3824
    3925double 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));
    4527}
    4628
    4729Vector 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)));
    5332}
    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.html
    73  * \param *out output stream for debugging
    74  * \param *Line1a first vector of first line
    75  * \param *Line1b second vector of first line
    76  * \param *Line2a first vector of second line
    77  * \param *Line2b second vector of second line
    78  * \return true - \a this will contain the intersection on return, false - lines are parallel
    79  */
    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,c
    120   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 parallelity
    132   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 s
    156   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   else
    166     s = 0.;
    167   Log() << Verbose(1) << "Factor s is " << temp1.ScalarProduct(temp2) << "/" << temp2.NormSquared() << " = " << s << "." << endl;
    168 
    169   // construct intersection
    170   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 rotate
    180  * \param alpha rotation angle in radian
    181  */
    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 line
    189   pair<Vector,Vector> parts = helper.partition(*direction);
    190 
    191   // we just keep anything that is along the axis
    192   Vector res = parts.first;
    193 
    194   // the rest has to be rotated
    195   Vector a = parts.second;
    196   // we only have to do the rest, if we actually could partition the vector
    197   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 back
    207   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.