#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;
}
/**
* @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.
*
* @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;
}