]> Shamusworld >> Repos - architektonas/blob - src/base/rs_arc.h
Initial import
[architektonas] / src / base / rs_arc.h
1 #ifndef RS_ARC_H
2 #define RS_ARC_H
3
4 #include "rs_atomicentity.h"
5
6 class PaintInterface;
7
8 /**
9  * Holds the data that defines an arc.
10  */
11 class RS_ArcData {
12 public:
13     RS_ArcData() {}
14
15     RS_ArcData(const Vector& center,
16                double radius,
17                double angle1, double angle2,
18                bool reversed) {
19
20         this->center = center;
21         this->radius = radius;
22         this->angle1 = angle1;
23         this->angle2 = angle2;
24         this->reversed = reversed;
25     }
26
27     void reset() {
28         center = Vector(false);
29         radius = 0.0;
30         angle1 = 0.0;
31         angle2 = 0.0;
32         reversed = false;
33     }
34
35     bool isValid() {
36         return (center.valid && radius>RS_TOLERANCE &&
37                 fabs(angle1-angle2)>RS_TOLERANCE_ANGLE);
38     }
39
40     friend std::ostream& operator << (std::ostream& os, const RS_ArcData& ad) {
41         os << "(" << ad.center <<
42         "/" << ad.radius <<
43         " " << ad.angle1 <<
44         "," << ad.angle2 <<
45         ")";
46         return os;
47     }
48
49 public:
50     Vector center;
51     double radius;
52     double angle1;
53     double angle2;
54     bool reversed;
55 };
56
57
58
59 /**
60  * Class for an arc entity. All angles are in Rad.
61  *
62  * @author Andrew Mustun
63  */
64 class RS_Arc : public RS_AtomicEntity {
65 public:
66     RS_Arc(RS_EntityContainer* parent,
67            const RS_ArcData& d);
68     virtual ~RS_Arc() {}
69
70     virtual RS_Entity* clone() {
71         RS_Arc* a = new RS_Arc(*this);
72         a->initId();
73         return a;
74     }
75
76     /** @return RS2::EntityArc */
77     virtual RS2::EntityType rtti() const {
78         return RS2::EntityArc;
79     }
80     /** @return true */
81     virtual bool isEdge() const {
82         return true;
83     }
84
85     /** @return Copy of data that defines the arc. **/
86     RS_ArcData getData() const {
87         return data;
88     }
89
90     virtual VectorSolutions getRefPoints();
91
92     /** Sets new arc parameters. **/
93     void setData(RS_ArcData d) {
94         data = d;
95     }
96
97     /** @return The center point (x) of this arc */
98     Vector getCenter() const {
99         return data.center;
100     }
101     /** Sets new center. */
102         void setCenter(const Vector& c) {
103                 data.center = c;
104         }
105
106     /** @return The radius of this arc */
107     double getRadius() const {
108         return data.radius;
109     }
110     /** Sets new radius. */
111     void setRadius(double r) {
112         data.radius = r;
113     }
114
115     /** @return The start angle of this arc */
116     double getAngle1() const {
117         return data.angle1;
118     }
119     /** Sets new start angle. */
120         void setAngle1(double a1) {
121                 data.angle1 = a1;
122         }
123     /** @return The end angle of this arc */
124     double getAngle2() const {
125         return data.angle2;
126     }
127     /** Sets new end angle. */
128         void setAngle2(double a2) {
129                 data.angle2 = a2;
130         }
131         /**
132          * @return Direction 1. The angle at which the arc starts at
133          * the startpoint.
134          */
135         double getDirection1() const {
136                 if (!data.reversed) {
137                         return RS_Math::correctAngle(data.angle1+M_PI/2.0);
138                 }
139                 else {
140                         return RS_Math::correctAngle(data.angle1-M_PI/2.0);
141                 }
142         }
143         /**
144          * @return Direction 2. The angle at which the arc starts at
145          * the endpoint.
146          */
147         double getDirection2() const {
148                 if (!data.reversed) {
149                         return RS_Math::correctAngle(data.angle2-M_PI/2.0);
150                 }
151                 else {
152                         return RS_Math::correctAngle(data.angle2+M_PI/2.0);
153                 }
154         }
155
156     /**
157      * @retval true if the arc is reversed (clockwise),
158      * @retval false otherwise
159      */
160     bool isReversed() const {
161         return data.reversed;
162     }
163         /** sets the reversed status. */
164         void setReversed(bool r) {
165                 data.reversed = r;
166         }
167
168     /** @return Start point of the entity. */
169     virtual Vector getStartpoint() const {
170         return startpoint;
171     }
172     /** @return End point of the entity. */
173     virtual Vector getEndpoint() const {
174         return endpoint;
175     }
176         virtual void moveStartpoint(const Vector& pos);
177         virtual void moveEndpoint(const Vector& pos);
178
179         virtual void trimStartpoint(const Vector& pos);
180         virtual void trimEndpoint(const Vector& pos);
181
182         virtual RS2::Ending getTrimPoint(const Vector& coord,
183                   const Vector& trimPoint);
184
185         virtual void reverse();
186
187     Vector getMiddlepoint() const;
188     double getAngleLength() const;
189     virtual double getLength();
190     double getBulge() const;
191
192     bool createFrom3P(const Vector& p1, const Vector& p2,
193                       const Vector& p3);
194         bool createFrom2PDirectionRadius(const Vector& startPoint, const Vector& endPoint,
195                 double direction1, double radius);
196         bool createFrom2PBulge(const Vector& startPoint, const Vector& endPoint,
197                 double bulge);
198
199     virtual Vector getNearestEndpoint(const Vector& coord,
200                                          double* dist = NULL);
201     virtual Vector getNearestPointOnEntity(const Vector& coord,
202             bool onEntity = true, double* dist = NULL, RS_Entity** entity=NULL);
203     virtual Vector getNearestCenter(const Vector& coord,
204                                        double* dist = NULL);
205     virtual Vector getNearestMiddle(const Vector& coord,
206                                        double* dist = NULL);
207     virtual Vector getNearestDist(double distance,
208                                      const Vector& coord,
209                                      double* dist = NULL);
210     virtual Vector getNearestDist(double distance,
211                                      bool startp);
212
213     virtual double getDistanceToPoint(const Vector& coord,
214                                       RS_Entity** entity=NULL,
215                                       RS2::ResolveLevel level=RS2::ResolveNone,
216                                                                           double solidDist = RS_MAXDOUBLE);
217     virtual void move(Vector offset);
218     virtual void rotate(Vector center, double angle);
219     virtual void scale(Vector center, Vector factor);
220     virtual void mirror(Vector axisPoint1, Vector axisPoint2);
221         virtual void moveRef(const Vector& ref, const Vector& offset);
222     virtual void stretch(Vector firstCorner,
223                          Vector secondCorner,
224                          Vector offset);
225
226 //    virtual void draw(RS_Painter* painter, RS_GraphicView* view, double patternOffset=0.0);
227     virtual void draw(PaintInterface * painter, RS_GraphicView * view, double patternOffset = 0.0);
228
229     friend std::ostream & operator<<(std::ostream & os, const RS_Arc & a);
230
231     virtual void calculateEndpoints();
232     virtual void calculateBorders();
233
234 protected:
235     RS_ArcData data;
236
237     /**
238      * Startpoint. This is redundant but stored for performance
239      * reasons.
240      */
241     Vector startpoint;
242     /**
243      * Endpoint. This is redundant but stored for performance
244      * reasons.
245      */
246     Vector endpoint;
247 };
248
249 #endif