|
|
2b429e |
|
|
|
2b429e |
|
|
|
2b429e |
#include <tools track.h=""></tools>
|
|
|
2b429e |
|
|
|
2b429e |
|
|
|
2b429e |
//*****************************************************************************************
|
|
|
49945e |
// Static fields
|
|
|
2b429e |
//*****************************************************************************************
|
|
|
2b429e |
|
|
|
49945e |
TTrack::Id TTrack::m_lastId = 0;
|
|
|
2b429e |
|
|
|
da847a |
|
|
|
da847a |
//*****************************************************************************************
|
|
|
da847a |
// TTrackTransform implemantation
|
|
|
da847a |
//*****************************************************************************************
|
|
|
da847a |
|
|
|
da847a |
TAffine TTrackTransform::makeTiltTransform(const TAffine &a) {
|
|
|
da847a |
double l1 = a.a11*a.a11 + a.a21*a.a22;
|
|
|
da847a |
double l2 = a.a11*a.a11 + a.a21*a.a22;
|
|
|
da847a |
double l = std::max(l1, l2);
|
|
|
da847a |
double k = l > TConsts::epsilon*TConsts::epsilon ? 1/sqrt(l) : 0;
|
|
|
da847a |
return TAffine( a.a11*k, a.a12*k, 0,
|
|
|
da847a |
a.a21*k, a.a22*k, 0 );
|
|
|
da847a |
}
|
|
|
da847a |
|
|
|
2b429e |
|
|
|
2b429e |
//*****************************************************************************************
|
|
|
fa009d |
// TTrackIntrOrig implemantation
|
|
|
2b429e |
//*****************************************************************************************
|
|
|
2b429e |
|
|
|
2b429e |
TTrackPoint
|
|
|
fa009d |
TTrackIntrOrig::interpolate(double index) {
|
|
|
fa009d |
return track.original ? track.calcPointFromOriginal(track.originalIndexByIndex(index))
|
|
|
fa009d |
: track.interpolateLinear(index);
|
|
|
2b429e |
}
|
|
|
2b429e |
|
|
|
2b429e |
|
|
|
2b429e |
//*****************************************************************************************
|
|
|
2b429e |
// TTrack implemantation
|
|
|
2b429e |
//*****************************************************************************************
|
|
|
2b429e |
|
|
|
2b429e |
TTrack::TTrack(
|
|
|
efa14d |
TInputState::DeviceId deviceId,
|
|
|
efa14d |
TInputState::TouchId touchId,
|
|
|
efa14d |
const TInputState::KeyHistory::Holder &keyHistory,
|
|
|
49945e |
const TInputState::ButtonHistory::Holder &buttonHistory,
|
|
|
49945e |
bool hasPressure,
|
|
|
fa009d |
bool hasTilt,
|
|
|
fa009d |
double timeOffset
|
|
|
2b429e |
):
|
|
|
49945e |
id(++m_lastId),
|
|
|
2b429e |
deviceId(deviceId),
|
|
|
2b429e |
touchId(touchId),
|
|
|
2b429e |
keyHistory(keyHistory),
|
|
|
2b429e |
buttonHistory(buttonHistory),
|
|
|
49945e |
hasPressure(hasPressure),
|
|
|
49945e |
hasTilt(hasTilt),
|
|
|
fa009d |
original(),
|
|
|
fa009d |
timeOffset(timeOffset),
|
|
|
fa009d |
rootTimeOffset(timeOffset),
|
|
|
49945e |
pointsRemoved(),
|
|
|
f278a5 |
pointsAdded(),
|
|
|
f278a5 |
fixedPointsAdded(),
|
|
|
f278a5 |
m_pointsFixed()
|
|
|
2b429e |
{ }
|
|
|
2b429e |
|
|
|
fa009d |
TTrack::TTrack(const TTrack &original, double timeOffset):
|
|
|
49945e |
id(++m_lastId),
|
|
|
fa009d |
deviceId(original.deviceId),
|
|
|
fa009d |
touchId(original.touchId),
|
|
|
fa009d |
keyHistory(original.keyHistory),
|
|
|
fa009d |
buttonHistory(original.buttonHistory),
|
|
|
fa009d |
hasPressure(original.hasPressure),
|
|
|
fa009d |
hasTilt(original.hasTilt),
|
|
|
fa009d |
original(&original),
|
|
|
fa009d |
timeOffset(timeOffset),
|
|
|
fa009d |
rootTimeOffset(original.rootTimeOffset + timeOffset),
|
|
|
49945e |
pointsRemoved(),
|
|
|
f278a5 |
pointsAdded(),
|
|
|
f278a5 |
fixedPointsAdded(),
|
|
|
f278a5 |
m_pointsFixed()
|
|
|
2b429e |
{ }
|
|
|
2b429e |
|
|
|
2b429e |
const TTrack*
|
|
|
2b429e |
TTrack::root() const
|
|
|
fa009d |
{ return original ? original->root() : this; }
|
|
|
2b429e |
|
|
|
2b429e |
int
|
|
|
2b429e |
TTrack::level() const
|
|
|
fa009d |
{ return original ? original->level() + 1 : 0; }
|
|
|
2b429e |
|
|
|
2b429e |
int
|
|
|
7e9eb1 |
TTrack::floorIndex(double index, double *outFrac) const {
|
|
|
fa009d |
int i = floorIndexNoClamp(index);
|
|
|
7e9eb1 |
if (i > size() - 1) {
|
|
|
7e9eb1 |
if (outFrac) *outFrac = 0.0;
|
|
|
7e9eb1 |
return size() - 1;
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
if (i < 0) {
|
|
|
7e9eb1 |
if (outFrac) *outFrac = 0.0;
|
|
|
7e9eb1 |
return 0;
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
if (outFrac) *outFrac = std::max(0.0, index - (double)i);
|
|
|
2b429e |
return i;
|
|
|
2b429e |
}
|
|
|
2b429e |
|
|
|
2b429e |
void
|
|
|
f278a5 |
TTrack::push_back(const TTrackPoint &point, bool fixed) {
|
|
|
fa009d |
assert(m_points.empty() || !m_points.back().final);
|
|
|
49945e |
m_points.push_back(point);
|
|
|
fa009d |
TTrackPoint &p = m_points.back();
|
|
|
fa009d |
if (m_points.size() <= 1) {
|
|
|
fa009d |
p.length = 0;
|
|
|
fa009d |
} else {
|
|
|
9f0c16 |
const TTrackPoint &prev = *(m_points.rbegin() + 1);
|
|
|
2b429e |
|
|
|
9f0c16 |
// fix originalIndex
|
|
|
9f0c16 |
if (p.originalIndex < prev.originalIndex)
|
|
|
9f0c16 |
p.originalIndex = prev.originalIndex;
|
|
|
2b429e |
|
|
|
9f0c16 |
// fix time
|
|
|
9f0c16 |
p.time = std::max(p.time, prev.time + TToolTimer::step);
|
|
|
00337d |
|
|
|
9f0c16 |
// calculate length
|
|
|
fa009d |
p.length = prev.length + tdistance(p.position, prev.position);
|
|
|
9f0c16 |
}
|
|
|
00337d |
++pointsAdded;
|
|
|
f278a5 |
if (fixed) fix_all();
|
|
|
2b429e |
}
|
|
|
2b429e |
|
|
|
2b429e |
void
|
|
|
2b429e |
TTrack::pop_back(int count) {
|
|
|
00337d |
if (count > size()) count = size();
|
|
|
2b429e |
if (count <= 0) return;
|
|
|
f278a5 |
assert(size() - count >= m_pointsFixed);
|
|
|
00337d |
m_points.resize(size() - count);
|
|
|
7a5892 |
if (pointsAdded > count)
|
|
|
7a5892 |
{ pointsAdded -= count; return; }
|
|
|
7a5892 |
if (pointsAdded > 0)
|
|
|
7a5892 |
{ count -= pointsAdded; pointsAdded = 0; }
|
|
|
00337d |
pointsRemoved += count;
|
|
|
2b429e |
}
|
|
|
2b429e |
|
|
|
f278a5 |
void
|
|
|
f278a5 |
TTrack::fix_points(int count) {
|
|
|
f278a5 |
count = std::min(count, previewSize());
|
|
|
f278a5 |
assert(count >= 0);
|
|
|
f278a5 |
if (count <= 0) return;
|
|
|
f278a5 |
m_pointsFixed += count;
|
|
|
f278a5 |
fixedPointsAdded += count;
|
|
|
f278a5 |
}
|
|
|
f278a5 |
|
|
|
2b429e |
|
|
|
2b429e |
TPointD
|
|
|
2b429e |
TTrack::calcTangent(double index, double distance) const {
|
|
|
9f0c16 |
double minDistance = 10.0*TConsts::epsilon;
|
|
|
2b429e |
if (distance < minDistance) distance = minDistance;
|
|
|
2b429e |
TTrackPoint p = calcPoint(index);
|
|
|
2b429e |
TTrackPoint pp = calcPoint(indexByLength(p.length - distance));
|
|
|
2b429e |
TPointD dp = p.position - pp.position;
|
|
|
2b429e |
double lenSqr = dp.x*dp.x + dp.y*dp.y;
|
|
|
9f0c16 |
return lenSqr > TConsts::epsilon*TConsts::epsilon ? dp*(1.0/sqrt(lenSqr)) : TPointD();
|
|
|
2b429e |
}
|
|
|
49945e |
|
|
|
49945e |
double
|
|
|
49945e |
TTrack::rootIndexByIndex(double index) const {
|
|
|
fa009d |
return original
|
|
|
fa009d |
? original->rootIndexByIndex( originalIndexByIndex(index) )
|
|
|
49945e |
: index;
|
|
|
49945e |
}
|
|
|
49945e |
|
|
|
49945e |
TTrackPoint
|
|
|
49945e |
TTrack::calcRootPoint(double index) const {
|
|
|
fa009d |
return original
|
|
|
fa009d |
? original->calcRootPoint( originalIndexByIndex(index) )
|
|
|
49945e |
: calcPoint(index);
|
|
|
49945e |
}
|