// Who When What
// --- ---------- -----------------------------------------------------------
// JLH 05/28/2010 Added this text. :-)
+// JLH 06/16/2010 Moved implementation from header file to this file
//
#include "rs_arc.h"
#include "rs_linetypepattern.h"
#include "rs_information.h"
#include "rs_math.h"
-#include "rs_graphicview.h"
-#include "paintintf.h"
+#include "graphicview.h"
+#include "paintinterface.h"
/**
* Default constructor.
*/
-RS_Arc::RS_Arc(RS_EntityContainer* parent,
- const RS_ArcData& d)
- : RS_AtomicEntity(parent), data(d) {
- calculateEndpoints();
- calculateBorders();
+RS_Arc::RS_Arc(RS_EntityContainer * parent, const RS_ArcData & d):
+ RS_AtomicEntity(parent), data(d)
+{
+ calculateEndpoints();
+ calculateBorders();
+}
+
+/*virtual*/ RS_Arc::~RS_Arc()
+{
+}
+
+/*virtual*/ RS_Entity * RS_Arc::clone()
+{
+ RS_Arc * a = new RS_Arc(*this);
+ a->initId();
+ return a;
+}
+
+/** @return RS2::EntityArc */
+/*virtual*/ RS2::EntityType RS_Arc::rtti() const
+{
+ return RS2::EntityArc;
+}
+
+/** @return true */
+/*virtual*/ bool RS_Arc::isEdge() const
+{
+ return true;
+}
+
+/** @return Copy of data that defines the arc. **/
+RS_ArcData RS_Arc::getData() const
+{
+ return data;
+}
+
+/*virtual*/ VectorSolutions RS_Arc::getRefPoints()
+{
+ VectorSolutions ret(startpoint, endpoint, data.center);
+ return ret;
+}
+
+/** Sets new arc parameters. **/
+void RS_Arc::setData(RS_ArcData d)
+{
+ data = d;
+}
+
+/** @return The center point (x) of this arc */
+Vector RS_Arc::getCenter() const
+{
+ return data.center;
+}
+
+/** Sets new center. */
+void RS_Arc::setCenter(const Vector & c)
+{
+ data.center = c;
+}
+
+/** @return The radius of this arc */
+double RS_Arc::getRadius() const
+{
+ return data.radius;
+}
+
+/** Sets new radius. */
+void RS_Arc::setRadius(double r)
+{
+ data.radius = r;
+}
+
+/** @return The start angle of this arc */
+double RS_Arc::getAngle1() const
+{
+ return data.angle1;
+}
+
+/** Sets new start angle. */
+void RS_Arc::setAngle1(double a1)
+{
+ data.angle1 = a1;
+}
+
+/** @return The end angle of this arc */
+double RS_Arc::getAngle2() const
+{
+ return data.angle2;
+}
+
+/** Sets new end angle. */
+void RS_Arc::setAngle2(double a2)
+{
+ data.angle2 = a2;
}
+/**
+ * @return Direction 1. The angle at which the arc starts at
+ * the startpoint.
+ */
+double RS_Arc::getDirection1() const
+{
+ if (!data.reversed)
+ return RS_Math::correctAngle(data.angle1 + M_PI / 2.0);
+
+ return RS_Math::correctAngle(data.angle1 - M_PI / 2.0);
+}
+
+/**
+ * @return Direction 2. The angle at which the arc starts at
+ * the endpoint.
+ */
+double RS_Arc::getDirection2() const
+{
+ if (!data.reversed)
+ return RS_Math::correctAngle(data.angle2 - M_PI / 2.0);
+
+ return RS_Math::correctAngle(data.angle2 + M_PI / 2.0);
+}
+
+/**
+ * @retval true if the arc is reversed (clockwise),
+ * @retval false otherwise
+ */
+bool RS_Arc::isReversed() const
+{
+ return data.reversed;
+}
+
+/** sets the reversed status. */
+void RS_Arc::setReversed(bool r)
+{
+ data.reversed = r;
+}
+
+/** @return Start point of the entity. */
+/*virtual*/ Vector RS_Arc::getStartpoint() const
+{
+ return startpoint;
+}
+/** @return End point of the entity. */
+/*virtual*/ Vector RS_Arc::getEndpoint() const
+{
+ return endpoint;
+}
/**
* Creates this arc from 3 given points which define the arc line.
* @param p2 2nd point.
* @param p3 3rd point.
*/
-bool RS_Arc::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);
- data.angle1 = data.center.angleTo(p1);
- data.angle2 = data.center.angleTo(p3);
- data.reversed = RS_Math::isAngleBetween(data.center.angleTo(p2),
- data.angle1, data.angle2, true);
-
- if (sol.get(0).valid && data.radius<1.0e14 &&
- data.radius>RS_TOLERANCE) {
- calculateEndpoints();
- calculateBorders();
- return true;
- } else {
- RS_DEBUG->print("RS_Arc::createFrom3P(): "
- "Cannot create an arc with inf radius.");
- return false;
- }
- } else {
- RS_DEBUG->print("RS_Arc::createFrom3P(): "
- "Cannot create an arc with radius 0.0.");
- return false;
- }
+bool RS_Arc::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);
+ data.angle1 = data.center.angleTo(p1);
+ data.angle2 = data.center.angleTo(p3);
+ data.reversed = RS_Math::isAngleBetween(data.center.angleTo(p2),
+ data.angle1, data.angle2, true);
+
+ if (sol.get(0).valid && data.radius < 1.0e14
+ && data.radius > RS_TOLERANCE)
+ {
+ calculateEndpoints();
+ calculateBorders();
+ return true;
+ }
+ else
+ {
+ RS_DEBUG->print("RS_Arc::createFrom3P(): "
+ "Cannot create an arc with inf radius.");
+ return false;
+ }
+ }
+ else
+ {
+ RS_DEBUG->print("RS_Arc::createFrom3P(): "
+ "Cannot create an arc with radius 0.0.");
+ return false;
+ }
}
-
-
/**
* Creates an arc from its startpoint, endpoint, start direction (angle)
* and radius.
* @retval true Successfully created arc
* @retval false Cannot creats arc (radius to small or endpoint to far away)
*/
-bool RS_Arc::createFrom2PDirectionRadius(const Vector& startPoint,
- const Vector& endPoint,
- double direction1, double radius) {
+bool RS_Arc::createFrom2PDirectionRadius(const Vector & startPoint, const Vector & endPoint, double direction1, double radius)
+{
+ Vector ortho;
+ ortho.setPolar(radius, direction1 + M_PI / 2.0);
+ Vector center1 = startPoint + ortho;
+ Vector center2 = startPoint - ortho;
- Vector ortho;
- ortho.setPolar(radius, direction1 + M_PI/2.0);
- Vector center1 = startPoint + ortho;
- Vector center2 = startPoint - ortho;
+ if (center1.distanceTo(endPoint) < center2.distanceTo(endPoint))
+ data.center = center1;
+ else
+ data.center = center2;
- if (center1.distanceTo(endPoint) < center2.distanceTo(endPoint)) {
- data.center = center1;
- } else {
- data.center = center2;
- }
+ data.radius = radius;
+ data.angle1 = data.center.angleTo(startPoint);
+ data.angle2 = data.center.angleTo(endPoint);
+ data.reversed = false;
- data.radius = radius;
- data.angle1 = data.center.angleTo(startPoint);
- data.angle2 = data.center.angleTo(endPoint);
- data.reversed = false;
+ double diff = RS_Math::correctAngle(getDirection1() - direction1);
- double diff = RS_Math::correctAngle(getDirection1()-direction1);
- if (fabs(diff-M_PI)<1.0e-1) {
- data.reversed = true;
- }
+ if (fabs(diff - M_PI) < 1.0e-1)
+ data.reversed = true;
- calculateEndpoints();
- calculateBorders();
+ calculateEndpoints();
+ calculateBorders();
- return true;
+ return true;
}
-
-
/**
* Creates an arc from its startpoint, endpoint and bulge.
*/
-bool RS_Arc::createFrom2PBulge(const Vector& startPoint, const Vector& endPoint,
- double bulge) {
- data.reversed = (bulge<0.0);
- double alpha = atan(bulge)*4.0;
+bool RS_Arc::createFrom2PBulge(const Vector & startPoint, const Vector & endPoint, double bulge)
+{
+ data.reversed = (bulge < 0.0);
+ double alpha = atan(bulge) * 4.0;
- Vector middle = (startPoint+endPoint)/2.0;
- double dist = startPoint.distanceTo(endPoint)/2.0;
+ Vector middle = (startPoint + endPoint) / 2.0;
+ double dist = startPoint.distanceTo(endPoint) / 2.0;
- // alpha can't be 0.0 at this point
- data.radius = fabs(dist / sin(alpha/2.0));
+ // alpha can't be 0.0 at this point
+ data.radius = fabs(dist / sin(alpha / 2.0));
- double wu = fabs(RS_Math::pow(data.radius, 2.0) - RS_Math::pow(dist, 2.0));
- double h = sqrt(wu);
- double angle = startPoint.angleTo(endPoint);
+ double wu = fabs(RS_Math::pow(data.radius, 2.0) - RS_Math::pow(dist, 2.0));
+ double h = sqrt(wu);
+ double angle = startPoint.angleTo(endPoint);
- if (bulge>0.0) {
- angle+=M_PI/2.0;
- } else {
- angle-=M_PI/2.0;
- }
+ if (bulge > 0.0)
+ angle += M_PI / 2.0;
+ else
+ angle -= M_PI / 2.0;
- if (fabs(alpha)>M_PI) {
- h*=-1.0;
- }
+ if (fabs(alpha) > M_PI)
+ h *= -1.0;
- data.center.setPolar(h, angle);
- data.center+=middle;
- data.angle1 = data.center.angleTo(startPoint);
- data.angle2 = data.center.angleTo(endPoint);
+ data.center.setPolar(h, angle);
+ data.center += middle;
+ data.angle1 = data.center.angleTo(startPoint);
+ data.angle2 = data.center.angleTo(endPoint);
- calculateEndpoints();
- calculateBorders();
+ calculateEndpoints();
+ calculateBorders();
return true;
}
-
-
/**
* Recalculates the endpoints using the angles and the radius.
*/
-void RS_Arc::calculateEndpoints() {
- startpoint.set(data.center.x + cos(data.angle1) * data.radius,
- data.center.y + sin(data.angle1) * data.radius);
- endpoint.set(data.center.x + cos(data.angle2) * data.radius,
- data.center.y + sin(data.angle2) * data.radius);
+void RS_Arc::calculateEndpoints()
+{
+ startpoint.set(data.center.x + cos(data.angle1) * data.radius,
+ data.center.y + sin(data.angle1) * data.radius);
+ endpoint.set(data.center.x + cos(data.angle2) * data.radius,
+ data.center.y + sin(data.angle2) * data.radius);
}
+void RS_Arc::calculateBorders()
+{
+ 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);
-void RS_Arc::calculateBorders() {
- 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);
-
- double a1 = !isReversed() ? data.angle1 : data.angle2;
- double a2 = !isReversed() ? data.angle2 : data.angle1;
-
- // check for left limit:
- if ((a1<M_PI && a2>M_PI) ||
- (a1>a2-1.0e-12 && a2>M_PI) ||
- (a1>a2-1.0e-12 && a1<M_PI) ) {
-
- minX = std::min(data.center.x - data.radius, minX);
- }
-
- // check for right limit:
- if (a1 > a2-1.0e-12) {
- maxX = std::max(data.center.x + data.radius, maxX);
- }
+ double a1 = !isReversed() ? data.angle1 : data.angle2;
+ double a2 = !isReversed() ? data.angle2 : data.angle1;
- // check for bottom limit:
- if ((a1<(M_PI_2*3) && a2>(M_PI_2*3)) ||
- (a1>a2-1.0e-12 && a2>(M_PI_2*3)) ||
- (a1>a2-1.0e-12 && a1<(M_PI_2*3)) ) {
+ // check for left limit:
+ if ((a1 < M_PI && a2 > M_PI)
+ || (a1 > a2 - 1.0e-12 && a2 > M_PI)
+ || (a1 > a2 - 1.0e-12 && a1 < M_PI) )
- minY = std::min(data.center.y - data.radius, minY);
- }
+ minX = std::min(data.center.x - data.radius, minX);
- // check for top limit:
- if ((a1<M_PI_2 && a2>M_PI_2) ||
- (a1>a2-1.0e-12 && a2>M_PI_2) ||
- (a1>a2-1.0e-12 && a1<M_PI_2) ) {
+ // check for right limit:
+ if (a1 > a2 - 1.0e-12)
+ maxX = std::max(data.center.x + data.radius, maxX);
- maxY = std::max(data.center.y + data.radius, maxY);
- }
+ // check for bottom limit:
+ if ((a1 < (M_PI_2 * 3) && a2 > (M_PI_2 * 3))
+ || (a1 > a2 - 1.0e-12 && a2 > (M_PI_2 * 3))
+ || (a1 > a2 - 1.0e-12 && a1 < (M_PI_2 * 3)) )
- minV.set(minX, minY);
- maxV.set(maxX, maxY);
-}
+ minY = std::min(data.center.y - data.radius, minY);
+ // check for top limit:
+ if ((a1 < M_PI_2 && a2 > M_PI_2)
+ || (a1 > a2 - 1.0e-12 && a2 > M_PI_2)
+ || (a1 > a2 - 1.0e-12 && a1 < M_PI_2) )
+ maxY = std::max(data.center.y + data.radius, maxY);
-VectorSolutions RS_Arc::getRefPoints() {
- VectorSolutions ret(startpoint, endpoint, data.center);
- return ret;
+ minV.set(minX, minY);
+ maxV.set(maxX, maxY);
}
+Vector RS_Arc::getNearestEndpoint(const Vector & coord, double * dist)
+{
+ double dist1, dist2;
+ Vector * nearerPoint;
-Vector RS_Arc::getNearestEndpoint(const Vector& coord, double* dist) {
- double dist1, dist2;
- Vector* nearerPoint;
-
- dist1 = startpoint.distanceTo(coord);
- dist2 = endpoint.distanceTo(coord);
+ 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;
- }
+ if (dist2 < dist1)
+ {
+ if (dist != NULL)
+ *dist = dist2;
+ nearerPoint = &endpoint;
+ }
+ else
+ {
+ if (dist != NULL)
+ *dist = dist1;
+ nearerPoint = &startpoint;
+ }
- return *nearerPoint;
+ return *nearerPoint;
}
+Vector RS_Arc::getNearestPointOnEntity(const Vector & coord, bool onEntity, double * dist, RS_Entity * * entity)
+{
+ Vector vec(false);
+ if (entity != NULL)
+ *entity = this;
-Vector RS_Arc::getNearestPointOnEntity(const Vector& coord,
- bool onEntity, double* dist, RS_Entity** entity) {
+ double angle = (coord - data.center).angle();
- Vector vec(false);
- if (entity!=NULL) {
- *entity = this;
- }
+ if (onEntity == false || RS_Math::isAngleBetween(angle,
+ data.angle1, data.angle2, isReversed()))
+ {
+ vec.setPolar(data.radius, angle);
+ vec += data.center;
+ }
- double angle = (coord-data.center).angle();
- if (onEntity==false || RS_Math::isAngleBetween(angle,
- data.angle1, data.angle2, isReversed())) {
- 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_Arc::getNearestCenter(const Vector& coord,
- double* dist) {
- if (dist!=NULL) {
- *dist = coord.distanceTo(data.center);
- }
- return data.center;
+Vector RS_Arc::getNearestCenter(const Vector & coord, double * dist)
+{
+ if (dist != NULL)
+ *dist = coord.distanceTo(data.center);
+ return data.center;
}
+Vector RS_Arc::getNearestMiddle(const Vector & coord, double * dist)
+{
+ Vector ret = getMiddlepoint();
-
-Vector RS_Arc::getNearestMiddle(const Vector& coord,
- double* dist) {
-
- Vector ret = getMiddlepoint();
-
- if (dist!=NULL) {
- *dist = coord.distanceTo(ret);
- }
- return ret;
+ if (dist != NULL)
+ *dist = coord.distanceTo(ret);
+ return ret;
}
+Vector RS_Arc::getNearestDist(double distance, const Vector & coord, double * dist)
+{
+ if (data.radius < 1.0e-6)
+ {
+ if (dist != NULL)
+ *dist = RS_MAXDOUBLE;
+ return Vector(false);
+ }
+ double a1, a2;
+ Vector p1, p2;
+ double aDist = distance / data.radius;
-Vector RS_Arc::getNearestDist(double distance,
- const Vector& coord,
- double* dist) {
-
- if (data.radius<1.0e-6) {
- if (dist!=NULL) {
- *dist = RS_MAXDOUBLE;
- }
- return Vector(false);
- }
-
- double a1, a2;
- Vector p1, p2;
- double aDist = distance / data.radius;
-
- if (isReversed()) {
- a1 = data.angle1 - aDist;
- a2 = data.angle2 + aDist;
- } else {
- a1 = data.angle1 + aDist;
- a2 = data.angle2 - aDist;
- }
+ if (isReversed())
+ {
+ a1 = data.angle1 - aDist;
+ a2 = data.angle2 + aDist;
+ }
+ else
+ {
+ a1 = data.angle1 + aDist;
+ a2 = data.angle2 - aDist;
+ }
- p1.setPolar(data.radius, a1);
- p1 += data.center;
- p2.setPolar(data.radius, a2);
- p2 += data.center;
+ p1.setPolar(data.radius, a1);
+ p1 += data.center;
+ p2.setPolar(data.radius, a2);
+ p2 += data.center;
- double dist1, dist2;
- Vector* nearerPoint;
+ double dist1, dist2;
+ Vector * nearerPoint;
- dist1 = p1.distanceTo(coord);
- dist2 = p2.distanceTo(coord);
+ dist1 = p1.distanceTo(coord);
+ dist2 = p2.distanceTo(coord);
- if (dist2<dist1) {
- if (dist!=NULL) {
- *dist = dist2;
- }
- nearerPoint = &p2;
- } else {
- if (dist!=NULL) {
- *dist = dist1;
- }
- nearerPoint = &p1;
- }
+ if (dist2 < dist1)
+ {
+ if (dist != NULL)
+ *dist = dist2;
+ nearerPoint = &p2;
+ }
+ else
+ {
+ if (dist != NULL)
+ *dist = dist1;
+ nearerPoint = &p1;
+ }
- return *nearerPoint;
+ return *nearerPoint;
}
+Vector RS_Arc::getNearestDist(double distance, bool startp)
+{
+ if (data.radius < 1.0e-6)
+ return Vector(false);
+
+ double a;
+ Vector p;
+ double aDist = distance / data.radius;
+
+ if (isReversed())
+ {
+ if (startp)
+ a = data.angle1 - aDist;
+ else
+ a = data.angle2 + aDist;
+ }
+ else
+ {
+ if (startp)
+ a = data.angle1 + aDist;
+ else
+ a = data.angle2 - aDist;
+ }
+ p.setPolar(data.radius, a);
+ p += data.center;
-
-Vector RS_Arc::getNearestDist(double distance,
- bool startp) {
-
- if (data.radius<1.0e-6) {
- return Vector(false);
- }
-
- double a;
- Vector p;
- double aDist = distance / data.radius;
-
- if (isReversed()) {
- if (startp) {
- a = data.angle1 - aDist;
- } else {
- a = data.angle2 + aDist;
- }
- } else {
- if (startp) {
- a = data.angle1 + aDist;
- } else {
- a = data.angle2 - aDist;
- }
- }
-
- p.setPolar(data.radius, a);
- p += data.center;
-
- return p;
+ return p;
}
+double RS_Arc::getDistanceToPoint(const Vector & coord, RS_Entity * * entity, RS2::ResolveLevel, double)
+{
+ if (entity != NULL)
+ *entity = this;
+ // check endpoints first:
+ double dist = coord.distanceTo(getStartpoint());
-double RS_Arc::getDistanceToPoint(const Vector& coord,
- RS_Entity** entity,
- RS2::ResolveLevel,
- double) {
- if (entity!=NULL) {
- *entity = this;
- }
+ if (dist < 1.0e-4)
+ return dist;
+ dist = coord.distanceTo(getEndpoint());
- // check endpoints first:
- double dist = coord.distanceTo(getStartpoint());
- if (dist<1.0e-4) {
- return dist;
- }
- dist = coord.distanceTo(getEndpoint());
- if (dist<1.0e-4) {
- return dist;
- }
+ if (dist < 1.0e-4)
+ return dist;
- if (RS_Math::isAngleBetween(data.center.angleTo(coord),
- data.angle1, data.angle2,
- isReversed())) {
+ if (RS_Math::isAngleBetween(data.center.angleTo(coord),
+ data.angle1, data.angle2,
+ isReversed()))
- return fabs((coord-data.center).magnitude() - data.radius);
- } else {
- return RS_MAXDOUBLE;
- }
+ return fabs((coord - data.center).magnitude() - data.radius);
+ else
+ return RS_MAXDOUBLE;
}
-
-
-void RS_Arc::moveStartpoint(const Vector& pos) {
- // polyline arcs: move point not angle:
- //if (parent!=NULL && parent->rtti()==RS2::EntityPolyline) {
- double bulge = getBulge();
- createFrom2PBulge(pos, getEndpoint(), bulge);
- //}
+void RS_Arc::moveStartpoint(const Vector & pos)
+{
+ // polyline arcs: move point not angle:
+ //if (parent!=NULL && parent->rtti()==RS2::EntityPolyline) {
+ double bulge = getBulge();
+ createFrom2PBulge(pos, getEndpoint(), bulge);
+ //}
// normal arc: move angle1
/*else {
- data.angle1 = data.center.angleTo(pos);
- calculateEndpoints();
- calculateBorders();
- }*/
+ data.angle1 = data.center.angleTo(pos);
+ calculateEndpoints();
+ calculateBorders();
+ }*/
}
-
-
-void RS_Arc::moveEndpoint(const Vector& pos) {
- // polyline arcs: move point not angle:
- //if (parent!=NULL && parent->rtti()==RS2::EntityPolyline) {
- double bulge = getBulge();
- createFrom2PBulge(getStartpoint(), pos, bulge);
- //}
+void RS_Arc::moveEndpoint(const Vector & pos)
+{
+ // polyline arcs: move point not angle:
+ //if (parent!=NULL && parent->rtti()==RS2::EntityPolyline) {
+ double bulge = getBulge();
+ createFrom2PBulge(getStartpoint(), pos, bulge);
+ //}
// normal arc: move angle1
/*else {
- data.angle2 = data.center.angleTo(pos);
+ data.angle2 = data.center.angleTo(pos);
calculateEndpoints();
- calculateBorders();
- }*/
+ calculateBorders();
+ }*/
}
-
-
-void RS_Arc::trimStartpoint(const Vector& pos) {
- data.angle1 = data.center.angleTo(pos);
- calculateEndpoints();
- calculateBorders();
+void RS_Arc::trimStartpoint(const Vector & pos)
+{
+ data.angle1 = data.center.angleTo(pos);
+ calculateEndpoints();
+ calculateBorders();
}
-
-
-void RS_Arc::trimEndpoint(const Vector& pos) {
- data.angle2 = data.center.angleTo(pos);
- calculateEndpoints();
- calculateBorders();
+void RS_Arc::trimEndpoint(const Vector & pos)
+{
+ data.angle2 = data.center.angleTo(pos);
+ calculateEndpoints();
+ calculateBorders();
}
-
-RS2::Ending RS_Arc::getTrimPoint(const Vector& coord,
- const Vector& trimPoint) {
-
- double angEl = data.center.angleTo(trimPoint);
- double angM = data.center.angleTo(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;
- }
- }
+RS2::Ending RS_Arc::getTrimPoint(const Vector & coord, const Vector & trimPoint)
+{
+ double angEl = data.center.angleTo(trimPoint);
+ double angM = data.center.angleTo(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;
+ }
}
-
-void RS_Arc::reverse() {
- double a = data.angle1;
- data.angle1 = data.angle2;
- data.angle2 = a;
- data.reversed = !data.reversed;
- calculateEndpoints();
- calculateBorders();
+void RS_Arc::reverse()
+{
+ double a = data.angle1;
+ data.angle1 = data.angle2;
+ data.angle2 = a;
+ data.reversed = !data.reversed;
+ calculateEndpoints();
+ calculateBorders();
}
-
-void RS_Arc::move(Vector offset) {
- data.center.move(offset);
- calculateEndpoints();
- calculateBorders();
+void RS_Arc::move(Vector offset)
+{
+ data.center.move(offset);
+ calculateEndpoints();
+ calculateBorders();
}
-
-
-void RS_Arc::rotate(Vector center, double angle) {
- RS_DEBUG->print("RS_Arc::rotate");
- data.center.rotate(center, angle);
- data.angle1 = RS_Math::correctAngle(data.angle1+angle);
- data.angle2 = RS_Math::correctAngle(data.angle2+angle);
- calculateEndpoints();
- calculateBorders();
- RS_DEBUG->print("RS_Arc::rotate: OK");
+void RS_Arc::rotate(Vector center, double angle)
+{
+ RS_DEBUG->print("RS_Arc::rotate");
+ data.center.rotate(center, angle);
+ data.angle1 = RS_Math::correctAngle(data.angle1 + angle);
+ data.angle2 = RS_Math::correctAngle(data.angle2 + angle);
+ calculateEndpoints();
+ calculateBorders();
+ RS_DEBUG->print("RS_Arc::rotate: OK");
}
+void RS_Arc::scale(Vector center, Vector factor)
+{
+ // negative scaling: mirroring
+ if (factor.x < 0.0)
+ mirror(data.center, data.center + Vector(0.0, 1.0));
+ //factor.x*=-1;
-void RS_Arc::scale(Vector center, Vector factor) {
- // negative scaling: mirroring
- if (factor.x<0.0) {
- mirror(data.center, data.center + Vector(0.0, 1.0));
- //factor.x*=-1;
- }
- if (factor.y<0.0) {
- mirror(data.center, data.center + Vector(1.0, 0.0));
- //factor.y*=-1;
- }
-
- data.center.scale(center, factor);
- data.radius *= factor.x;
- if (data.radius<0.0) {
- data.radius*=-1.0;
- }
- calculateEndpoints();
- calculateBorders();
-}
+ if (factor.y < 0.0)
+ mirror(data.center, data.center + Vector(1.0, 0.0));
+ //factor.y*=-1;
+ data.center.scale(center, factor);
+ data.radius *= factor.x;
+ if (data.radius < 0.0)
+ data.radius *= -1.0;
+ calculateEndpoints();
+ calculateBorders();
+}
-void RS_Arc::mirror(Vector axisPoint1, Vector axisPoint2) {
- data.center.mirror(axisPoint1, axisPoint2);
- data.reversed = (!data.reversed);
- /*
- startpoint.mirror(axisPoint1, axisPoint2);
- endpoint.mirror(axisPoint1, axisPoint2);
+void RS_Arc::mirror(Vector axisPoint1, Vector axisPoint2)
+{
+ data.center.mirror(axisPoint1, axisPoint2);
+ data.reversed = (!data.reversed);
+ /*
+ startpoint.mirror(axisPoint1, axisPoint2);
+ endpoint.mirror(axisPoint1, axisPoint2);
- data.angle1 = data.center.angleTo(startpoint);
- data.angle2 = data.center.angleTo(endpoint);
- */
+ data.angle1 = data.center.angleTo(startpoint);
+ data.angle2 = data.center.angleTo(endpoint);
+ */
- Vector vec;
- vec.setPolar(1.0, data.angle1);
- vec.mirror(Vector(0.0,0.0), axisPoint2-axisPoint1);
- data.angle1 = vec.angle();
+ Vector vec;
+ vec.setPolar(1.0, data.angle1);
+ vec.mirror(Vector(0.0, 0.0), axisPoint2 - axisPoint1);
+ data.angle1 = vec.angle();
- vec.setPolar(1.0, data.angle2);
- vec.mirror(Vector(0.0,0.0), axisPoint2-axisPoint1);
- data.angle2 = vec.angle();
+ vec.setPolar(1.0, data.angle2);
+ vec.mirror(Vector(0.0, 0.0), axisPoint2 - axisPoint1);
+ data.angle2 = vec.angle();
- calculateEndpoints();
- calculateBorders();
+ calculateEndpoints();
+ calculateBorders();
}
+void RS_Arc::moveRef(const Vector & ref, const Vector & offset)
+{
+ if (ref.distanceTo(startpoint) < 1.0e-4)
+ moveStartpoint(startpoint + offset);
-void RS_Arc::moveRef(const Vector& ref, const Vector& offset) {
- if (ref.distanceTo(startpoint)<1.0e-4) {
- moveStartpoint(startpoint+offset);
- }
- if (ref.distanceTo(endpoint)<1.0e-4) {
- moveEndpoint(endpoint+offset);
- }
+ if (ref.distanceTo(endpoint) < 1.0e-4)
+ moveEndpoint(endpoint + offset);
}
+void RS_Arc::stretch(Vector firstCorner, Vector secondCorner, Vector offset)
+{
+ if (getMin().isInWindow(firstCorner, secondCorner)
+ && getMax().isInWindow(firstCorner, secondCorner))
+ move(offset);
+ else
+ {
+ if (getStartpoint().isInWindow(firstCorner,
+ secondCorner))
+ moveStartpoint(getStartpoint() + offset);
-void RS_Arc::stretch(Vector firstCorner,
- Vector secondCorner,
- Vector offset) {
-
- if (getMin().isInWindow(firstCorner, secondCorner) &&
- getMax().isInWindow(firstCorner, secondCorner)) {
- move(offset);
- }
- else {
- if (getStartpoint().isInWindow(firstCorner,
- secondCorner)) {
- moveStartpoint(getStartpoint() + offset);
- }
- if (getEndpoint().isInWindow(firstCorner,
- secondCorner)) {
- moveEndpoint(getEndpoint() + offset);
- }
+ if (getEndpoint().isInWindow(firstCorner,
+ secondCorner))
+ moveEndpoint(getEndpoint() + offset);
}
}
-//void RS_Arc::draw(RS_Painter* painter, RS_GraphicView* view,
-void RS_Arc::draw(PaintInterface * painter, RS_GraphicView * view, double /*patternOffset*/)
+void RS_Arc::draw(PaintInterface * painter, GraphicView * view, double /*patternOffset*/)
{
- if (painter == NULL || view == NULL)
- return;
+ if (painter == NULL || view == NULL)
+ return;
+
+ //double styleFactor = getStyleFactor();
+
+ // simple style-less lines
+ if (getPen().getLineType() == RS2::SolidLine
+ || isSelected()
+ || view->getDrawingMode() == RS2::ModePreview)
+
+ painter->drawArc(view->toGui(getCenter()),
+ getRadius() * view->getFactor().x,
+ getAngle1(), getAngle2(),
+ isReversed());
+ else
+ {
+ double styleFactor = getStyleFactor(view);
+
+ if (styleFactor < 0.0)
+ {
+ painter->drawArc(view->toGui(getCenter()),
+ getRadius() * view->getFactor().x,
+ getAngle1(), getAngle2(),
+ isReversed());
+ return;
+ }
- //double styleFactor = getStyleFactor();
+ // Pattern:
+ RS_LineTypePattern * pat;
- // simple style-less lines
- if (getPen().getLineType()==RS2::SolidLine ||
- isSelected() ||
- view->getDrawingMode()==RS2::ModePreview) {
+ if (isSelected())
+ pat = &patternSelected;
+ else
+ pat = view->getPattern(getPen().getLineType());
- painter->drawArc(view->toGui(getCenter()),
- getRadius() * view->getFactor().x,
- getAngle1(), getAngle2(),
- isReversed());
- } else {
- double styleFactor = getStyleFactor(view);
- if (styleFactor<0.0) {
- painter->drawArc(view->toGui(getCenter()),
- getRadius() * view->getFactor().x,
- getAngle1(), getAngle2(),
- isReversed());
+ if (pat == NULL)
return;
- }
- // Pattern:
- RS_LineTypePattern* pat;
- if (isSelected()) {
- pat = &patternSelected;
- } else {
- pat = view->getPattern(getPen().getLineType());
- }
-
- 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 a1;
- double a2;
- if (data.reversed) {
- a2 = getAngle1();
- a1 = getAngle2();
- } else {
- a1 = getAngle1();
- a2 = getAngle2();
- }
-
- double* da; // array of distances in x.
- int i; // index counter
-
- double length = getAngleLength();
-
- // create scaled 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 = a1;
- //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] > 0.0) {
- if (tot+da[i]<length) {
- painter->drawArc(cp, r,
- curA,
- curA + da[i],
- false);
- } else {
- painter->drawArc(cp, r,
- curA,
- a2,
- false);
- }
- }
- curA+=da[i];
- tot+=da[i];
- done=tot>length;
-
- i++;
- if (i>=pat->num) {
- i=0;
- }
- } while(!done);
-
- delete[] da;
- }
-}
+ 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 a1;
+ double a2;
+
+ if (data.reversed)
+ {
+ a2 = getAngle1();
+ a1 = getAngle2();
+ }
+ else
+ {
+ a1 = getAngle1();
+ a2 = getAngle2();
+ }
+
+ double * da; // array of distances in x.
+ int i; // index counter
+
+ double length = getAngleLength();
+
+ // create scaled 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 = a1;
+ //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] > 0.0)
+ {
+ if (tot + da[i] < length)
+ painter->drawArc(cp, r,
+ curA,
+ curA + da[i],
+ false);
+ else
+ painter->drawArc(cp, r,
+ curA,
+ a2,
+ false);
+ }
+ curA += da[i];
+ tot += da[i];
+ done = tot > length;
+
+ i++;
+
+ if (i >= pat->num)
+ i = 0;
+ }
+ while (!done);
+
+ delete[] da;
+ }
+}
/**
* @return Middle point of the entity.
*/
-Vector RS_Arc::getMiddlepoint() const {
- double a;
- Vector ret;
+Vector RS_Arc::getMiddlepoint() const
+{
+ double a;
+ Vector ret;
- if (isReversed()) {
- a = data.angle1 - getAngleLength()/2.0;
- } else {
- a = data.angle1 + getAngleLength()/2.0;
- }
- ret.setPolar(data.radius, a);
- ret+=data.center;
+ if (isReversed())
+ a = data.angle1 - getAngleLength() / 2.0;
+ else
+ a = data.angle1 + getAngleLength() / 2.0;
+ ret.setPolar(data.radius, a);
+ ret += data.center;
- return ret;
+ return ret;
}
-
-
/**
* @return Angle length in rad.
*/
-double RS_Arc::getAngleLength() const {
- double ret = 0.0;
-
- if (isReversed()) {
- if (data.angle1<data.angle2) {
- ret = data.angle1+2*M_PI-data.angle2;
- } else {
- ret = data.angle1-data.angle2;
- }
- } else {
- if (data.angle2<data.angle1) {
- ret = data.angle2+2*M_PI-data.angle1;
- } else {
- ret = data.angle2-data.angle1;
- }
- }
+double RS_Arc::getAngleLength() const
+{
+ double ret = 0.0;
+
+ if (isReversed())
+ {
+ if (data.angle1 < data.angle2)
+ ret = data.angle1 + 2 * M_PI - data.angle2;
+ else
+ ret = data.angle1 - data.angle2;
+ }
+ else
+ {
+ if (data.angle2 < data.angle1)
+ ret = data.angle2 + 2 * M_PI - data.angle1;
+ else
+ ret = data.angle2 - data.angle1;
+ }
- // full circle:
- if (fabs(ret)<1.0e-6) {
- ret = 2*M_PI;
- }
+ // full circle:
+ if (fabs(ret) < 1.0e-6)
+ ret = 2 * M_PI;
- return ret;
+ return ret;
}
-
-
/**
* @return Length of the arc.
*/
-double RS_Arc::getLength() {
- return getAngleLength()*data.radius;
+double RS_Arc::getLength()
+{
+ return getAngleLength() * data.radius;
}
-
-
/**
* Gets the arc's bulge (tangens of angle length divided by 4).
*/
-double RS_Arc::getBulge() const {
- double bulge = tan(fabs(getAngleLength())/4.0);
- if (isReversed()) {
- bulge*=-1;
- }
- return bulge;
-}
-
+double RS_Arc::getBulge() const
+{
+ double bulge = tan(fabs(getAngleLength()) / 4.0);
+ if (isReversed())
+ bulge *= -1;
+ return bulge;
+}
/**
* Dumps the point's data to stdout.
*/
-std::ostream& operator << (std::ostream& os, const RS_Arc& a) {
- os << " Arc: " << a.data << "\n";
- return os;
+std::ostream & operator<<(std::ostream & os, const RS_Arc & a)
+{
+ os << " Arc: " << a.data << "\n";
+ return os;
}