bool REllipseData::moveReferencePoint(const RVector& referencePoint, const RVector& targetPoint) { RVector startPoint = getStartPoint(); RVector endPoint = getEndPoint(); if (!isFullEllipse()) { if (referencePoint.equalsFuzzy(startPoint)) { moveStartPoint(targetPoint, true); return true; } if (referencePoint.equalsFuzzy(endPoint)) { moveEndPoint(targetPoint, true); return true; } } if (referencePoint.equalsFuzzy(center+majorPoint)) { double minorRadius = getMinorRadius(); majorPoint = targetPoint-center; setRatio(minorRadius / getMajorRadius()); return true; } if (referencePoint.equalsFuzzy(center-majorPoint)) { double minorRadius = getMinorRadius(); majorPoint = -(targetPoint-center); setRatio(minorRadius / getMajorRadius()); return true; } if (referencePoint.equalsFuzzy(center+getMinorPoint())) { setMinorPoint(targetPoint-center); return true; } if (referencePoint.equalsFuzzy(center-getMinorPoint())) { setMinorPoint(-(targetPoint-center)); return true; } if (referencePoint.equalsFuzzy(center)) { center = targetPoint; return true; } return false; }
void REllipse::correctMajorMinor() { if (ratio>1.0) { RVector mp = getMinorPoint(); ratio = 1.0/ratio; setMajorPoint(mp); startParam = RMath::getNormalizedAngle(startParam - M_PI/2.0); endParam = RMath::getNormalizedAngle(endParam - M_PI/2.0); } }
QList<RRefPoint> REllipseData::getReferencePoints(RS::ProjectionRenderingHint hint) const { Q_UNUSED(hint) QList<RRefPoint> ret; ret.append(RRefPoint(center, RRefPoint::Center)); ret.append(RRefPoint(center+majorPoint, RRefPoint::Secondary)); ret.append(RRefPoint(center-majorPoint, RRefPoint::Secondary)); ret.append(RRefPoint(center+getMinorPoint(), RRefPoint::Secondary)); ret.append(RRefPoint(center-getMinorPoint(), RRefPoint::Secondary)); ret.append(RRefPoint::toRefPointList(getFoci(), RRefPoint::Secondary)); if (!isFullEllipse()) { ret.append(RRefPoint(getStartPoint(), RRefPoint::Start)); ret.append(RRefPoint(getEndPoint(), RRefPoint::End)); } return ret; }
QList<RVector> REllipseData::getReferencePoints( RS::ProjectionRenderingHint hint) const { Q_UNUSED(hint) QList<RVector> ret; ret.append(center); ret.append(center+majorPoint); ret.append(center-majorPoint); ret.append(center+getMinorPoint()); ret.append(center-getMinorPoint()); ret.append(getFoci()); if (!isFullEllipse()) { ret.append(getStartPoint()); ret.append(getEndPoint()); } return ret; }
QList<RVector> REllipse::getBoxCorners() { QList<RVector> ret; RVector minorPoint = getMinorPoint(); ret.append(center + majorPoint + minorPoint); ret.append(center + majorPoint - minorPoint); ret.append(center - majorPoint - minorPoint); ret.append(center - majorPoint + minorPoint); return ret; }
QList<RLine> REllipse::getTangents(const RVector& point) const { QList<RLine> ret; if (getDistanceTo(point, false) < RS::PointTolerance) { // point is on ellipse: return ret; } // point is at center (prevents recursion when swapping ellipse minor / major): if (point.getDistanceTo(getCenter())<RS::PointTolerance) { return ret; } // swap ellipse minor / major if point is on minor axis // 20120928: and not also on major axis (prevent recursion): RLine minorAxis(getCenter(), getCenter() + getMinorPoint()); RLine majorAxis(getCenter(), getCenter() + getMajorPoint()); if (minorAxis.isOnShape(point, false) && !majorAxis.isOnShape(point, false)) { REllipse e2 =*this; e2.majorPoint = getMinorPoint(); e2.ratio = 1.0/ratio; return e2.getTangents(point); } double a = getMajorRadius(); // the length of the major axis / 2 double b = getMinorRadius(); // the length of the minor axis / 2 // rotate and move point: RVector point2 = point; point2.move(-getCenter()); point2.rotate(-getAngle()); double xp = point2.x; // coordinates of the given point double yp = point2.y; double xt1; // Tangent point 1 double yt1; double xt2; // Tangent point 2 double yt2; double a2 = a * a; double b2 = b * b; double d = a2 / b2 * yp / xp; double e = a2 / xp; double af = b2 * d * d + a2; double bf = -b2 * d * e * 2.0; double cf = b2 * e * e - a2 * b2; double t = sqrt(bf * bf - af * cf * 4.0); if (RMath::isNaN(t)) { return ret; } yt1 = (t - bf) / (af * 2.0); xt1 = e - d * yt1; yt2 = (-t - bf) / (af * 2.0); xt2 = e - d * yt2; RVector s1(xt1, yt1); s1.rotate(getAngle()); s1.move(getCenter()); RVector s2(xt2, yt2); s2.rotate(getAngle()); s2.move(getCenter()); if (s1.isValid()) { ret.append(RLine(point, s1)); } if (s2.isValid()) { ret.append(RLine(point, s2)); } return ret; }