|
|
7e9eb1 |
|
|
shun-iwasawa |
ec85ad |
#ifndef NDEBUG
|
|
|
7e9eb1 |
|
|
|
d8eddc |
#include <tools modifiers="" modifiertest.h=""></tools>
|
|
|
7e9eb1 |
|
|
|
d8eddc |
// std includes
|
|
|
d8eddc |
#include <cmath></cmath>
|
|
|
7e9eb1 |
|
|
|
7e9eb1 |
//*****************************************************************************************
|
|
|
7e9eb1 |
// TModifierTest::Modifier implementation
|
|
|
7e9eb1 |
//*****************************************************************************************
|
|
|
7e9eb1 |
|
|
shun-iwasawa |
ec85ad |
TModifierTest::Modifier::Modifier(TTrackHandler &handler, double angle,
|
|
shun-iwasawa |
ec85ad |
double radius, double speed)
|
|
shun-iwasawa |
ec85ad |
: TTrackModifier(handler), angle(angle), radius(radius), speed(speed) {}
|
|
|
7e9eb1 |
|
|
shun-iwasawa |
ec85ad |
TTrackPoint TModifierTest::Modifier::calcPoint(double originalIndex) {
|
|
|
7e9eb1 |
TTrackPoint p = TTrackModifier::calcPoint(originalIndex);
|
|
|
7e9eb1 |
|
|
|
9f0c16 |
if (p.length > TConsts::epsilon) {
|
|
|
7e9eb1 |
double frac;
|
|
|
7e9eb1 |
int i0 = original.floorIndex(originalIndex, &frac);
|
|
|
7e9eb1 |
int i1 = original.ceilIndex(originalIndex);
|
|
|
7e9eb1 |
if (i0 < 0) return p;
|
|
|
7e9eb1 |
|
|
shun-iwasawa |
ec85ad |
if (Handler *handler = dynamic_cast<handler *="">(&this->handler)) {</handler>
|
|
shun-iwasawa |
ec85ad |
double angle = this->angle + speed * TTrack::interpolationLinear(
|
|
shun-iwasawa |
ec85ad |
handler->angles[i0],
|
|
shun-iwasawa |
ec85ad |
handler->angles[i1], frac);
|
|
shun-iwasawa |
ec85ad |
double radius = 2.0 * this->radius * p.pressure;
|
|
shun-iwasawa |
ec85ad |
double s = sin(angle);
|
|
shun-iwasawa |
ec85ad |
double c = cos(angle);
|
|
shun-iwasawa |
ec85ad |
|
|
shun-iwasawa |
ec85ad |
TPointD tangent =
|
|
shun-iwasawa |
ec85ad |
original.calcTangent(originalIndex, fabs(2.0 * this->radius / speed));
|
|
shun-iwasawa |
ec85ad |
p.position.x -= tangent.y * s * radius;
|
|
shun-iwasawa |
ec85ad |
p.position.y += tangent.x * s * radius;
|
|
shun-iwasawa |
ec85ad |
p.pressure *= 1.0 - 0.5 * c;
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
} else {
|
|
|
7e9eb1 |
p.pressure = 0.0;
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
|
|
|
7e9eb1 |
return p;
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
|
|
|
7e9eb1 |
//*****************************************************************************************
|
|
|
7e9eb1 |
// TModifierTest implementation
|
|
|
7e9eb1 |
//*****************************************************************************************
|
|
|
7e9eb1 |
|
|
shun-iwasawa |
ec85ad |
TModifierTest::TModifierTest(int count, double radius)
|
|
shun-iwasawa |
ec85ad |
: count(count), radius(radius) {}
|
|
|
7e9eb1 |
|
|
shun-iwasawa |
ec85ad |
void TModifierTest::modifyTrack(const TTrack &track,
|
|
shun-iwasawa |
ec85ad |
TTrackList &outTracks) {
|
|
shun-iwasawa |
ec85ad |
const double segmentSize = 2.0 * M_PI / 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);
|
|
shun-iwasawa |
ec85ad |
for (int i = 0; i < count; ++i)
|
|
shun-iwasawa |
ec85ad |
track.handler->tracks.push_back(new TTrack(new Modifier(
|
|
shun-iwasawa |
ec85ad |
*track.handler, i * 2.0 * M_PI / (double)count, radius, 0.25)));
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
|
|
shun-iwasawa |
ec85ad |
Handler *handler = dynamic_cast<handler *="">(track.handler.getPointer());</handler>
|
|
|
7e9eb1 |
if (!handler) {
|
|
|
f278a5 |
TInputModifier::modifyTrack(track, outTracks);
|
|
|
7e9eb1 |
return;
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
|
|
shun-iwasawa |
ec85ad |
outTracks.insert(outTracks.end(), track.handler->tracks.begin(),
|
|
shun-iwasawa |
ec85ad |
track.handler->tracks.end());
|
|
shun-iwasawa |
ec85ad |
if (!track.changed()) return;
|
|
|
7e9eb1 |
|
|
|
c3c215 |
int start = track.size() - track.pointsAdded;
|
|
|
7e9eb1 |
if (start < 0) start = 0;
|
|
|
7e9eb1 |
|
|
|
7e9eb1 |
// remove angles
|
|
shun-iwasawa |
ec85ad |
double lastAngle = start < (int)handler->angles.size()
|
|
shun-iwasawa |
ec85ad |
? handler->angles[start]
|
|
shun-iwasawa |
ec85ad |
: handler->angles.empty() ? 0.0
|
|
shun-iwasawa |
ec85ad |
: handler->angles.back();
|
|
|
00337d |
handler->angles.resize(start, lastAngle);
|
|
|
7e9eb1 |
|
|
|
7e9eb1 |
// add angles
|
|
shun-iwasawa |
ec85ad |
for (int i = start; i < track.size(); ++i) {
|
|
|
7e9eb1 |
if (i > 0) {
|
|
shun-iwasawa |
ec85ad |
double dl = track[i].length - track[i - 1].length;
|
|
|
9f0c16 |
double da = track[i].pressure > TConsts::epsilon
|
|
shun-iwasawa |
ec85ad |
? dl / (radius * track[i].pressure)
|
|
shun-iwasawa |
ec85ad |
: 0.0;
|
|
shun-iwasawa |
ec85ad |
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
|
|
shun-iwasawa |
ec85ad |
for (TTrackList::const_iterator ti = handler->tracks.begin();
|
|
shun-iwasawa |
ec85ad |
ti != handler->tracks.end(); ++ti) {
|
|
shun-iwasawa |
ec85ad |
TTrack &subTrack = **ti;
|
|
|
9f0c16 |
double currentSegmentSize = segmentSize;
|
|
shun-iwasawa |
ec85ad |
if (const Modifier *modifier =
|
|
shun-iwasawa |
ec85ad |
dynamic_cast<const *="" modifier="">(subTrack.modifier.getPointer()))</const>
|
|
|
9f0c16 |
if (fabs(modifier->speed) > TConsts::epsilon)
|
|
shun-iwasawa |
ec85ad |
currentSegmentSize = segmentSize / fabs(modifier->speed);
|
|
|
7e9eb1 |
|
|
|
7e9eb1 |
// remove points
|
|
shun-iwasawa |
ec85ad |
int subStart =
|
|
shun-iwasawa |
ec85ad |
subTrack.floorIndex(subTrack.indexByOriginalIndex(start - 1)) + 1;
|
|
|
00337d |
subTrack.truncate(subStart);
|
|
|
7e9eb1 |
|
|
|
7e9eb1 |
// add points
|
|
shun-iwasawa |
ec85ad |
for (int i = start; i < track.size(); ++i) {
|
|
|
7e9eb1 |
if (i > 0) {
|
|
shun-iwasawa |
ec85ad |
double prevAngle = handler->angles[i - 1];
|
|
|
7e9eb1 |
double nextAngle = handler->angles[i];
|
|
shun-iwasawa |
ec85ad |
if (fabs(nextAngle - prevAngle) > 1.5 * currentSegmentSize) {
|
|
shun-iwasawa |
ec85ad |
double step = currentSegmentSize / fabs(nextAngle - prevAngle);
|
|
shun-iwasawa |
ec85ad |
double end = 1.0 - 0.5 * step;
|
|
shun-iwasawa |
ec85ad |
for (double frac = step; frac < end; frac += step)
|
|
shun-iwasawa |
ec85ad |
subTrack.push_back(
|
|
|
f278a5 |
subTrack.modifier->calcPoint((double)i - 1.0 + frac), false);
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
}
|
|
|
f278a5 |
subTrack.push_back(subTrack.modifier->calcPoint(i), false);
|
|
|
7e9eb1 |
}
|
|
|
f278a5 |
|
|
|
f278a5 |
// fix points
|
|
|
f278a5 |
if (track.fixedSize())
|
|
|
f278a5 |
subTrack.fix_to(
|
|
|
f278a5 |
subTrack.floorIndex(subTrack.indexByOriginalIndex(track.fixedSize() - 1)) + 1 );
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
|
|
|
00337d |
track.resetChanges();
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
|
|
|
f278a5 |
#endif
|