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