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; }
void Operation::IsIntersect(Shape* s1, Shape* s2) const { //Проверка правильности подбора типов фигур if((s1->id == 'T' && s2->id == 'S') || (s2->id == 'T' && s1->id == 'S')) { Shape *triagle = s1->id == 'T' ? s1 : s2, *square = s1->id == 'S' ? s1 : s2; Line distanceLine(triagle->GetCenterOfGravity(), square->GetCenterOfGravity()); double RT = triagle->GetCircumscribedRadius(), RS = square->GetCircumscribedRadius(), distance = distanceLine.GetLength(); double rT = triagle->GetInscribedRadius(), rS = square->GetInscribedRadius(); cout << "Shape " << s1->id << " and " << s2->id << " is " << (distance <= RT + RS && distance >= abs(rS - rT) ? ("") : ("not ")) << "intersect!" << endl; } else { std::cout << "Not such operation" << std::endl; } }
void Operation::IsInclude(Shape* s1, Shape* s2) const { //Проверка правильности подбора типов фигур if((s1->id == 'T' && s2->id == 'S') || (s2->id == 'T' && s1->id == 'S')) { Shape *triagle = s1->id == 'T' ? s1 : s2, *square = s1->id == 'S' ? s1 : s2; Line distanceLine(triagle->GetCenterOfGravity(), square->GetCenterOfGravity()); double distance = distanceLine.GetLength(); double rT = triagle->GetInscribedRadius(), rS = square->GetInscribedRadius(); if (distance < abs(rS - rT)) { cout << "Shape " << (s1->GetArea() > s2->GetArea() ? s1->id : s2->id) << " is include " << (s1->GetArea() > s2->GetArea() ? s2->id : s1->id) << endl; } else { cout << "Shape " << s1->id << " and " << s2->id << " is not include each other!" << endl; } } else { std::cout << "Not such operation" << std::endl; } }
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; }
float approximateDistance() const { return distanceLine(start, control1) + distanceLine(control1, control2) + distanceLine(control2, end); }
float PathTraversalState::lineTo(const FloatPoint& point) { float distance = distanceLine(m_current, point); m_current = m_control1 = m_control2 = point; return distance; }
float PathTraversalState::closeSubpath() { float distance = distanceLine(m_current, m_start); m_start = m_control1 = m_control2 = m_current; return distance; }