static float curveLength(PathTraversalState& traversalState, CurveType curve) { Vector<CurveType> curveStack; curveStack.append(curve); float totalLength = 0.0f; do { float length = curve.approximateDistance(); if ((length - distanceLine(curve.start, curve.end)) > kPathSegmentLengthTolerance) { CurveType left, right; curve.split(left, right); curve = left; curveStack.append(right); } else { totalLength += length; if (traversalState.m_action == PathTraversalState::TraversalPointAtLength || traversalState.m_action == PathTraversalState::TraversalNormalAngleAtLength) { traversalState.m_previous = curve.start; traversalState.m_current = curve.end; if (traversalState.m_totalLength + totalLength > traversalState.m_desiredLength) return totalLength; } curve = curveStack.last(); curveStack.removeLast(); } } while (!curveStack.isEmpty()); return totalLength; }
static float curveLength(PathTraversalState& traversalState, CurveType curve) { static const unsigned short curveSplitDepthLimit = 20; static const double pathSegmentLengthToleranceSquared = 1.e-16; double curveScaleForToleranceSquared = curve.magnitudeSquared(); if (curveScaleForToleranceSquared < pathSegmentLengthToleranceSquared) return 0; Vector<CurveType> curveStack; curveStack.append(curve); float totalLength = 0; do { float length = curve.approximateDistance(); double lengthDiscrepancy = length - distanceLine(curve.start, curve.end); if ((lengthDiscrepancy * lengthDiscrepancy) / curveScaleForToleranceSquared > pathSegmentLengthToleranceSquared && curve.splitDepth < curveSplitDepthLimit) { CurveType leftCurve; CurveType rightCurve; curve.split(leftCurve, rightCurve); curve = leftCurve; curveStack.append(rightCurve); } else { totalLength += length; if (traversalState.m_action == PathTraversalState::TraversalPointAtLength || traversalState.m_action == PathTraversalState::TraversalNormalAngleAtLength) { traversalState.m_previous = curve.start; traversalState.m_current = curve.end; if (traversalState.m_totalLength + totalLength > traversalState.m_desiredLength) return totalLength; } curve = curveStack.last(); curveStack.removeLast(); } } while (!curveStack.isEmpty()); return totalLength; }