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