X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fbase%2Frs_circle.cpp;h=5eebd9a6262479e72a1074ebfa6e15029ffb6e15;hb=27d4a138d23453e93a833e9347444b828a971cb4;hp=2f5532d778c0a28fd3430b6b8c04454d45b39685;hpb=16ce54abf01ca3032e42a5bb11a4afcf9014dcca;p=architektonas diff --git a/src/base/rs_circle.cpp b/src/base/rs_circle.cpp index 2f5532d..5eebd9a 100644 --- a/src/base/rs_circle.cpp +++ b/src/base/rs_circle.cpp @@ -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" /** @@ -25,12 +26,102 @@ 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; inum; ++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])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; }