/** * Creates an arc from 3 points. */ RArc RArc::createFrom3Points(const RVector& startPoint, const RVector& point, const RVector& endPoint) { // intersection of two middle lines // middle points between first two points: RVector mp1 = RVector::getAverage(startPoint, point); double a1 = startPoint.getAngleTo(point) + M_PI / 2.0; // direction from middle point to center: RVector dir1 = RVector::createPolar(1.0, a1); // middle points between last two points: RVector mp2 = RVector::getAverage(point, endPoint); double a2 = point.getAngleTo(endPoint) + M_PI / 2.0; // direction from middle point to center: RVector dir2 = RVector::createPolar(1.0, a2); RLine midLine1(mp1, mp1 + dir1); RLine midLine2(mp2, mp2 + dir2); QList<RVector> ips = midLine1.getIntersectionPoints(midLine2, false); if (ips.length()!=1) { //this.error = qsTr("No arc possible"); return RArc(); } RVector center = ips[0]; double radius = center.getDistanceTo(endPoint); double angle1 = center.getAngleTo(startPoint); double angle2 = center.getAngleTo(endPoint); bool reversed = RMath::isAngleBetween(center.getAngleTo(point), angle1, angle2, true); return RArc(center, radius, angle1, angle2, reversed); }
RCircle RCircle::createFrom3Points(const RVector& p1, const RVector& p2, const RVector& p3) { // intersection of two middle lines // middle points between first two points: RVector mp1 = RVector::getAverage(p1, p2); double a1 = p1.getAngleTo(p2) + M_PI / 2.0; // direction from middle point to center: RVector dir1 = RVector::createPolar(1.0, a1); // middle points between last two points: RVector mp2 = RVector::getAverage(p2, p3); double a2 = p2.getAngleTo(p3) + M_PI / 2.0; // direction from middle point to center: RVector dir2 = RVector::createPolar(1.0, a2); RLine midLine1(mp1, mp1 + dir1); RLine midLine2(mp2, mp2 + dir2); QList<RVector> ips = midLine1.getIntersectionPoints(midLine2, false); if (ips.length()!=1) { return RCircle(); } RVector center = ips[0]; double radius = center.getDistanceTo(p3); // double angle1 = center.getAngleTo(p1); // double angle2 = center.getAngleTo(p3); // bool reversed = RMath::isAngleBetween(center.getAngleTo(p2), // angle1, angle2, true); return RCircle(center, radius); }
/** * Creates this arc from 3 given points which define the arc line. * * @param p1 1st point. * @param p2 2nd point. * @param p3 3rd point. */ bool RS_Arc::createFrom3P(const RS_Vector& p1, const RS_Vector& p2, const RS_Vector& p3) { if (p1.distanceTo(p2)>RS_TOLERANCE && p2.distanceTo(p3)>RS_TOLERANCE && p3.distanceTo(p1)>RS_TOLERANCE) { // middle points between 3 points: RS_Vector mp1, mp2; RS_Vector dir1, dir2; double a1, a2; // intersection of two middle lines mp1 = (p1 + p2)/2.0; a1 = p1.angleTo(p2) + M_PI/2.0; dir1.setPolar(100.0, a1); mp2 = (p2 + p3)/2.0; a2 = p2.angleTo(p3) + M_PI/2.0; dir2.setPolar(100.0, a2); RS_ConstructionLineData d1(mp1, mp1 + dir1); RS_ConstructionLineData d2(mp2, mp2 + dir2); RS_ConstructionLine midLine1(NULL, d1); RS_ConstructionLine midLine2(NULL, d2); RS_VectorSolutions sol = RS_Information::getIntersection(&midLine1, &midLine2); data.center = sol.get(0); data.radius = data.center.distanceTo(p3); data.angle1 = data.center.angleTo(p1); data.angle2 = data.center.angleTo(p3); data.reversed = RS_Math::isAngleBetween(data.center.angleTo(p2), data.angle1, data.angle2, true); if (sol.get(0).valid && data.radius<1.0e14 && data.radius>RS_TOLERANCE) { calculateEndpoints(); calculateBorders(); return true; } else { RS_DEBUG->print("RS_Arc::createFrom3P(): " "Cannot create an arc with inf radius."); return false; } } else { RS_DEBUG->print("RS_Arc::createFrom3P(): " "Cannot create an arc with radius 0.0."); return false; } }