]> Shamusworld >> Repos - architektonas/blobdiff - src/base/rs_ellipse.cpp
Refactoring: Moved RS_GraphicView to GraphicView.
[architektonas] / src / base / rs_ellipse.cpp
index 8300a182891da9fe95530e41d3a6082411cf7819..380df86f83358d323c0388728460fed898c6bbfa 100644 (file)
 
 #include "rs_ellipse.h"
 
-#include "rs_graphic.h"
-#include "rs_graphicview.h"
+#include "drawing.h"
+#include "graphicview.h"
 #include "rs_information.h"
+#include "rs_linetypepattern.h"
 #include "paintintf.h"
 
 /**
@@ -29,425 +30,559 @@ RS_Ellipse::RS_Ellipse(RS_EntityContainer * parent, const RS_EllipseData & d):
        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);
@@ -465,18 +600,12 @@ void RS_Ellipse::draw(PaintInterface * painter, RS_GraphicView * view, double /*
                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();
@@ -503,7 +632,7 @@ void RS_Ellipse::draw(PaintInterface * painter, RS_GraphicView * view, double /*
                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)
                        {
@@ -511,29 +640,23 @@ void RS_Ellipse::draw(PaintInterface * painter, RS_GraphicView * view, double /*
 
                                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;
        }
@@ -542,8 +665,9 @@ void RS_Ellipse::draw(PaintInterface * painter, RS_GraphicView * view, double /*
 /**
  * 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;
 }