]> Shamusworld >> Repos - architektonas/blobdiff - src/base/rs_circle.cpp
Refactoring: Moved RS_GraphicView to GraphicView.
[architektonas] / src / base / rs_circle.cpp
index 2f5532d778c0a28fd3430b6b8c04454d45b39685..5eebd9a6262479e72a1074ebfa6e15029ffb6e15 100644 (file)
@@ -16,7 +16,8 @@
 
 #include "rs_constructionline.h"
 #include "rs_information.h"
-#include "rs_graphicview.h"
+#include "rs_linetypepattern.h"
+#include "graphicview.h"
 #include "paintintf.h"
 
 /**
 RS_Circle::RS_Circle(RS_EntityContainer * parent, const RS_CircleData & d):
        RS_AtomicEntity(parent), data(d)
 {
-    calculateBorders();
+       calculateBorders();
+}
+
+/*virtual*/ RS_Circle::~RS_Circle()
+{
+}
+
+/*virtual*/ RS_Entity * RS_Circle::clone()
+{
+       RS_Circle * c = new RS_Circle(*this);
+       c->initId();
+       return c;
+}
+
+/**    @return RS2::EntityCircle */
+/*virtual*/ RS2::EntityType RS_Circle::rtti() const
+{
+       return RS2::EntityCircle;
+}
+
+/** @return true */
+/*virtual*/ bool RS_Circle::isEdge() const
+{
+       return true;
+}
+
+/** @return Copy of data that defines the circle. **/
+RS_CircleData RS_Circle::getData()
+{
+       return data;
+}
+
+VectorSolutions RS_Circle::getRefPoints()
+{
+       Vector v1(data.radius, 0.0);
+       Vector v2(0.0, data.radius);
+
+       VectorSolutions ret(data.center, data.center + v1, data.center + v2, data.center - v1, data.center - v2);
+       return ret;
+}
+
+/*virtual*/ Vector RS_Circle::getStartpoint() const
+{
+       return data.center + Vector(data.radius, 0.0);
+}
+
+/*virtual*/ Vector RS_Circle::getEndpoint() const
+{
+       return data.center + Vector(data.radius, 0.0);
+}
+
+/**
+       * @return Direction 1. The angle at which the arc starts at
+       * the startpoint.
+       */
+double RS_Circle::getDirection1() const
+{
+       return M_PI / 2.0;
+}
+
+/**
+       * @return Direction 2. The angle at which the arc starts at
+       * the endpoint.
+       */
+double RS_Circle::getDirection2() const
+{
+       return M_PI / 2.0 * 3.0;
+}
+
+/** @return The center point (x) of this arc */
+Vector RS_Circle::getCenter()
+{
+       return data.center;
+}
+
+/** Sets new center. */
+void RS_Circle::setCenter(const Vector & c)
+{
+       data.center = c;
+}
+
+/** @return The radius of this arc */
+double RS_Circle::getRadius()
+{
+       return data.radius;
+}
+
+/** Sets new radius. */
+void RS_Circle::setRadius(double r)
+{
+       data.radius = r;
 }
 
 void RS_Circle::calculateBorders()
 {
-       Vector r(data.radius,data.radius,0.0);
+       Vector r(data.radius, data.radius, 0.0);
        minV = data.center - r;
        maxV = data.center + r;
 }
@@ -38,60 +129,63 @@ void RS_Circle::calculateBorders()
 /**
  * @return Angle length in rad.
  */
-double RS_Circle::getAngleLength() const {
-    return 2*M_PI;
+double RS_Circle::getAngleLength() const
+{
+       return 2 * M_PI;
 }
 
-
-
 /**
  * @return Length of the circle which is the circumference.
  */
-double RS_Circle::getLength() {
-       return 2*M_PI*data.radius;
+double RS_Circle::getLength()
+{
+       return 2 * M_PI * data.radius;
 }
 
-
 /**
  * Creates this circle from a center point and a radius.
  *
  * @param c Center.
  * @param r Radius
  */
-bool RS_Circle::createFromCR(const Vector& c, double r) {
-    if (fabs(r)>RS_TOLERANCE) {
-        data.radius = fabs(r);
-        data.center = c;
-        return true;
-    } else {
-        RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Circle::createFromCR(): "
-                        "Cannot create a circle with radius 0.0.");
-        return false;
-    }
+bool RS_Circle::createFromCR(const Vector & c, double r)
+{
+       if (fabs(r) > RS_TOLERANCE)
+       {
+               data.radius = fabs(r);
+               data.center = c;
+               return true;
+       }
+       else
+       {
+               RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Circle::createFromCR(): "
+                       "Cannot create a circle with radius 0.0.");
+               return false;
+       }
 }
 
-
-
 /**
  * Creates this circle from two opposite points.
  *
  * @param p1 1st point.
  * @param p2 2nd point.
  */
-bool RS_Circle::createFrom2P(const Vector& p1, const Vector& p2) {
-    if (p1.distanceTo(p2)>RS_TOLERANCE) {
-        data.radius = p1.distanceTo(p2)/2.0;
-        data.center = p1 + (p2-p1)/2.0;
-        return true;
-    } else {
-        RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Circle::createFrom2P(): "
-                        "Cannot create a circle with radius 0.0.");
-        return false;
-    }
+bool RS_Circle::createFrom2P(const Vector & p1, const Vector & p2)
+{
+       if (p1.distanceTo(p2) > RS_TOLERANCE)
+       {
+               data.radius = p1.distanceTo(p2) / 2.0;
+               data.center = p1 + (p2 - p1) / 2.0;
+               return true;
+       }
+       else
+       {
+               RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Circle::createFrom2P(): "
+                       "Cannot create a circle with radius 0.0.");
+               return false;
+       }
 }
 
-
-
 /**
  * Creates this circle from 3 given points which define the circle line.
  *
@@ -99,290 +193,256 @@ bool RS_Circle::createFrom2P(const Vector& p1, const Vector& p2) {
  * @param p2 2nd point.
  * @param p3 3rd point.
  */
-bool RS_Circle::createFrom3P(const Vector& p1, const Vector& p2,
-                             const Vector& p3) {
-    if (p1.distanceTo(p2)>RS_TOLERANCE &&
-            p2.distanceTo(p3)>RS_TOLERANCE &&
-            p3.distanceTo(p1)>RS_TOLERANCE) {
-
-        // middle points between 3 points:
-        Vector mp1, mp2;
-        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);
-
-        VectorSolutions sol =
-            RS_Information::getIntersection(&midLine1, &midLine2);
-
-        data.center = sol.get(0);
-        data.radius = data.center.distanceTo(p3);
-
-        if (sol.get(0).valid && data.radius<1.0e14 && data.radius>RS_TOLERANCE) {
-            return true;
-        } else {
-            RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Circle::createFrom3P(): "
-                            "Cannot create a circle with inf radius.");
-            return false;
-        }
-    } else {
-        RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Circle::createFrom3P(): "
-                        "Cannot create a circle with radius 0.0.");
-        return false;
-    }
-}
-
-
-
-VectorSolutions RS_Circle::getRefPoints() {
-       Vector v1(data.radius, 0.0);
-       Vector v2(0.0, data.radius);
-
-       VectorSolutions ret(data.center,
-               data.center+v1, data.center+v2,
-               data.center-v1, data.center-v2);
-       return ret;
+bool RS_Circle::createFrom3P(const Vector & p1, const Vector & p2, const Vector & p3)
+{
+       if (p1.distanceTo(p2) > RS_TOLERANCE
+           && p2.distanceTo(p3) > RS_TOLERANCE
+           && p3.distanceTo(p1) > RS_TOLERANCE)
+       {
+               // middle points between 3 points:
+               Vector mp1, mp2;
+               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);
+
+               VectorSolutions sol =
+                       RS_Information::getIntersection(&midLine1, &midLine2);
+
+               data.center = sol.get(0);
+               data.radius = data.center.distanceTo(p3);
+
+               if (sol.get(0).valid && data.radius < 1.0e14 && data.radius > RS_TOLERANCE)
+                       return true;
+               else
+               {
+                       RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Circle::createFrom3P(): "
+                               "Cannot create a circle with inf radius.");
+                       return false;
+               }
+       }
+       else
+       {
+               RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Circle::createFrom3P(): "
+                       "Cannot create a circle with radius 0.0.");
+               return false;
+       }
 }
 
-
 /**
  * @return Always an invalid vector.
  */
-Vector RS_Circle::getNearestEndpoint(const Vector& /*coord*/, double* dist) {
-    if (dist!=NULL) {
-        *dist = RS_MAXDOUBLE;
-    }
-    return Vector(false);
+Vector RS_Circle::getNearestEndpoint(const Vector & /*coord*/, double * dist)
+{
+       if (dist != NULL)
+               *dist = RS_MAXDOUBLE;
+       return Vector(false);
 }
 
+Vector RS_Circle::getNearestPointOnEntity(const Vector & coord, bool /*onEntity*/, double * dist, RS_Entity ** entity)
+{
+       Vector vec(false);
 
+       if (entity != NULL)
+               *entity = this;
 
-Vector RS_Circle::getNearestPointOnEntity(const Vector& coord,
-        bool /*onEntity*/, double* dist, RS_Entity** entity) {
-
-    Vector vec(false);
-    if (entity!=NULL) {
-        *entity = this;
-    }
-
-    double angle = (coord-data.center).angle();
-    vec.setPolar(data.radius, angle);
-    vec+=data.center;
+       double angle = (coord - data.center).angle();
+       vec.setPolar(data.radius, angle);
+       vec += data.center;
 
-    if (dist!=NULL) {
-        *dist = fabs((vec-data.center).magnitude()-data.radius);
-    }
+       if (dist != NULL)
+               *dist = fabs((vec - data.center).magnitude() - data.radius);
 
-    return vec;
+       return vec;
 }
 
-
-
-Vector RS_Circle::getNearestCenter(const Vector& coord,
-                                      double* dist) {
-    if (dist!=NULL) {
-        *dist = coord.distanceTo(data.center);
-    }
-    return data.center;
+Vector RS_Circle::getNearestCenter(const Vector & coord, double * dist)
+{
+       if (dist != NULL)
+               *dist = coord.distanceTo(data.center);
+       return data.center;
 }
 
-
-
-Vector RS_Circle::getNearestMiddle(const Vector& /*coord*/,
-                                      double* dist) {
-    if (dist!=NULL) {
-        *dist = RS_MAXDOUBLE;
-    }
-    return Vector(false);
+Vector RS_Circle::getNearestMiddle(const Vector & /*coord*/, double * dist)
+{
+       if (dist != NULL)
+               *dist = RS_MAXDOUBLE;
+       return Vector(false);
 }
 
-
-
-Vector RS_Circle::getNearestDist(double /*distance*/,
-                                    const Vector& /*coord*/,
-                                    double* dist) {
-
-    if (dist!=NULL) {
-        *dist = RS_MAXDOUBLE;
-    }
-    return Vector(false);
+Vector RS_Circle::getNearestDist(double /*distance*/, const Vector & /*coord*/, double * dist)
+{
+       if (dist != NULL)
+               *dist = RS_MAXDOUBLE;
+       return Vector(false);
 }
 
-Vector RS_Circle::getNearestDist(double /*distance*/,
-                                  bool /*startp*/) {
-
-    return Vector(false);
+Vector RS_Circle::getNearestDist(double /*distance*/, bool /*startp*/)
+{
+       return Vector(false);
 }
 
+double RS_Circle::getDistanceToPoint(const Vector & coord, RS_Entity * * entity, RS2::ResolveLevel, double)
+{
+       if (entity != NULL)
+               *entity = this;
 
-
-double RS_Circle::getDistanceToPoint(const Vector& coord,
-                                     RS_Entity** entity,
-                                     RS2::ResolveLevel, double) {
-    if (entity!=NULL) {
-        *entity = this;
-    }
-
-    return fabs((coord-data.center).magnitude() - data.radius);
+       return fabs((coord - data.center).magnitude() - data.radius);
 }
 
-
-
-void RS_Circle::move(Vector offset) {
-    data.center.move(offset);
-    calculateBorders();
+void RS_Circle::move(Vector offset)
+{
+       data.center.move(offset);
+       calculateBorders();
 }
 
-
-
-void RS_Circle::rotate(Vector center, double angle) {
-    data.center.rotate(center, angle);
-    calculateBorders();
+void RS_Circle::rotate(Vector center, double angle)
+{
+       data.center.rotate(center, angle);
+       calculateBorders();
 }
 
-
-
-void RS_Circle::scale(Vector center, Vector factor) {
-    data.center.scale(center, factor);
-    data.radius *= factor.x;
-    calculateBorders();
+void RS_Circle::scale(Vector center, Vector factor)
+{
+       data.center.scale(center, factor);
+       data.radius *= factor.x;
+       calculateBorders();
 }
 
-
-
-void RS_Circle::mirror(Vector axisPoint1, Vector axisPoint2) {
+void RS_Circle::mirror(Vector axisPoint1, Vector axisPoint2)
+{
        data.center.mirror(axisPoint1, axisPoint2);
-    calculateBorders();
+       calculateBorders();
 }
 
-void RS_Circle::draw(PaintInterface * painter, RS_GraphicView * view, double /*patternOffset*/)
+void RS_Circle::draw(PaintInterface * painter, GraphicView * view, double /*patternOffset*/)
 {
-    if (painter == NULL || view == NULL)
-        return;
-
-    // simple style-less lines
-    if (getPen().getLineType()==RS2::SolidLine ||
-            isSelected() ||
-            view->getDrawingMode()==RS2::ModePreview) {
-
-        painter->drawArc(view->toGui(getCenter()),
-                         getRadius() * view->getFactor().x,
-                         0.0, 2*M_PI,
-                         false);
-    } else {
+       if (painter == NULL || view == NULL)
+               return;
+
+       // simple style-less lines
+       if (getPen().getLineType() == RS2::SolidLine
+           || isSelected()
+           || view->getDrawingMode() == RS2::ModePreview)
+
+               painter->drawArc(view->toGui(getCenter()),
+                       getRadius() * view->getFactor().x,
+                       0.0, 2 * M_PI,
+                       false);
+       else
+       {
                double styleFactor = getStyleFactor(view);
-               if (styleFactor<0.0) {
-               painter->drawArc(view->toGui(getCenter()),
-                         getRadius() * view->getFactor().x,
-                         0.0, 2*M_PI,
-                         false);
+
+               if (styleFactor < 0.0)
+               {
+                       painter->drawArc(view->toGui(getCenter()),
+                               getRadius() * view->getFactor().x,
+                               0.0, 2 * M_PI,
+                               false);
                        return;
                }
 
-        // Pattern:
-        RS_LineTypePattern* pat;
-        if (isSelected()) {
-            pat = &patternSelected;
-        } else {
-            pat = view->getPattern(getPen().getLineType());
-        }
+               // Pattern:
+               RS_LineTypePattern * pat;
 
-        if (pat==NULL) {
-            return;
-        }
+               if (isSelected())
+                       pat = &patternSelected;
+               else
+                       pat = view->getPattern(getPen().getLineType());
 
-               if (getRadius()<1.0e-6) {
+               if (pat == NULL)
                        return;
+
+               if (getRadius() < 1.0e-6)
+                       return;
+
+               // Pen to draw pattern is always solid:
+               RS_Pen pen = painter->getPen();
+               pen.setLineType(RS2::SolidLine);
+               painter->setPen(pen);
+
+               double * da; // array of distances in x.
+               int i;  // index counter
+
+               double length = getAngleLength();
+
+               // create pattern:
+               da = new double[pat->num];
+
+               for (i = 0; i < pat->num; ++i)
+                       da[i] = fabs(pat->pattern[i] * styleFactor) / getRadius();
+
+               double tot = 0.0;
+               i = 0;
+               bool done = false;
+               double curA = 0.0;
+               //double cx = getCenter().x * factor.x + offsetX;
+               //double cy = - a->getCenter().y * factor.y + getHeight() - offsetY;
+               Vector cp = view->toGui(getCenter());
+               double r = getRadius() * view->getFactor().x;
+
+               do
+               {
+                       if (pat->pattern[i] * styleFactor > 0.0)
+                       {
+                               if (tot + fabs(da[i]) < length)
+                                       painter->drawArc(cp, r,
+                                               curA,
+                                               curA + da[i],
+                                               false);
+                               else
+                                       painter->drawArc(cp, r,
+                                               curA,
+                                               2 * M_PI,
+                                               false);
+                       }
+                       curA += da[i];
+                       tot += fabs(da[i]);
+                       done = tot > length;
+
+                       i++;
+
+                       if (i >= pat->num)
+                               i = 0;
                }
+               while (!done);
 
-        // Pen to draw pattern is always solid:
-        RS_Pen pen = painter->getPen();
-        pen.setLineType(RS2::SolidLine);
-        painter->setPen(pen);
-
-        double* da;     // array of distances in x.
-        int i;          // index counter
-
-        double length = getAngleLength();
-
-        // create pattern:
-        da = new double[pat->num];
-
-        for (i=0; i<pat->num; ++i) {
-            da[i] = fabs(pat->pattern[i] * styleFactor)/getRadius();
-        }
-
-        double tot=0.0;
-        i=0;
-        bool done = false;
-        double curA = 0.0;
-        //double cx = getCenter().x * factor.x + offsetX;
-        //double cy = - a->getCenter().y * factor.y + getHeight() - offsetY;
-        Vector cp = view->toGui(getCenter());
-        double r = getRadius() * view->getFactor().x;
-
-        do {
-            if (pat->pattern[i] * styleFactor > 0.0) {
-                if (tot+fabs(da[i])<length) {
-                    painter->drawArc(cp, r,
-                                     curA,
-                                     curA + da[i],
-                                     false);
-                } else {
-                    painter->drawArc(cp, r,
-                                     curA,
-                                     2*M_PI,
-                                     false);
-                }
-            }
-            curA+=da[i];
-            tot+=fabs(da[i]);
-            done=tot>length;
-
-            i++;
-            if (i>=pat->num) {
-                i=0;
-            }
-        } while(!done);
-
-        delete[] da;
-    }
-}
-
-
-
-void RS_Circle::moveRef(const Vector& ref, const Vector& offset) {
+               delete[] da;
+       }
+}
+
+void RS_Circle::moveRef(const Vector & ref, const Vector & offset)
+{
        Vector v1(data.radius, 0.0);
        Vector v2(0.0, data.radius);
 
-    if (ref.distanceTo(data.center + v1)<1.0e-4) {
+       if (ref.distanceTo(data.center + v1) < 1.0e-4)
                data.radius = data.center.distanceTo(data.center + v1 + offset);
-    } else if (ref.distanceTo(data.center + v2)<1.0e-4) {
+       else if (ref.distanceTo(data.center + v2) < 1.0e-4)
                data.radius = data.center.distanceTo(data.center + v2 + offset);
-    } else if (ref.distanceTo(data.center - v1)<1.0e-4) {
+       else if (ref.distanceTo(data.center - v1) < 1.0e-4)
                data.radius = data.center.distanceTo(data.center - v1 + offset);
-    } else if (ref.distanceTo(data.center - v2)<1.0e-4) {
+       else if (ref.distanceTo(data.center - v2) < 1.0e-4)
                data.radius = data.center.distanceTo(data.center - v2 + offset);
-       }
 }
 
-
 /**
  * Dumps the circle's data to stdout.
  */
-std::ostream& operator << (std::ostream& os, const RS_Circle& a) {
-    os << " Circle: " << a.data << "\n";
-    return os;
+std::ostream & operator<<(std::ostream & os, const RS_Circle & a)
+{
+       os << " Circle: " << a.data << "\n";
+       return os;
 }