Ignore:
Timestamp:
Aug 20, 2014, 1:04:08 PM (11 years ago)
Author:
Frederik Heber <heber@…>
Children:
6aa6b7
Parents:
a39f66
git-author:
Frederik Heber <heber@…> (06/05/14 17:42:39)
git-committer:
Frederik Heber <heber@…> (08/20/14 13:04:08)
Message:

Dropped quaternion rotation for simple arbitrary rotation axis and angle.

  • with newCenter, oldCenter and the cross product we have all we need: a rotation axis and an angle. We don't need to burden ourselves with those stupid, absolutely not working quaternions.
  • removeMatchingPoints() now works on an array.
  • Orientation rotation was wrong way round, added check.
  • TESTFIX: removed QuaternionTest from SphericalPointDistributionTest, marked FragmentMolecule-cycle and StoreSaturatedFragment regression tests as XFAIL.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Fragmentation/Exporters/SphericalPointDistribution.cpp

    ra39f66 rbb011f  
    136136
    137137SphericalPointDistribution::Polygon_t removeMatchingPoints(
    138     const SphericalPointDistribution::Polygon_t &_points,
     138    const VectorArray_t &_points,
    139139    const IndexList_t &_matchingindices
    140140    )
     
    144144  std::sort(indices.begin(), indices.end());
    145145  LOG(4, "DEBUG: sorted matching is " << indices);
    146   IndexArray_t::const_iterator valueiter = indices.begin();
    147   SphericalPointDistribution::Polygon_t::const_iterator pointiter =
    148       _points.begin();
    149   for (unsigned int i=0; i< _points.size(); ++i, ++pointiter) {
    150     // skip all those in values
    151     if (*valueiter == i)
    152       ++valueiter;
    153     else
    154       remainingpoints.push_back(*pointiter);
     146  IndexArray_t remainingindices(_points.size(), -1);
     147  std::generate(remainingindices.begin(), remainingindices.end(), UniqueNumber);
     148  IndexArray_t::iterator remainiter = std::set_difference(
     149      remainingindices.begin(), remainingindices.end(),
     150      indices.begin(), indices.end(),
     151      remainingindices.begin());
     152  remainingindices.erase(remainiter, remainingindices.end());
     153  LOG(4, "DEBUG: remaining indices are " << remainingindices);
     154  for (IndexArray_t::const_iterator iter = remainingindices.begin();
     155      iter != remainingindices.end(); ++iter) {
     156    remainingpoints.push_back(_points[*iter]);
    155157  }
    156   LOG(4, "DEBUG: remaining indices are " << remainingpoints);
    157158
    158159  return remainingpoints;
     
    289290    // determine rotation angles to align the two point distributions with
    290291    // respect to bestmatching
    291     SphericalPointDistribution::Polygon_t rotated_newpolygon;
     292    VectorArray_t rotated_newpolygon = remainingnew;
    292293    Vector oldCenter;
    293294    {
     
    306307      if ((oldCenter - newCenter).NormSquared() > std::numeric_limits<double>::epsilon()*1e4) {
    307308        // setup quaternion
    308         Vector RotationAxis = newCenter;
    309         RotationAxis.VectorProduct(oldCenter);
     309        Vector RotationAxis = oldCenter;
     310        RotationAxis.VectorProduct(newCenter);
     311        Line Axis(zeroVec, RotationAxis);
    310312        RotationAxis.Normalize();
    311         const double RotationAngle = oldCenter.Angle(newCenter)/(M_PI/2.);
    312 //            RotationAxis.Angle(oldCenter) - RotationAxis.Angle(newCenter);
    313         boost::math::quaternion<double> q
    314             (RotationAngle, RotationAxis[0], RotationAxis[1], RotationAxis[2]);
    315         LOG(5, "DEBUG: RotationAxis is " << RotationAxis
    316             << ", RotationAngle is " << RotationAngle);
    317         LOG(5, "DEBUG: Quaternion describing rotation is " << q);
     313        const double RotationAngle = oldCenter.Angle(newCenter); // /(M_PI/2.);
     314        LOG(5, "DEBUG: Rotate coordinate system by " << RotationAngle
     315            << " around axis " << RotationAxis);
     316
     317        // apply rotation angles
     318        for (VectorArray_t::iterator iter = rotated_newpolygon.begin();
     319            iter != rotated_newpolygon.end(); ++iter) {
     320          Vector &current = *iter;
     321          LOG(5, "DEBUG: Original point is " << current);
     322          current =  Axis.rotateVector(current, RotationAngle);
     323          LOG(5, "DEBUG: Rotated point is " << current);
     324        }
     325      }
     326    }
     327    // rotate triangle/line/point around itself to match orientation
     328    if (MCS.bestmatching.size() > 1) {
     329      if (oldCenter.NormSquared() > std::numeric_limits<double>::epsilon()*1e4) {
     330        // construct RotationAxis and two points on its plane, defining the angle
     331        const Line RotationAxis(zeroVec, oldCenter);
     332        Vector oldPosition(rotated_newpolygon[*MCS.bestmatching.begin()]);
     333        oldPosition.ProjectOntoPlane(RotationAxis.getDirection());
     334        Vector newPosition(remainingold[*MCS.bestmatching.begin()]);
     335        newPosition.ProjectOntoPlane(RotationAxis.getDirection());
     336
     337        // construct reference vector to determine direction of rotation
     338        Vector dreiBein(oldPosition);
     339        dreiBein.VectorProduct(oldCenter);
     340        dreiBein.Normalize();
     341        const double sign =
     342            (dreiBein.ScalarProduct(newPosition) < 0.) ? -1. : +1.;
     343        LOG(6, "DEBUG: oldCenter on plane is " << oldPosition
     344            << ", newCenter in plane is " << newPosition
     345            << ", and dreiBein is " << dreiBein);
     346        const double RotationAngle = sign * oldPosition.Angle(newPosition);
     347        LOG(5, "DEBUG: Rotating around self is " << RotationAngle
     348            << " around axis " << RotationAxis);
     349
    318350#ifndef NDEBUG
     351        // check: first bestmatching in rotated_newpolygon and remainingnew
     352        // should now equal
    319353        {
    320         // check that rotation works in DEBUG mode
    321         boost::math::quaternion<double> p(0., newCenter[0], newCenter[1], newCenter[2]);
    322         boost::math::quaternion<double> q_inverse =
    323             boost::math::conj(q)/(boost::math::norm(q));
    324         p = q * p * q_inverse;
    325         boost::math::quaternion<double> identity(1,0,0,0);
    326         ASSERT( boost::math::norm(q*q_inverse - identity) < std::numeric_limits<double>::epsilon()*1e4,
    327             "matchSphericalPointDistributions() - quaternion does not rotate newCenter "
    328             +toString(q*q_inverse)+" into oldCenter "+toString(identity)+".");
    329         boost::math::quaternion<double> comparison(0., -oldCenter[0], oldCenter[1], oldCenter[2]);
    330         ASSERT( boost::math::norm(p - comparison) < std::numeric_limits<double>::epsilon()*1e4,
    331             "matchSphericalPointDistributions() - quaternion does not rotate newCenter "
    332             +toString(p)+" into oldCenter "+toString(comparison)+".");
     354          const IndexList_t::const_iterator iter = MCS.bestmatching.begin();
     355          Vector rotatednew = RotationAxis.rotateVector(
     356              rotated_newpolygon[*iter],
     357              RotationAngle);
     358          LOG(4, "CHECK: rotated first new bestmatching is " << rotatednew
     359              << " while old was " << remainingold[*iter]);
     360          ASSERT( (rotatednew - remainingold[*iter]).Norm()
     361              < std::numeric_limits<double>::epsilon()*1e4,
     362              "matchSphericalPointDistributions() - orientation rotation does not work as expected.");
    333363        }
    334364#endif
    335365
    336         // rotate spherical distribution
    337         rotated_newpolygon = rotatePolygon(_newpolygon, q);
    338         LOG(5, "DEBUG: Rotated new polygon is " << rotated_newpolygon);
    339       } else {
    340         rotated_newpolygon = _newpolygon;
    341       }
    342     }
    343     // rotate triangle/line/point around itself to match orientation
    344     const Line RotationAxis(zeroVec, oldCenter);
    345     const double RotationAngle =
    346         oldCenter.Angle(remainingold[0])
    347         - oldCenter.Angle(remainingnew[*MCS.bestmatching.begin()]);
    348     LOG(5, "DEBUG: Rotate around self is " << RotationAngle
    349         << " around axis " << RotationAxis);
    350 
    351     for (SphericalPointDistribution::Polygon_t::iterator iter = rotated_newpolygon.begin();
    352         iter != rotated_newpolygon.end(); ++iter) {
    353       RotationAxis.rotateVector(*iter, RotationAngle);
     366        for (VectorArray_t::iterator iter = rotated_newpolygon.begin();
     367            iter != rotated_newpolygon.end(); ++iter) {
     368          Vector &current = *iter;
     369          LOG(6, "DEBUG: Original point is " << current);
     370          current = RotationAxis.rotateVector(current, RotationAngle);
     371          LOG(6, "DEBUG: Rotated point is " << current);
     372        }
     373      }
    354374    }
    355375
Note: See TracChangeset for help on using the changeset viewer.