]> Shamusworld >> Repos - architektonas/blob - src/base/rs_constructionline.cpp
20b9ccde6e61f8dbfe0f1af873c8510d21a55c51
[architektonas] / src / base / rs_constructionline.cpp
1 // rs_constructionline.cpp
2 //
3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
9 //
10 // JLH = James L. Hammons <jlhamm@acm.org>
11 //
12 // Who  When        What
13 // ---  ----------  -----------------------------------------------------------
14 // JLH  05/28/2010  Added this text. :-)
15 // JLH  06/02/2010  Moved implementation from header to here WHERE IT BELONGS.
16 //
17
18 #include "rs_constructionline.h"
19
20 #include "rs_debug.h"
21
22 /**
23  * Constructor.
24  */
25 RS_ConstructionLine::RS_ConstructionLine(RS_EntityContainer * parent,
26         const RS_ConstructionLineData & d): RS_AtomicEntity(parent), data(d)
27 {
28         calculateBorders();
29 }
30
31 /**
32  * Destructor.
33  */
34 RS_ConstructionLine::~RS_ConstructionLine()
35 {
36 }
37
38 RS_Entity * RS_ConstructionLine::clone()
39 {
40         RS_ConstructionLine * c = new RS_ConstructionLine(*this);
41         c->initId();
42         return c;
43 }
44
45 /**     @return RS2::EntityConstructionLine */
46 /*virtual*/ RS2::EntityType RS_ConstructionLine::rtti() const
47 {
48         return RS2::EntityConstructionLine;
49 }
50
51 /**
52  * @todo
53  * @return Start point of the entity.
54  */
55 /*virtual*/ Vector RS_ConstructionLine::getStartpoint() const
56 {
57         return Vector(false);
58 }
59
60 /**
61  * @todo
62  * @return End point of the entity.
63  */
64 /*virtual*/ Vector RS_ConstructionLine::getEndpoint() const
65 {
66         return Vector(false);
67 }
68
69 /** @return Copy of data that defines the line. */
70 RS_ConstructionLineData RS_ConstructionLine::getData() const
71 {
72         return data;
73 }
74
75 /** @return First definition point. */
76 Vector RS_ConstructionLine::getPoint1() const
77 {
78         return data.point1;
79 }
80 /** @return Second definition point. */
81 Vector RS_ConstructionLine::getPoint2() const
82 {
83         return data.point2;
84 }
85
86 void RS_ConstructionLine::calculateBorders()
87 {
88         minV = Vector::minimum(data.point1, data.point2);
89         maxV = Vector::maximum(data.point1, data.point2);
90 }
91
92 Vector RS_ConstructionLine::getNearestEndpoint(const Vector & coord, double * dist)
93 {
94         double dist1, dist2;
95         Vector * nearerPoint;
96
97         dist1 = data.point1.distanceTo(coord);
98         dist2 = data.point2.distanceTo(coord);
99
100         if (dist2 < dist1)
101         {
102                 if (dist != NULL)
103                         *dist = dist2;
104
105                 nearerPoint = &data.point2;
106         }
107         else
108         {
109                 if (dist != NULL)
110                         *dist = dist1;
111
112                 nearerPoint = &data.point1;
113         }
114
115         return *nearerPoint;
116 }
117
118 Vector RS_ConstructionLine::getNearestPointOnEntity(const Vector & coord,
119         bool /*onEntity*/, double * /*dist*/, RS_Entity ** entity)
120 {
121         if (entity != NULL)
122                 *entity = this;
123
124         Vector ae = data.point2-data.point1;
125         Vector ea = data.point1-data.point2;
126         Vector ap = coord-data.point1;
127         Vector ep = coord-data.point2;
128
129         if (ae.magnitude() < 1.0e-6 || ea.magnitude() < 1.0e-6)
130                 return Vector(false);
131
132         // Orthogonal projection from both sides:
133         Vector ba = ae * Vector::dotP(ae, ap) / (ae.magnitude() * ae.magnitude());
134         Vector be = ea * Vector::dotP(ea, ep) / (ea.magnitude() * ea.magnitude());
135
136         return data.point1 + ba;
137 }
138
139 Vector RS_ConstructionLine::getNearestCenter(const Vector & /*coord*/, double * dist)
140 {
141         if (dist != NULL)
142                 *dist = RS_MAXDOUBLE;
143
144         return Vector(false);
145 }
146
147 Vector RS_ConstructionLine::getNearestMiddle(const Vector & /*coord*/, double * dist)
148 {
149         if (dist != NULL)
150                 *dist = RS_MAXDOUBLE;
151
152         return Vector(false);
153 }
154
155 Vector RS_ConstructionLine::getNearestDist(double /*distance*/, const Vector & /*coord*/,
156         double * dist)
157 {
158         if (dist != NULL)
159                 *dist = RS_MAXDOUBLE;
160
161         return Vector(false);
162 }
163
164 double RS_ConstructionLine::getDistanceToPoint(const Vector& coord,
165         RS_Entity** entity,
166         RS2::ResolveLevel /*level*/, double /*solidDist*/)
167 {
168         RS_DEBUG->print("RS_ConstructionLine::getDistanceToPoint");
169
170         if (entity != NULL)
171                 *entity = this;
172
173         double dist = RS_MAXDOUBLE;
174         Vector ae = data.point2-data.point1;
175         Vector ea = data.point1-data.point2;
176         Vector ap = coord-data.point1;
177         Vector ep = coord-data.point2;
178
179         if (ae.magnitude() < 1.0e-6 || ea.magnitude() < 1.0e-6)
180                 return dist;
181
182         // Orthogonal projection from both sides:
183         Vector ba = ae * Vector::dotP(ae, ap) / RS_Math::pow(ae.magnitude(), 2);
184         Vector be = ea * Vector::dotP(ea, ep) / RS_Math::pow(ea.magnitude(), 2);
185
186         RS_DEBUG->print("ba: %f", ba.magnitude());
187         RS_DEBUG->print("ae: %f", ae.magnitude());
188
189         Vector cp = Vector::crossP(ap, ae);
190         dist = cp.magnitude() / ae.magnitude();
191
192         return dist;
193 }
194
195 void RS_ConstructionLine::move(Vector offset)
196 {
197         data.point1.move(offset);
198         data.point2.move(offset);
199         //calculateBorders();
200 }
201
202 void RS_ConstructionLine::rotate(Vector center, double angle)
203 {
204         data.point1.rotate(center, angle);
205         data.point2.rotate(center, angle);
206         //calculateBorders();
207 }
208
209 void RS_ConstructionLine::scale(Vector center, Vector factor)
210 {
211         data.point1.scale(center, factor);
212         data.point2.scale(center, factor);
213         //calculateBorders();
214 }
215
216 void RS_ConstructionLine::mirror(Vector axisPoint1, Vector axisPoint2)
217 {
218         data.point1.mirror(axisPoint1, axisPoint2);
219         data.point2.mirror(axisPoint1, axisPoint2);
220 }
221
222 /*virtual*/ void RS_ConstructionLine::draw(PaintInterface *, GraphicView *, double)
223 {
224 }
225
226 /**
227  * Dumps the point's data to stdout.
228  */
229 std::ostream & operator<<(std::ostream & os, const RS_ConstructionLine & l)
230 {
231         os << " ConstructionLine: " << l.getData() << "\n";
232         return os;
233 }