7e9eb1
7e9eb1
d8eddc
#include <tools modifiers="" modifiertest.h=""></tools>
7e9eb1
d8eddc
// std includes
d8eddc
#include <cmath></cmath>
7e9eb1
7e9eb1
//*****************************************************************************************
7e9eb1
//    TModifierTest::Modifier implementation
7e9eb1
//*****************************************************************************************
7e9eb1
7e9eb1
7e9eb1
TModifierTest::Modifier::Modifier(
7e9eb1
  TTrackHandler &handler,
7e9eb1
  double angle,
7e9eb1
  double radius,
7e9eb1
  double speed
7e9eb1
):
7e9eb1
  TTrackModifier(handler),
7e9eb1
  angle(angle),
7e9eb1
  radius(radius),
7e9eb1
  speed(speed)
7e9eb1
{ }
7e9eb1
7e9eb1
7e9eb1
TTrackPoint
7e9eb1
TModifierTest::Modifier::calcPoint(double originalIndex) {
7e9eb1
  TTrackPoint p = TTrackModifier::calcPoint(originalIndex);
7e9eb1
7e9eb1
  if (p.length > 2.0) {
7e9eb1
    double frac;
7e9eb1
    int i0 = original.floorIndex(originalIndex, &frac);
7e9eb1
    int i1 = original.ceilIndex(originalIndex);
7e9eb1
    if (i0 < 0) return p;
7e9eb1
7e9eb1
    if (Handler *handler = dynamic_cast<handler*>(&this->handler)) {</handler*>
7e9eb1
      double angle = this->angle + speed*TTrack::interpolationLinear(
7e9eb1
        handler->angles[i0], handler->angles[i1], frac);
7e9eb1
      double radius = 2.0*this->radius*p.pressure;
7e9eb1
      double s = sin(angle);
7e9eb1
      double c = cos(angle);
7e9eb1
7e9eb1
      TPointD tangent = TPointD(1.0, 0.0); // original.calcTangent(originalIndex, fabs(2.0*this->radius/speed));
7e9eb1
      p.position.x += radius*(c*tangent.x - s*tangent.y);
7e9eb1
      p.position.y += radius*(s*tangent.x + c*tangent.y);
7e9eb1
      p.pressure   *= 0.5*(1.0 + c);
7e9eb1
    }
7e9eb1
  } else {
7e9eb1
    p.pressure = 0.0;
7e9eb1
  }
7e9eb1
7e9eb1
  return p;
7e9eb1
}
7e9eb1
7e9eb1
7e9eb1
//*****************************************************************************************
7e9eb1
//    TModifierTest implementation
7e9eb1
//*****************************************************************************************
7e9eb1
7e9eb1
7e9eb1
TModifierTest::TModifierTest():
7e9eb1
  count(1),
7e9eb1
  radius(40.0)
7e9eb1
{ }
7e9eb1
7e9eb1
7e9eb1
void
7e9eb1
TModifierTest::modifyTrack(
c3c215
  const TTrack &track,
7e9eb1
  const TInputSavePoint::Holder &savePoint,
7e9eb1
  TTrackList &outTracks )
7e9eb1
{
7e9eb1
  const double segmentSize = M_PI/180.0*10.0;
7e9eb1
c3c215
  if (!track.handler) {
c3c215
    if (track.getKeyState(track.front().time).isPressed(TKey(Qt::Key_Alt))) {
7e9eb1
      // TModifierTest::Handler for spiro
c3c215
      track.handler = new Handler(track);
7e9eb1
      for(int i = 0; i < count; ++i)
c3c215
        track.handler->tracks.push_back(
7e9eb1
          new TTrack(
7e9eb1
            new Modifier(
c3c215
              *track.handler,
7e9eb1
              i*2.0*M_PI/(double)count,
7e9eb1
              radius,
7e9eb1
              2.0 )));
7e9eb1
    }
7e9eb1
  }
7e9eb1
c3c215
  Handler *handler = dynamic_cast<handler*>(track.handler.getPointer());</handler*>
7e9eb1
  if (!handler) {
7e9eb1
    TInputModifier::modifyTrack(track, savePoint, outTracks);
7e9eb1
    return;
7e9eb1
  }
7e9eb1
7e9eb1
  outTracks.insert(
7e9eb1
    outTracks.end(),
c3c215
    track.handler->tracks.begin(),
c3c215
    track.handler->tracks.end() );
c3c215
  if (!track.changed())
7e9eb1
    return;
7e9eb1
c3c215
  int start = track.size() - track.pointsAdded;
7e9eb1
  if (start < 0) start = 0;
7e9eb1
7e9eb1
  // remove angles
7e9eb1
  if (start < (int)handler->angles.size())
7e9eb1
    handler->angles.erase(
7e9eb1
      handler->angles.begin() + start,
7e9eb1
      handler->angles.end() );
7e9eb1
7e9eb1
  // add angles
c3c215
  for(int i = start; i < track.size(); ++i) {
7e9eb1
    if (i > 0) {
c3c215
      double dl = track[i].length - track[i-1].length;
c3c215
      double da = track[i].pressure > TTrack::epsilon
c3c215
                ? dl/(2.0*radius*track[i].pressure) : 0.0;
7e9eb1
      handler->angles.push_back(handler->angles[i-1] + da);
7e9eb1
    } else {
7e9eb1
      handler->angles.push_back(0.0);
7e9eb1
    }
7e9eb1
  }
7e9eb1
7e9eb1
  // process sub-tracks
7e9eb1
  for(TTrackList::const_iterator ti = handler->tracks.begin(); ti != handler->tracks.end(); ++ti) {
7e9eb1
    TTrack &subTrack = **ti;
7e9eb1
7e9eb1
    // remove points
7e9eb1
    int subStart = subTrack.floorIndex(subTrack.indexByOriginalIndex(start));
7e9eb1
    if (subStart < 0) subStart = 0;
7e9eb1
    if (subStart < subTrack.size() && subTrack[subStart].originalIndex + TTrack::epsilon < start)
7e9eb1
      ++subStart;
7e9eb1
7e9eb1
    if (subStart < subTrack.size()) {
7e9eb1
      subTrack.pointsRemoved += subTrack.size() - subStart;
7e9eb1
      subTrack.truncate(subStart);
7e9eb1
    }
7e9eb1
7e9eb1
    // add points
c3c215
    for(int i = start; i < track.size(); ++i) {
7e9eb1
      if (i > 0) {
7e9eb1
        double prevAngle = handler->angles[i-1];
7e9eb1
        double nextAngle = handler->angles[i];
7e9eb1
        if (fabs(nextAngle - prevAngle) > 1.5*segmentSize) {
7e9eb1
          double step = segmentSize/fabs(nextAngle - prevAngle);
7e9eb1
          double end = 1.0 - 0.5*step;
7e9eb1
          for(double frac = step; frac < end; frac += step)
7e9eb1
            subTrack.push_back( subTrack.modifier->calcPoint((double)i - 1.0 + frac) );
7e9eb1
        }
7e9eb1
      }
7e9eb1
      subTrack.push_back( subTrack.modifier->calcPoint(i) );
7e9eb1
    }
7e9eb1
    subTrack.pointsAdded += subTrack.size() - subStart;
7e9eb1
  }
7e9eb1
c3c215
  track.pointsRemoved = 0;
c3c215
  track.pointsAdded = 0;
7e9eb1
}
7e9eb1