Changeset 76c0d6 for src/Line.cpp


Ignore:
Timestamp:
Jun 4, 2010, 9:28:46 AM (15 years ago)
Author:
Tillmann Crueger <crueger@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
2c8934
Parents:
e05826 (diff), 27ac00 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'StructureRefactoring' into stable

Conflicts:

molecuilder/src/Makefile.am
molecuilder/src/periodentafel.cpp

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Line.cpp

    re05826 r76c0d6  
    1111
    1212#include "vector.hpp"
    13 
    14 Line::Line(Vector &_origin, Vector &_direction) :
    15   origin(new Vector(_origin)),
     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
     21using namespace std;
     22
     23Line::Line(const Vector &_origin, const Vector &_direction) :
    1624  direction(new Vector(_direction))
    1725{
    1826  direction->Normalize();
    19 }
     27  origin.reset(new Vector(_origin.partition(*direction).second));
     28}
     29
     30Line::Line(const Line &src) :
     31  origin(new Vector(*src.origin)),
     32  direction(new Vector(*src.direction))
     33{}
    2034
    2135Line::~Line()
     
    2438
    2539double Line::distance(const Vector &point) const{
    26   return fabs(point.ScalarProduct(*direction) - origin->ScalarProduct(*direction));
     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();
    2745}
    2846
    2947Vector Line::getClosestPoint(const Vector &point) const{
    30   double factor = point.ScalarProduct(*direction) - origin->ScalarProduct(*direction);
    31   return (point - (factor * (*direction)));
    32 }
     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;
     53}
     54
     55Vector Line::getDirection() const{
     56  return *direction;
     57}
     58
     59Vector Line::getOrigin() const{
     60  return *origin;
     61}
     62
     63vector<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 */
     80Vector 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 */
     182Vector 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
     211Plane Line::getOrthogonalPlane(const Vector &origin) const{
     212  return Plane(getDirection(),origin);
     213}
     214
     215Line 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.