RArc RArc::createTangential(const RVector& startPoint, const RVector& pos, double direction, double radius) { RArc arc; arc.radius = radius; // orthogonal to base entity: RVector ortho; ortho.setPolar(radius, direction + M_PI/2.0); // two possible center points for arc: RVector center1 = startPoint + ortho; RVector center2 = startPoint - ortho; if (center1.getDistanceTo(pos) < center2.getDistanceTo(pos)) { arc.center = center1; } else { arc.center = center2; } // angles: arc.startAngle = arc.center.getAngleTo(startPoint); arc.endAngle = arc.center.getAngleTo(pos); // handle arc direction: arc.reversed = false; double diff = RMath::getNormalizedAngle(arc.getDirection1() - direction); if (fabs(diff-M_PI) < 1.0e-1) { arc.reversed = true; } return arc; }
void RExporter::exportArcSegment(const RArc& arc, bool allowForZeroLength) { if (allowForZeroLength && arc.isFullCircle()) { exportLineSegment(RLine(arc.getStartPoint(), arc.getEndPoint()), arc.getDirection1()); return; } double segmentLength; if (pixelSizeHint>0.0) { // approximate arc with segments with the length of 2 pixels: segmentLength = pixelSizeHint * 2; } else { segmentLength = arc.getRadius() / 40.0; } // avoid a segment length of 0: if (segmentLength<1.0e-4) { segmentLength = 1.0e-4; } double a1 = arc.getStartAngle(); double a2 = arc.getEndAngle(); RVector center = arc.getCenter(); double radius = arc.getRadius(); double aStep; if (radius<1.0e-3) { aStep = 0.1; } else { aStep = segmentLength / radius; if (aStep>1.0) { aStep = 1.0; } double minAStep = RSettings::getMinArcAngleStep(); if (draftMode) { minAStep *= 4; } if (aStep<minAStep) { aStep = minAStep; } } RVector prev = arc.getStartPoint(); RVector ci; double a; if (!arc.isReversed()) { // Arc Counterclockwise: if(a1>a2-RS::AngleTolerance) { a2+=2*M_PI; } for (a=a1+aStep; a<=a2; a+=aStep) { ci.x = center.x + cos(a) * radius; ci.y = center.y + sin(a) * radius; exportLineSegment(RLine(prev, ci), a+M_PI_2); prev = ci; } } else { // Arc Clockwise: if (a1<a2+RS::AngleTolerance) { a2-=2*M_PI; } for (a=a1-aStep; a>=a2; a-=aStep) { ci.x = center.x + cos(a) * radius; ci.y = center.y + sin(a) * radius; exportLineSegment(RLine(prev, ci), a+M_PI_2); prev = ci; } } this->exportLineSegment(RLine(prev, arc.getEndPoint()), arc.getEndAngle()+M_PI_2); }