f278a5
f278a5
f278a5
#include <tools modifiers="" modifiersmooth.h=""></tools>
f278a5
#include <algorithm></algorithm>
f278a5
f278a5
f278a5
f278a5
//*****************************************************************************************
f278a5
//    TModifierSmooth implementation
f278a5
//*****************************************************************************************
f278a5
f278a5
fa009d
TModifierSmooth::TModifierSmooth(int radius):
fa009d
  radius(radius) { }
f278a5
f278a5
f278a5
void
f278a5
TModifierSmooth::modifyTrack(
f278a5
  const TTrack &track,
f278a5
  TTrackList &outTracks )
f278a5
{
fa009d
  int radius = abs(this->radius);
f278a5
  
fa009d
  if (!track.handler && radius) {
fa009d
    Handler *handler = new Handler(radius);
fa009d
    track.handler = handler;
fa009d
    handler->track = new TTrack(track);
f278a5
  }
f278a5
fa009d
  Handler *handler = dynamic_cast<handler*>(track.handler.getPointer());</handler*>
fa009d
  if (!handler)
fa009d
    return TInputModifier::modifyTrack(track, outTracks);
fa009d
  
fa009d
  radius = handler->radius;
fa009d
  outTracks.push_back(handler->track);
fa009d
  TTrack &subTrack = *handler->track;
fa009d
  
f278a5
  if (!track.changed())
f278a5
    return;
f278a5
  
f278a5
  // remove points
f278a5
  int start = std::max(0, track.size() - track.pointsAdded);
f278a5
  subTrack.truncate(start);
f278a5
f278a5
  // add points
f278a5
  // extra points will be added at the beginning and at the end
f278a5
  int size = track.size() + 2*radius;
f278a5
  double k = 1.0/(2*radius + 1);
f278a5
  TTrackTangent accum;
f278a5
  for(int i = start - 2*radius; i < size; ++i) {
f278a5
    
f278a5
    const TTrackPoint &p1 = track[i];
f278a5
    accum.position += p1.position;
f278a5
    accum.pressure += p1.pressure;
f278a5
    accum.tilt     += p1.tilt;
f278a5
    if (i < start)
f278a5
      continue;
f278a5
fa009d
    double originalIndex;
fa009d
    if (i <= radius) {
fa009d
      originalIndex = i/(double)(radius + 1);
fa009d
    } else
fa009d
    if (i >= size - radius - 1) {
fa009d
      originalIndex = track.size() - 1 - (size - i - 1)/(double)(radius + 1);
fa009d
    } else {
fa009d
      originalIndex = i - radius;
fa009d
    }
fa009d
    
fa009d
    TTrackPoint p = subTrack.pointFromOriginal(i - radius);
fa009d
    p.position = accum.position*k;
fa009d
    p.pressure = accum.pressure*k;
fa009d
    p.tilt = accum.tilt*k;
fa009d
    p.originalIndex = originalIndex;
fa009d
    p.final = p.final && i == size - 1;
fa009d
    subTrack.push_back(p, false);
f278a5
    
f278a5
    const TTrackPoint &p0 = track[i - 2*radius];
f278a5
    accum.position -= p0.position;
f278a5
    accum.pressure -= p0.pressure;
f278a5
    accum.tilt     -= p0.tilt;
f278a5
  }
f278a5
  
f278a5
  // fix points
f278a5
  if (track.fixedFinished()) {
f278a5
    subTrack.fix_all();
f278a5
  } else
f278a5
  if (track.fixedSize()) {
f278a5
    subTrack.fix_to(track.fixedSize());
f278a5
  }
f278a5
  
f278a5
  track.resetChanges();
f278a5
}
f278a5