#include "rs_ellipse.h"
#include "drawing.h"
-#include "rs_graphicview.h"
+#include "graphicview.h"
#include "rs_information.h"
+#include "rs_linetypepattern.h"
#include "paintintf.h"
/**
calculateBorders();
}
-/**
- * Recalculates the endpoints using the angles and the radius.
- */
- /*
-void RS_Ellipse::calculateEndpoints() {
- double angle = data.majorP.angle();
- double radius1 = getMajorRadius();
- double radius2 = getMinorRadius();
+/*virtual*/ RS_Ellipse::~RS_Ellipse()
+{
+}
- startpoint.set(data.center.x + cos(data.angle1) * radius1,
- data.center.y + sin(data.angle1) * radius2);
- startpoint.rotate(data.center, angle);
- endpoint.set(data.center.x + cos(data.angle2) * radius1,
- data.center.y + sin(data.angle2) * radius2);
- endpoint.rotate(data.center, angle);
+/*virtual*/ RS_Entity * RS_Ellipse::clone()
+{
+ RS_Ellipse * e = new RS_Ellipse(*this);
+ e->initId();
+ return e;
}
-*/
+/** @return RS2::EntityEllipse */
+/*virtual*/ RS2::EntityType RS_Ellipse::rtti() const
+{
+ return RS2::EntityEllipse;
+}
/**
- * Calculates the boundary box of this ellipse.
- *
- * @todo Fix that - the algorithm used is really bad / slow.
+ * @return Start point of the entity.
*/
-void RS_Ellipse::calculateBorders() {
- RS_DEBUG->print("RS_Ellipse::calculateBorders");
-
- double radius1 = getMajorRadius();
- double radius2 = getMinorRadius();
- double angle = getAngle();
- double a1 = ((!isReversed()) ? data.angle1 : data.angle2);
- double a2 = ((!isReversed()) ? data.angle2 : data.angle1);
- Vector startpoint = getStartpoint();
- Vector endpoint = getEndpoint();
+/*virtual*/ Vector RS_Ellipse::getStartpoint() const
+{
+ Vector p;
+ p.set(data.center.x + cos(data.angle1) * getMajorRadius(),
+ data.center.y + sin(data.angle1) * getMinorRadius());
+ p.rotate(data.center, getAngle());
+ return p;
+}
- double minX = std::min(startpoint.x, endpoint.x);
- double minY = std::min(startpoint.y, endpoint.y);
- double maxX = std::max(startpoint.x, endpoint.x);
- double maxY = std::max(startpoint.y, endpoint.y);
+/**
+ * @return End point of the entity.
+ */
+/*virtual*/ Vector RS_Ellipse::getEndpoint() const
+{
+ Vector p;
+ p.set(data.center.x + cos(data.angle2) * getMajorRadius(),
+ data.center.y + sin(data.angle2) * getMinorRadius());
+ p.rotate(data.center, getAngle());
+ return p;
+}
- // kind of a brute force. TODO: exact calculation
- Vector vp;
- double a = a1;
- do {
- vp.set(data.center.x + radius1 * cos(a),
- data.center.y + radius2 * sin(a));
- vp.rotate(data.center, angle);
+void RS_Ellipse::moveStartpoint(const Vector & pos)
+{
+ data.angle1 = getEllipseAngle(pos);
+ //data.angle1 = data.center.angleTo(pos);
+ //calculateEndpoints();
+ calculateBorders();
+}
- minX = std::min(minX, vp.x);
- minY = std::min(minY, vp.y);
- maxX = std::max(maxX, vp.x);
- maxY = std::max(maxY, vp.y);
+void RS_Ellipse::moveEndpoint(const Vector & pos)
+{
+ data.angle2 = getEllipseAngle(pos);
+ //data.angle2 = data.center.angleTo(pos);
+ //calculateEndpoints();
+ calculateBorders();
+}
- a += 0.03;
- } while (RS_Math::isAngleBetween(RS_Math::correctAngle(a), a1, a2, false) &&
- a<4*M_PI);
+RS2::Ending RS_Ellipse::getTrimPoint(const Vector & coord, const Vector & trimPoint)
+{
+ double angEl = getEllipseAngle(trimPoint);
+ double angM = getEllipseAngle(coord);
+ if (RS_Math::getAngleDifference(angM, angEl) > M_PI)
+ //if (data.reversed) {
+ // return RS2::EndingEnd;
+ //}
+ //else {
+ return RS2::EndingStart;
+ //}
+ else
+ //if (data.reversed) {
+ // return RS2::EndingStart;
+ //}
+ //else {
+ return RS2::EndingEnd;
+ //}
+}
- minV.set(minX, minY);
- maxV.set(maxX, maxY);
- RS_DEBUG->print("RS_Ellipse::calculateBorders: OK");
+double RS_Ellipse::getEllipseAngle(const Vector & pos)
+{
+ Vector m = pos;
+ m.rotate(data.center, -data.majorP.angle());
+ Vector v = m - data.center;
+ v.scale(Vector(1.0, 1.0 / data.ratio));
+ return v.angle();
}
+/** @return Copy of data that defines the ellipse. **/
+RS_EllipseData RS_Ellipse::getData()
+{
+ return data;
+}
+VectorSolutions RS_Ellipse::getRefPoints()
+{
+ VectorSolutions ret(getStartpoint(), getEndpoint(), data.center);
+ return ret;
+}
-VectorSolutions RS_Ellipse::getRefPoints() {
- VectorSolutions ret(getStartpoint(), getEndpoint(), data.center);
- return ret;
+/**
+ * @retval true if the arc is reversed (clockwise),
+ * @retval false otherwise
+ */
+bool RS_Ellipse::isReversed() const
+{
+ return data.reversed;
}
+/** sets the reversed status. */
+void RS_Ellipse::setReversed(bool r)
+{
+ data.reversed = r;
+}
+/** @return The rotation angle of this ellipse */
+double RS_Ellipse::getAngle() const
+{
+ return data.majorP.angle();
+}
-Vector RS_Ellipse::getNearestEndpoint(const Vector& coord, double* dist) {
- double dist1, dist2;
- Vector nearerPoint;
- Vector startpoint = getStartpoint();
- Vector endpoint = getEndpoint();
+/** @return The start angle of this arc */
+double RS_Ellipse::getAngle1()
+{
+ return data.angle1;
+}
- dist1 = startpoint.distanceTo(coord);
- dist2 = endpoint.distanceTo(coord);
-
- if (dist2<dist1) {
- if (dist!=NULL) {
- *dist = dist2;
- }
- nearerPoint = endpoint;
- } else {
- if (dist!=NULL) {
- *dist = dist1;
- }
- nearerPoint = startpoint;
- }
-
- return nearerPoint;
-}
-
-
-
-Vector RS_Ellipse::getNearestPointOnEntity(const Vector& coord,
- bool onEntity, double* dist, RS_Entity** entity) {
-
- RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity");
-
- Vector ret(false);
-
- if (entity!=NULL) {
- *entity = this;
- }
- double ang = getAngle();
-
- Vector normalized = (coord - data.center).rotate(-ang);
-
- double dU = normalized.x;
- double dV = normalized.y;
- double dA = getMajorRadius();
- double dB = getMinorRadius();
- double dEpsilon = 1.0e-8;
- int iMax = 32;
- int riIFinal = 0;
- double rdX = 0.0;
- double rdY = 0.0;
- double dDistance;
- bool swap = false;
- bool majorSwap = false;
-
- if (dA<dB) {
- double dum = dA;
- dA = dB;
- dB = dum;
- dum = dU;
- dU = dV;
- dV = dum;
- majorSwap = true;
- }
-
- if (dV<0.0) {
- dV*=-1.0;
- swap = true;
- }
-
- // initial guess
- double dT = dB*(dV - dB);
-
- // Newton s method
- int i;
- for (i = 0; i < iMax; i++) {
- RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: i: %d", i);
- double dTpASqr = dT + dA*dA;
- double dTpBSqr = dT + dB*dB;
- double dInvTpASqr = 1.0/dTpASqr;
- double dInvTpBSqr = 1.0/dTpBSqr;
- double dXDivA = dA*dU*dInvTpASqr;
- double dYDivB = dB*dV*dInvTpBSqr;
- double dXDivASqr = dXDivA*dXDivA;
- double dYDivBSqr = dYDivB*dYDivB;
- double dF = dXDivASqr + dYDivBSqr - 1.0;
- RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: dF: %f", dF);
- if ( fabs(dF) < dEpsilon ) {
- // F(t0) is close enough to zero, terminate the iteration:
- rdX = dXDivA*dA;
- rdY = dYDivB*dB;
- riIFinal = i;
- RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: rdX,rdY 1: %f,%f", rdX, rdY);
- break;
- }
- double dFDer = 2.0*(dXDivASqr*dInvTpASqr + dYDivBSqr*dInvTpBSqr);
- double dRatio = dF/dFDer;
- RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: dRatio: %f", dRatio);
- if ( fabs(dRatio) < dEpsilon ) {
- // t1-t0 is close enough to zero, terminate the iteration:
- rdX = dXDivA*dA;
- rdY = dYDivB*dB;
- riIFinal = i;
- RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: rdX,rdY 2: %f,%f", rdX, rdY);
- break;
- }
- dT += dRatio;
- }
- if ( i == iMax ) {
- // failed to converge:
- RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: failed");
- dDistance = RS_MAXDOUBLE;
- }
- else {
- double dDelta0 = rdX - dU;
- double dDelta1 = rdY - dV;
- dDistance = sqrt(dDelta0*dDelta0 + dDelta1*dDelta1);
- ret = Vector(rdX, rdY);
- RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: rdX,rdY 2: %f,%f", rdX, rdY);
- RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: ret: %f,%f", ret.x, ret.y);
- }
-
- if (dist!=NULL) {
- if (ret.valid) {
- *dist = dDistance;
- } else {
- *dist = RS_MAXDOUBLE;
- }
- }
-
- if (ret.valid) {
- if (swap) {
- ret.y*=-1.0;
- }
- if (majorSwap) {
- double dum = ret.x;
- ret.x = ret.y;
- ret.y = dum;
- }
- ret = (ret.rotate(ang) + data.center);
-
- if (onEntity) {
- double a1 = data.center.angleTo(getStartpoint());
- double a2 = data.center.angleTo(getEndpoint());
- double a = data.center.angleTo(ret);
- if (!RS_Math::isAngleBetween(a, a1, a2, data.reversed)) {
- ret = Vector(false);
- }
- }
- }
-
- return ret;
+/** Sets new start angle. */
+void RS_Ellipse::setAngle1(double a1)
+{
+ data.angle1 = a1;
}
+/** @return The end angle of this arc */
+double RS_Ellipse::getAngle2()
+{
+ return data.angle2;
+}
+/** Sets new end angle. */
+void RS_Ellipse::setAngle2(double a2)
+{
+ data.angle2 = a2;
+}
-/**
- * @param tolerance Tolerance.
- *
- * @retval true if the given point is on this entity.
- * @retval false otherwise
- */
-bool RS_Ellipse::isPointOnEntity(const Vector& coord,
- double tolerance) {
- double dist = getDistanceToPoint(coord, NULL, RS2::ResolveNone);
- return (dist<=tolerance);
+/** @return The center point (x) of this arc */
+Vector RS_Ellipse::getCenter()
+{
+ return data.center;
}
+/** Sets new center. */
+void RS_Ellipse::setCenter(const Vector & c)
+{
+ data.center = c;
+}
+/** @return The endpoint of the major axis (relative to center). */
+Vector RS_Ellipse::getMajorP()
+{
+ return data.majorP;
+}
-Vector RS_Ellipse::getNearestCenter(const Vector& coord,
- double* dist) {
- if (dist!=NULL) {
- *dist = coord.distanceTo(data.center);
- }
- return data.center;
+/** Sets new major point (relative to center). */
+void RS_Ellipse::setMajorP(const Vector & p)
+{
+ data.majorP = p;
}
+/** @return The ratio of minor to major axis */
+double RS_Ellipse::getRatio()
+{
+ return data.ratio;
+}
+/** Sets new ratio. */
+void RS_Ellipse::setRatio(double r)
+{
+ data.ratio = r;
+}
/**
- * @todo Implement this.
+ * @return Angle length in rad.
*/
-Vector RS_Ellipse::getNearestMiddle(const Vector& /*coord*/,
- double* dist) {
- if (dist!=NULL) {
- *dist = RS_MAXDOUBLE;
- }
- return Vector(false);
+/*virtual*/ double RS_Ellipse::getAngleLength() const
+{
+ if (isReversed())
+ return data.angle1 - data.angle2;
+ else
+ return data.angle2 - data.angle1;
}
+/** @return The major radius of this ellipse. Same as getRadius() */
+double RS_Ellipse::getMajorRadius() const
+{
+ return data.majorP.magnitude();
+}
-
-Vector RS_Ellipse::getNearestDist(double /*distance*/,
- const Vector& /*coord*/,
- double* dist) {
- if (dist!=NULL) {
- *dist = RS_MAXDOUBLE;
- }
- return Vector(false);
+/** @return The minor radius of this ellipse */
+double RS_Ellipse::getMinorRadius() const
+{
+ return data.majorP.magnitude() * data.ratio;
}
+/**
+ * Recalculates the endpoints using the angles and the radius.
+ */
+/*
+ void RS_Ellipse::calculateEndpoints() {
+ double angle = data.majorP.angle();
+ double radius1 = getMajorRadius();
+ double radius2 = getMinorRadius();
+
+ startpoint.set(data.center.x + cos(data.angle1) * radius1,
+ data.center.y + sin(data.angle1) * radius2);
+ startpoint.rotate(data.center, angle);
+ endpoint.set(data.center.x + cos(data.angle2) * radius1,
+ data.center.y + sin(data.angle2) * radius2);
+ endpoint.rotate(data.center, angle);
+ }
+ */
+/**
+ * Calculates the boundary box of this ellipse.
+ *
+ * @todo Fix that - the algorithm used is really bad / slow.
+ */
+void RS_Ellipse::calculateBorders()
+{
+ RS_DEBUG->print("RS_Ellipse::calculateBorders");
+
+ double radius1 = getMajorRadius();
+ double radius2 = getMinorRadius();
+ double angle = getAngle();
+ double a1 = ((!isReversed()) ? data.angle1 : data.angle2);
+ double a2 = ((!isReversed()) ? data.angle2 : data.angle1);
+ Vector startpoint = getStartpoint();
+ Vector endpoint = getEndpoint();
-double RS_Ellipse::getDistanceToPoint(const Vector& coord,
- RS_Entity** entity,
- RS2::ResolveLevel, double /*solidDist*/) {
- double dist = RS_MAXDOUBLE;
- getNearestPointOnEntity(coord, true, &dist, entity);
+ double minX = std::min(startpoint.x, endpoint.x);
+ double minY = std::min(startpoint.y, endpoint.y);
+ double maxX = std::max(startpoint.x, endpoint.x);
+ double maxY = std::max(startpoint.y, endpoint.y);
- return dist;
+ // kind of a brute force. TODO: exact calculation
+ Vector vp;
+ double a = a1;
-}
+ do
+ {
+ vp.set(data.center.x + radius1 * cos(a),
+ data.center.y + radius2 * sin(a));
+ vp.rotate(data.center, angle);
+ minX = std::min(minX, vp.x);
+ minY = std::min(minY, vp.y);
+ maxX = std::max(maxX, vp.x);
+ maxY = std::max(maxY, vp.y);
+ a += 0.03;
+ }
+ while (RS_Math::isAngleBetween(RS_Math::correctAngle(a), a1, a2, false)
+ && a < 4 * M_PI);
-void RS_Ellipse::move(Vector offset) {
- data.center.move(offset);
- //calculateEndpoints();
- calculateBorders();
+ minV.set(minX, minY);
+ maxV.set(maxX, maxY);
+ RS_DEBUG->print("RS_Ellipse::calculateBorders: OK");
}
+Vector RS_Ellipse::getNearestEndpoint(const Vector & coord, double * dist)
+{
+ double dist1, dist2;
+ Vector nearerPoint;
+ Vector startpoint = getStartpoint();
+ Vector endpoint = getEndpoint();
+ dist1 = startpoint.distanceTo(coord);
+ dist2 = endpoint.distanceTo(coord);
-void RS_Ellipse::rotate(Vector center, double angle) {
- data.center.rotate(center, angle);
- data.majorP.rotate(angle);
- //calculateEndpoints();
- calculateBorders();
+ if (dist2 < dist1)
+ {
+ if (dist != NULL)
+ *dist = dist2;
+ nearerPoint = endpoint;
+ }
+ else
+ {
+ if (dist != NULL)
+ *dist = dist1;
+ nearerPoint = startpoint;
+ }
+
+ return nearerPoint;
}
+Vector RS_Ellipse::getNearestPointOnEntity(const Vector & coord, bool onEntity, double * dist, RS_Entity * * entity)
+{
+ RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity");
+
+ Vector ret(false);
+
+ if (entity != NULL)
+ *entity = this;
+ double ang = getAngle();
+
+ Vector normalized = (coord - data.center).rotate(-ang);
+
+ double dU = normalized.x;
+ double dV = normalized.y;
+ double dA = getMajorRadius();
+ double dB = getMinorRadius();
+ double dEpsilon = 1.0e-8;
+ int iMax = 32;
+ int riIFinal = 0;
+ double rdX = 0.0;
+ double rdY = 0.0;
+ double dDistance;
+ bool swap = false;
+ bool majorSwap = false;
+
+ if (dA < dB)
+ {
+ double dum = dA;
+ dA = dB;
+ dB = dum;
+ dum = dU;
+ dU = dV;
+ dV = dum;
+ majorSwap = true;
+ }
+ if (dV < 0.0)
+ {
+ dV *= -1.0;
+ swap = true;
+ }
-void RS_Ellipse::moveStartpoint(const Vector& pos) {
- data.angle1 = getEllipseAngle(pos);
- //data.angle1 = data.center.angleTo(pos);
- //calculateEndpoints();
- calculateBorders();
-}
+ // initial guess
+ double dT = dB * (dV - dB);
+ // Newton s method
+ int i;
+ for (i = 0; i < iMax; i++)
+ {
+ RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: i: %d", i);
+ double dTpASqr = dT + dA * dA;
+ double dTpBSqr = dT + dB * dB;
+ double dInvTpASqr = 1.0 / dTpASqr;
+ double dInvTpBSqr = 1.0 / dTpBSqr;
+ double dXDivA = dA * dU * dInvTpASqr;
+ double dYDivB = dB * dV * dInvTpBSqr;
+ double dXDivASqr = dXDivA * dXDivA;
+ double dYDivBSqr = dYDivB * dYDivB;
+ double dF = dXDivASqr + dYDivBSqr - 1.0;
+ RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: dF: %f", dF);
+
+ if (fabs(dF) < dEpsilon)
+ {
+ // F(t0) is close enough to zero, terminate the iteration:
+ rdX = dXDivA * dA;
+ rdY = dYDivB * dB;
+ riIFinal = i;
+ RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: rdX,rdY 1: %f,%f", rdX, rdY);
+ break;
+ }
+ double dFDer = 2.0 * (dXDivASqr * dInvTpASqr + dYDivBSqr * dInvTpBSqr);
+ double dRatio = dF / dFDer;
+ RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: dRatio: %f", dRatio);
-void RS_Ellipse::moveEndpoint(const Vector& pos) {
- data.angle2 = getEllipseAngle(pos);
- //data.angle2 = data.center.angleTo(pos);
- //calculateEndpoints();
- calculateBorders();
-}
+ if (fabs(dRatio) < dEpsilon)
+ {
+ // t1-t0 is close enough to zero, terminate the iteration:
+ rdX = dXDivA * dA;
+ rdY = dYDivB * dB;
+ riIFinal = i;
+ RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: rdX,rdY 2: %f,%f", rdX, rdY);
+ break;
+ }
+ dT += dRatio;
+ }
+ if (i == iMax)
+ {
+ // failed to converge:
+ RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: failed");
+ dDistance = RS_MAXDOUBLE;
+ }
+ else
+ {
+ double dDelta0 = rdX - dU;
+ double dDelta1 = rdY - dV;
+ dDistance = sqrt(dDelta0 * dDelta0 + dDelta1 * dDelta1);
+ ret = Vector(rdX, rdY);
+ RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: rdX,rdY 2: %f,%f", rdX, rdY);
+ RS_DEBUG->print("RS_Ellipse::getNearestPointOnEntity: ret: %f,%f", ret.x, ret.y);
+ }
-RS2::Ending RS_Ellipse::getTrimPoint(const Vector& coord,
- const Vector& trimPoint) {
+ if (dist != NULL)
+ {
+ if (ret.valid)
+ *dist = dDistance;
+ else
+ *dist = RS_MAXDOUBLE;
+ }
- double angEl = getEllipseAngle(trimPoint);
- double angM = getEllipseAngle(coord);
+ if (ret.valid)
+ {
+ if (swap)
+ ret.y *= -1.0;
- if (RS_Math::getAngleDifference(angM, angEl)>M_PI) {
- //if (data.reversed) {
- // return RS2::EndingEnd;
- //}
- //else {
- return RS2::EndingStart;
- //}
- }
- else {
- //if (data.reversed) {
- // return RS2::EndingStart;
- //}
- //else {
- return RS2::EndingEnd;
- //}
+
+ if (majorSwap)
+ {
+ double dum = ret.x;
+ ret.x = ret.y;
+ ret.y = dum;
+ }
+ ret = (ret.rotate(ang) + data.center);
+
+ if (onEntity)
+ {
+ double a1 = data.center.angleTo(getStartpoint());
+ double a2 = data.center.angleTo(getEndpoint());
+ double a = data.center.angleTo(ret);
+
+ if (!RS_Math::isAngleBetween(a, a1, a2, data.reversed))
+ ret = Vector(false);
+ }
}
+
+ return ret;
}
-double RS_Ellipse::getEllipseAngle(const Vector& pos) {
- Vector m = pos;
- m.rotate(data.center, -data.majorP.angle());
- Vector v = m-data.center;
- v.scale(Vector(1.0, 1.0/data.ratio));
- return v.angle();
+/**
+ * @param tolerance Tolerance.
+ *
+ * @retval true if the given point is on this entity.
+ * @retval false otherwise
+ */
+bool RS_Ellipse::isPointOnEntity(const Vector & coord, double tolerance)
+{
+ double dist = getDistanceToPoint(coord, NULL, RS2::ResolveNone);
+ return (dist <= tolerance);
}
+Vector RS_Ellipse::getNearestCenter(const Vector & coord, double * dist)
+{
+ if (dist != NULL)
+ *dist = coord.distanceTo(data.center);
+ return data.center;
+}
+/**
+ * @todo Implement this.
+ */
+Vector RS_Ellipse::getNearestMiddle(const Vector & /*coord*/, double * dist)
+{
+ if (dist != NULL)
+ *dist = RS_MAXDOUBLE;
+ return Vector(false);
+}
+
+Vector RS_Ellipse::getNearestDist(double /*distance*/, const Vector & /*coord*/, double * dist)
+{
+ if (dist != NULL)
+ *dist = RS_MAXDOUBLE;
+ return Vector(false);
+}
+
+double RS_Ellipse::getDistanceToPoint(const Vector & coord, RS_Entity * * entity, RS2::ResolveLevel, double /*solidDist*/)
+{
+ double dist = RS_MAXDOUBLE;
+ getNearestPointOnEntity(coord, true, &dist, entity);
+
+ return dist;
+}
+
+void RS_Ellipse::move(Vector offset)
+{
+ data.center.move(offset);
+ //calculateEndpoints();
+ calculateBorders();
+}
-void RS_Ellipse::scale(Vector center, Vector factor) {
- data.center.scale(center, factor);
- data.majorP.scale(factor);
- //calculateEndpoints();
- calculateBorders();
+void RS_Ellipse::rotate(Vector center, double angle)
+{
+ data.center.rotate(center, angle);
+ data.majorP.rotate(angle);
+ //calculateEndpoints();
+ calculateBorders();
}
+void RS_Ellipse::scale(Vector center, Vector factor)
+{
+ data.center.scale(center, factor);
+ data.majorP.scale(factor);
+ //calculateEndpoints();
+ calculateBorders();
+}
/**
* @todo deal with angles correctly
*/
-void RS_Ellipse::mirror(Vector axisPoint1, Vector axisPoint2) {
- Vector mp = data.center + data.majorP;
+void RS_Ellipse::mirror(Vector axisPoint1, Vector axisPoint2)
+{
+ Vector mp = data.center + data.majorP;
- data.center.mirror(axisPoint1, axisPoint2);
- mp.mirror(axisPoint1, axisPoint2);
+ data.center.mirror(axisPoint1, axisPoint2);
+ mp.mirror(axisPoint1, axisPoint2);
- data.majorP = mp - data.center;
+ data.majorP = mp - data.center;
- double a = axisPoint1.angleTo(axisPoint2);
+ double a = axisPoint1.angleTo(axisPoint2);
- Vector vec;
- vec.setPolar(1.0, data.angle1);
- vec.mirror(Vector(0.0,0.0), axisPoint2-axisPoint1);
- data.angle1 = vec.angle() - 2*a;
+ Vector vec;
+ vec.setPolar(1.0, data.angle1);
+ vec.mirror(Vector(0.0, 0.0), axisPoint2 - axisPoint1);
+ data.angle1 = vec.angle() - 2 * a;
- vec.setPolar(1.0, data.angle2);
- vec.mirror(Vector(0.0,0.0), axisPoint2-axisPoint1);
- data.angle2 = vec.angle() - 2*a;
+ vec.setPolar(1.0, data.angle2);
+ vec.mirror(Vector(0.0, 0.0), axisPoint2 - axisPoint1);
+ data.angle2 = vec.angle() - 2 * a;
- data.reversed = (!data.reversed);
+ data.reversed = (!data.reversed);
- //calculateEndpoints();
- calculateBorders();
+ //calculateEndpoints();
+ calculateBorders();
}
-
-
-void RS_Ellipse::moveRef(const Vector& ref, const Vector& offset) {
+void RS_Ellipse::moveRef(const Vector & ref, const Vector & offset)
+{
Vector startpoint = getStartpoint();
Vector endpoint = getEndpoint();
- if (ref.distanceTo(startpoint)<1.0e-4) {
- moveStartpoint(startpoint+offset);
- }
- if (ref.distanceTo(endpoint)<1.0e-4) {
- moveEndpoint(endpoint+offset);
- }
-}
+ if (ref.distanceTo(startpoint) < 1.0e-4)
+ moveStartpoint(startpoint + offset);
+
+ if (ref.distanceTo(endpoint) < 1.0e-4)
+ moveEndpoint(endpoint + offset);
+}
-//void RS_Ellipse::draw(RS_Painter* painter, RS_GraphicView* view, double /*patternOffset*/) {
-void RS_Ellipse::draw(PaintInterface * painter, RS_GraphicView * view, double /*patternOffset*/)
+void RS_Ellipse::draw(PaintInterface * painter, GraphicView * view, double /*patternOffset*/)
{
- if (painter == NULL || view == NULL)
+ if (!painter || !view)
return;
- if (getPen().getLineType()==RS2::SolidLine || isSelected()
- || view->getDrawingMode()==RS2::ModePreview)
- {
+ if (getPen().getLineType() == RS2::SolidLine || isSelected()
+ || view->getDrawingMode() == RS2::ModePreview)
painter->drawEllipse(view->toGui(getCenter()),
getMajorRadius() * view->getFactor().x,
getMinorRadius() * view->getFactor().x,
getAngle(), getAngle1(), getAngle2(), isReversed());
- }
else
{
double styleFactor = getStyleFactor(view);
RS_LineTypePattern * pat;
if (isSelected())
- {
pat = &patternSelected;
- }
else
- {
pat = view->getPattern(getPen().getLineType());
- }
if (pat == NULL)
- {
return;
- }
// Pen to draw pattern is always solid:
RS_Pen pen = painter->getPen();
do
{
curR = sqrt(RS_Math::pow(getMinorRadius() * cos(curA), 2.0)
- + RS_Math::pow(getMajorRadius() * sin(curA), 2.0));
+ + RS_Math::pow(getMajorRadius() * sin(curA), 2.0));
if (curR > 1.0e-6)
{
if (pat->pattern[i] * styleFactor > 0.0)
{
- if (tot+fabs(da[i])<length)
- {
+ if (tot + fabs(da[i]) < length)
painter->drawEllipse(cp, r1, r2, getAngle(), curA, curA + da[i], false);
- }
else
- {
painter->drawEllipse(cp, r1, r2, getAngle(), curA, getAngle2(), false);
- }
}
}
- curA+=da[i];
- tot+=fabs(da[i]);
- done=tot>length;
+ curA += da[i];
+ tot += fabs(da[i]);
+ done = tot > length;
i++;
if (i >= pat->num)
- {
- i=0;
- }
+ i = 0;
}
- while(!done);
+ while (!done);
delete[] da;
}
/**
* Dumps the point's data to stdout.
*/
-std::ostream& operator << (std::ostream& os, const RS_Ellipse& a) {
- os << " Ellipse: " << a.data << "\n";
- return os;
+std::ostream & operator<<(std::ostream & os, const RS_Ellipse & a)
+{
+ os << " Ellipse: " << a.data << "\n";
+ return os;
}