2b429e
2b429e
2b429e
#include <tools track.h=""></tools>
2b429e
2b429e
2b429e
//*****************************************************************************************
49945e
//    Static fields
2b429e
//*****************************************************************************************
2b429e
49945e
TTrack::Id TTrack::m_lastId = 0;
2b429e
2b429e
2b429e
//*****************************************************************************************
2b429e
//    TTrackModifier implemantation
2b429e
//*****************************************************************************************
2b429e
2b429e
TTrackPoint
2b429e
TTrackModifier::calcPoint(double originalIndex) {
2b429e
  TTrackPoint p = original.calcPoint(originalIndex);
2b429e
  p.originalIndex = originalIndex;
2b429e
  return p;
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,
49945e
  bool hasTilt
2b429e
):
49945e
  id(++m_lastId),
2b429e
  deviceId(deviceId),
2b429e
  touchId(touchId),
2b429e
  keyHistory(keyHistory),
2b429e
  buttonHistory(buttonHistory),
49945e
  hasPressure(hasPressure),
49945e
  hasTilt(hasTilt),
49945e
  pointsRemoved(),
f278a5
  pointsAdded(),
f278a5
  fixedPointsAdded(),
f278a5
  m_pointsFixed()
2b429e
  { }
2b429e
2b429e
TTrack::TTrack(const TTrackModifierP &modifier):
49945e
  id(++m_lastId),
2b429e
  deviceId(modifier->original.deviceId),
2b429e
  touchId(modifier->original.touchId),
2b429e
  keyHistory(modifier->original.keyHistory),
2b429e
  buttonHistory(modifier->original.buttonHistory),
49945e
  hasPressure(modifier->original.hasPressure),
49945e
  hasTilt(modifier->original.hasTilt),
7e9eb1
  modifier(modifier),
49945e
  pointsRemoved(),
f278a5
  pointsAdded(),
f278a5
  fixedPointsAdded(),
f278a5
  m_pointsFixed()
2b429e
  { }
2b429e
2b429e
const TTrack*
2b429e
TTrack::root() const
2b429e
  { return original() ? original()->root() : this; }
2b429e
2b429e
int
2b429e
TTrack::level() const
2b429e
  { return original() ? original()->level() + 1 : 0; }
2b429e
2b429e
int
7e9eb1
TTrack::floorIndex(double index, double *outFrac) const {
9f0c16
  int i = (int)floor(index + TConsts::epsilon);
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) {
49945e
  m_points.push_back(point);
9f0c16
  if (size() > 1) {
9f0c16
    const TTrackPoint &prev = *(m_points.rbegin() + 1);
9f0c16
    TTrackPoint &p = m_points.back();
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
9f0c16
    TPointD d = p.position - prev.position;
9f0c16
    p.length = prev.length + sqrt(d.x*d.x + d.y*d.y);
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
TTrackPoint
2b429e
TTrack::calcPoint(double index) const {
2b429e
  return modifier
2b429e
       ? modifier->calcPoint( originalIndexByIndex(index) )
2b429e
       : interpolateLinear(index);
2b429e
}
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 {
49945e
  return modifier
49945e
       ? modifier->original.rootIndexByIndex( originalIndexByIndex(index) )
49945e
       : index;
49945e
}
49945e
49945e
TTrackPoint
49945e
TTrack::calcRootPoint(double index) const {
49945e
  return modifier
49945e
       ? modifier->original.calcRootPoint( originalIndexByIndex(index) )
49945e
       : calcPoint(index);
49945e
}