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
}