Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/vector.cpp

    rb998c3 r7b36fe  
    88#include "defs.hpp"
    99#include "helpers.hpp"
    10 #include "memoryallocator.hpp"
     10#include "info.hpp"
     11#include "gslmatrix.hpp"
    1112#include "leastsquaremin.hpp"
    1213#include "log.hpp"
     14#include "memoryallocator.hpp"
    1315#include "vector.hpp"
    1416#include "verbose.hpp"
     17
     18#include <gsl/gsl_linalg.h>
     19#include <gsl/gsl_matrix.h>
     20#include <gsl/gsl_permutation.h>
     21#include <gsl/gsl_vector.h>
    1522
    1623/************************************ Functions for class vector ************************************/
     
    215222 * \param *Origin first vector of line
    216223 * \param *LineVector second vector of line
    217  * \return true -  \a this contains intersection point on return, false - line is parallel to plane
     224 * \return true -  \a this contains intersection point on return, false - line is parallel to plane (even if in-plane)
    218225 */
    219226bool Vector::GetIntersectionWithPlane(const Vector * const PlaneNormal, const Vector * const PlaneOffset, const Vector * const Origin, const Vector * const LineVector)
    220227{
     228  Info FunctionInfo(__func__);
    221229  double factor;
    222230  Vector Direction, helper;
     
    226234  Direction.SubtractVector(Origin);
    227235  Direction.Normalize();
    228   //Log() << Verbose(4) << "INFO: Direction is " << Direction << "." << endl;
     236  Log() << Verbose(1) << "INFO: Direction is " << Direction << "." << endl;
     237  //Log() << Verbose(1) << "INFO: PlaneNormal is " << *PlaneNormal << " and PlaneOffset is " << *PlaneOffset << "." << endl;
    229238  factor = Direction.ScalarProduct(PlaneNormal);
    230   if (factor < MYEPSILON) { // Uniqueness: line parallel to plane?
    231     eLog() << Verbose(2) << "Line is parallel to plane, no intersection." << endl;
     239  if (fabs(factor) < MYEPSILON) { // Uniqueness: line parallel to plane?
     240    Log() << Verbose(1) << "BAD: Line is parallel to plane, no intersection." << endl;
    232241    return false;
    233242  }
     
    235244  helper.SubtractVector(Origin);
    236245  factor = helper.ScalarProduct(PlaneNormal)/factor;
    237   if (factor < MYEPSILON) { // Origin is in-plane
    238     //Log() << Verbose(2) << "Origin of line is in-plane, simple." << endl;
     246  if (fabs(factor) < MYEPSILON) { // Origin is in-plane
     247    Log() << Verbose(1) << "GOOD: Origin of line is in-plane." << endl;
    239248    CopyVector(Origin);
    240249    return true;
     
    243252  Direction.Scale(factor);
    244253  CopyVector(Origin);
    245   //Log() << Verbose(4) << "INFO: Scaled direction is " << Direction << "." << endl;
     254  Log() << Verbose(1) << "INFO: Scaled direction is " << Direction << "." << endl;
    246255  AddVector(&Direction);
    247256
     
    250259  helper.SubtractVector(PlaneOffset);
    251260  if (helper.ScalarProduct(PlaneNormal) < MYEPSILON) {
    252     //Log() << Verbose(2) << "INFO: Intersection at " << *this << " is good." << endl;
     261    Log() << Verbose(1) << "GOOD: Intersection is " << *this << "." << endl;
    253262    return true;
    254263  } else {
     
    286295
    287296/** Calculates the intersection of the two lines that are both on the same plane.
    288  * We construct auxiliary plane with its vector normal to one line direction and the PlaneNormal, then a vector
    289  * from the first line's offset onto the plane. Finally, scale by factor is 1/cos(angle(line1,line2..)) = 1/SP(...), and
    290  * project onto the first line's direction and add its offset.
     297 * This is taken from Weisstein, Eric W. "Line-Line Intersection." From MathWorld--A Wolfram Web Resource. http://mathworld.wolfram.com/Line-LineIntersection.html
    291298 * \param *out output stream for debugging
    292299 * \param *Line1a first vector of first line
     
    299306bool Vector::GetIntersectionOfTwoLinesOnPlane(const Vector * const Line1a, const Vector * const Line1b, const Vector * const Line2a, const Vector * const Line2b, const Vector *PlaneNormal)
    300307{
    301   bool result = true;
    302   Vector Direction, OtherDirection;
    303   Vector AuxiliaryNormal;
    304   Vector Distance;
    305   const Vector *Normal = NULL;
    306   Vector *ConstructedNormal = NULL;
    307   bool FreeNormal = false;
    308 
    309   // construct both direction vectors
    310   Zero();
    311   Direction.CopyVector(Line1b);
    312   Direction.SubtractVector(Line1a);
    313   if (Direction.IsZero())
     308  Info FunctionInfo(__func__);
     309
     310  GSLMatrix *M = new GSLMatrix(4,4);
     311
     312  M->SetAll(1.);
     313  for (int i=0;i<3;i++) {
     314    M->Set(0, i, Line1a->x[i]);
     315    M->Set(1, i, Line1b->x[i]);
     316    M->Set(2, i, Line2a->x[i]);
     317    M->Set(3, i, Line2b->x[i]);
     318  }
     319 
     320  //Log() << Verbose(1) << "Coefficent matrix is:" << endl;
     321  //for (int i=0;i<4;i++) {
     322  //  for (int j=0;j<4;j++)
     323  //    cout << "\t" << M->Get(i,j);
     324  //  cout << endl;
     325  //}
     326  if (fabs(M->Determinant()) > MYEPSILON) {
     327    Log() << Verbose(1) << "Determinant of coefficient matrix is NOT zero." << endl;
    314328    return false;
    315   OtherDirection.CopyVector(Line2b);
    316   OtherDirection.SubtractVector(Line2a);
    317   if (OtherDirection.IsZero())
     329  }
     330  Log() << Verbose(1) << "INFO: Line1a = " << *Line1a << ", Line1b = " << *Line1b << ", Line2a = " << *Line2a << ", Line2b = " << *Line2b << "." << endl;
     331
     332
     333  // constuct a,b,c
     334  Vector a;
     335  Vector b;
     336  Vector c;
     337  Vector d;
     338  a.CopyVector(Line1b);
     339  a.SubtractVector(Line1a);
     340  b.CopyVector(Line2b);
     341  b.SubtractVector(Line2a);
     342  c.CopyVector(Line2a);
     343  c.SubtractVector(Line1a);
     344  d.CopyVector(Line2b);
     345  d.SubtractVector(Line1b);
     346  Log() << Verbose(1) << "INFO: a = " << a << ", b = " << b << ", c = " << c << "." << endl;
     347  if ((a.NormSquared() < MYEPSILON) || (b.NormSquared() < MYEPSILON)) {
     348   Zero();
     349   Log() << Verbose(1) << "At least one of the lines is ill-defined, i.e. offset equals second vector." << endl;
     350   return false;
     351  }
     352
     353  // check for parallelity
     354  Vector parallel;
     355  double factor = 0.;
     356  if (fabs(a.ScalarProduct(&b)*a.ScalarProduct(&b)/a.NormSquared()/b.NormSquared() - 1.) < MYEPSILON) {
     357    parallel.CopyVector(Line1a);
     358    parallel.SubtractVector(Line2a);
     359    factor = parallel.ScalarProduct(&a)/a.Norm();
     360    if ((factor >= -MYEPSILON) && (factor - 1. < MYEPSILON)) {
     361      CopyVector(Line2a);
     362      Log() << Verbose(1) << "Lines conincide." << endl;
     363      return true;
     364    } else {
     365      parallel.CopyVector(Line1a);
     366      parallel.SubtractVector(Line2b);
     367      factor = parallel.ScalarProduct(&a)/a.Norm();
     368      if ((factor >= -MYEPSILON) && (factor - 1. < MYEPSILON)) {
     369        CopyVector(Line2b);
     370        Log() << Verbose(1) << "Lines conincide." << endl;
     371        return true;
     372      }
     373    }
     374    Log() << Verbose(1) << "Lines are parallel." << endl;
     375    Zero();
    318376    return false;
    319 
    320   Direction.Normalize();
    321   OtherDirection.Normalize();
    322 
    323   //Log() << Verbose(4) << "INFO: Normalized Direction " << Direction << " and OtherDirection " << OtherDirection << "." << endl;
    324 
    325   if (fabs(OtherDirection.ScalarProduct(&Direction) - 1.) < MYEPSILON) { // lines are parallel
    326     if ((Line1a == Line2a) || (Line1a == Line2b))
    327       CopyVector(Line1a);
    328     else if ((Line1b == Line2b) || (Line1b == Line2b))
    329         CopyVector(Line1b);
    330     else
    331       return false;
    332     Log() << Verbose(4) << "INFO: Intersection is " << *this << "." << endl;
    333     return true;
    334   } else {
    335     // check whether we have a plane normal vector
    336     if (PlaneNormal == NULL) {
    337       ConstructedNormal = new Vector;
    338       ConstructedNormal->MakeNormalVector(&Direction, &OtherDirection);
    339       Normal = ConstructedNormal;
    340       FreeNormal = true;
    341     } else
    342       Normal = PlaneNormal;
    343 
    344     AuxiliaryNormal.MakeNormalVector(&OtherDirection, Normal);
    345     //Log() << Verbose(4) << "INFO: PlaneNormal is " << *Normal << " and AuxiliaryNormal " << AuxiliaryNormal << "." << endl;
    346 
    347     Distance.CopyVector(Line2a);
    348     Distance.SubtractVector(Line1a);
    349     //Log() << Verbose(4) << "INFO: Distance is " << Distance << "." << endl;
    350     if (Distance.IsZero()) {
    351       // offsets are equal, match found
    352       CopyVector(Line1a);
    353       result = true;
    354     } else {
    355       CopyVector(Distance.Projection(&AuxiliaryNormal));
    356       //Log() << Verbose(4) << "INFO: Projected Distance is " << *this << "." << endl;
    357       double factor = Direction.ScalarProduct(&AuxiliaryNormal);
    358       //Log() << Verbose(4) << "INFO: Scaling factor is " << factor << "." << endl;
    359       Scale(1./(factor*factor));
    360       //Log() << Verbose(4) << "INFO: Scaled Distance is " << *this << "." << endl;
    361       CopyVector(Projection(&Direction));
    362       //Log() << Verbose(4) << "INFO: Distance, projected into Direction, is " << *this << "." << endl;
    363       if (this->IsZero())
    364         result = false;
    365       else
    366         result = true;
    367       AddVector(Line1a);
    368     }
    369 
    370     if (FreeNormal)
    371       delete(ConstructedNormal);
    372   }
    373   if (result)
    374     Log() << Verbose(4) << "INFO: Intersection is " << *this << "." << endl;
    375 
    376   return result;
     377  }
     378
     379  // obtain s
     380  double s;
     381  Vector temp1, temp2;
     382  temp1.CopyVector(&c);
     383  temp1.VectorProduct(&b);
     384  temp2.CopyVector(&a);
     385  temp2.VectorProduct(&b);
     386  Log() << Verbose(1) << "INFO: temp1 = " << temp1 << ", temp2 = " << temp2 << "." << endl;
     387  if (fabs(temp2.NormSquared()) > MYEPSILON)
     388    s = temp1.ScalarProduct(&temp2)/temp2.NormSquared();
     389  else
     390    s = 0.;
     391  Log() << Verbose(1) << "Factor s is " << temp1.ScalarProduct(&temp2) << "/" << temp2.NormSquared() << " = " << s << "." << endl;
     392
     393  // construct intersection
     394  CopyVector(&a);
     395  Scale(s);
     396  AddVector(Line1a);
     397  Log() << Verbose(1) << "Intersection is at " << *this << "." << endl;
     398
     399  return true;
    377400};
    378401
Note: See TracChangeset for help on using the changeset viewer.