Curve* EllipticalArc::portion(double f, double t) const { // fix input arguments if (f < 0) f = 0; if (f > 1) f = 1; if (t < 0) t = 0; if (t > 1) t = 1; if ( are_near(f, t) ) { EllipticalArc *arc = static_cast<EllipticalArc*>(duplicate()); arc->_center = arc->_initial_point = arc->_final_point = pointAt(f); arc->_start_angle = arc->_end_angle = _start_angle; arc->_rot_angle = _rot_angle; arc->_sweep = _sweep; arc->_large_arc = _large_arc; return arc; } EllipticalArc *arc = static_cast<EllipticalArc*>(duplicate()); arc->_initial_point = pointAt(f); arc->_final_point = pointAt(t); if ( f > t ) arc->_sweep = !_sweep; if ( _large_arc && fabs(sweepAngle() * (t-f)) < M_PI) arc->_large_arc = false; arc->_updateCenterAndAngles(arc->isSVGCompliant()); //TODO: be more clever return arc; }
double QgsGeometryUtils::circleLength( double x1, double y1, double x2, double y2, double x3, double y3 ) { double centerX, centerY, radius; circleCenterRadius( QgsPointV2( x1, y1 ), QgsPointV2( x2, y2 ), QgsPointV2( x3, y3 ), radius, centerX, centerY ); double length = M_PI / 180.0 * radius * sweepAngle( centerX, centerY, x1, y1, x2, y2, x3, y3 ); if ( length < 0 ) { length = -length; } return length; }
void SpiralShape::updatePath(const QSizeF &size) { createPath(size); normalize(); #if 0 Q_UNUSED(size); QPointF startpoint(m_handles[0]); QPointF curvePoints[12]; int pointCnt = arcToCurve(m_radii.x(), m_radii.y(), m_startAngle, sweepAngle() , startpoint, curvePoints); int cp = 0; m_points[cp]->setPoint(startpoint); m_points[cp]->unsetProperty(KoPathPoint::HasControlPoint1); for (int i = 0; i < pointCnt; i += 3) { m_points[cp]->setControlPoint2(curvePoints[i]); m_points[++cp]->setControlPoint1(curvePoints[i+1]); m_points[cp]->setPoint(curvePoints[i+2]); m_points[cp]->unsetProperty(KoPathPoint::HasControlPoint2); } if (m_type == Curve) { m_points[++cp]->setPoint(m_center); m_points[cp]->unsetProperty(KoPathPoint::HasControlPoint1); m_points[cp]->unsetProperty(KoPathPoint::HasControlPoint2); } else if (m_type == Line && m_startAngle == m_endAngle) { m_points[0]->setControlPoint1(m_points[cp]->controlPoint1()); m_points[0]->setPoint(m_points[cp]->point()); --cp; } m_subpaths[0]->clear(); for (int i = 0; i <= cp; ++i) { if (i < cp || (m_type == Line && m_startAngle != m_endAngle)) { m_points[i]->unsetProperty(KoPathPoint::CloseSubpath); } else { m_points[i]->setProperty(KoPathPoint::CloseSubpath); } m_subpaths[0]->push_back(m_points[i]); } #endif }
D2<SBasis> EllipticalArc::toSBasis() const { D2<SBasis> arc; // the interval of parametrization has to be [0,1] Coord et = initialAngle().radians() + ( _sweep ? sweepAngle() : -sweepAngle() ); Linear param(initialAngle(), et); Coord cos_rot_angle, sin_rot_angle; sincos(_rot_angle, sin_rot_angle, cos_rot_angle); // order = 4 seems to be enough to get a perfect looking elliptical arc SBasis arc_x = ray(X) * cos(param,4); SBasis arc_y = ray(Y) * sin(param,4); arc[0] = arc_x * cos_rot_angle - arc_y * sin_rot_angle + Linear(center(X),center(X)); arc[1] = arc_x * sin_rot_angle + arc_y * cos_rot_angle + Linear(center(Y),center(Y)); // ensure that endpoints remain exact for ( int d = 0 ; d < 2 ; d++ ) { arc[d][0][0] = initialPoint()[d]; arc[d][0][1] = finalPoint()[d]; } return arc; }