]> Shamusworld >> Repos - architektonas/blob - src/base/rs_constructionline.cpp
Initial import
[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 //
14
15 #include "rs_constructionline.h"
16
17 #include "rs_debug.h"
18
19 /**
20  * Constructor.
21  */
22 RS_ConstructionLine::RS_ConstructionLine(RS_EntityContainer * parent,
23         const RS_ConstructionLineData & d): RS_AtomicEntity(parent), data(d)
24 {
25         calculateBorders();
26 }
27
28 /**
29  * Destructor.
30  */
31 RS_ConstructionLine::~RS_ConstructionLine()
32 {
33 }
34
35 RS_Entity * RS_ConstructionLine::clone()
36 {
37         RS_ConstructionLine * c = new RS_ConstructionLine(*this);
38         c->initId();
39         return c;
40 }
41
42 void RS_ConstructionLine::calculateBorders()
43 {
44         minV = Vector::minimum(data.point1, data.point2);
45         maxV = Vector::maximum(data.point1, data.point2);
46 }
47
48 Vector RS_ConstructionLine::getNearestEndpoint(const Vector & coord, double * dist)
49 {
50         double dist1, dist2;
51         Vector * nearerPoint;
52
53         dist1 = data.point1.distanceTo(coord);
54         dist2 = data.point2.distanceTo(coord);
55
56         if (dist2 < dist1)
57         {
58                 if (dist != NULL)
59                         *dist = dist2;
60
61                 nearerPoint = &data.point2;
62         }
63         else
64         {
65                 if (dist != NULL)
66                         *dist = dist1;
67
68                 nearerPoint = &data.point1;
69         }
70
71         return *nearerPoint;
72 }
73
74 Vector RS_ConstructionLine::getNearestPointOnEntity(const Vector & coord,
75         bool /*onEntity*/, double * /*dist*/, RS_Entity ** entity)
76 {
77         if (entity != NULL)
78                 *entity = this;
79
80         Vector ae = data.point2-data.point1;
81         Vector ea = data.point1-data.point2;
82         Vector ap = coord-data.point1;
83         Vector ep = coord-data.point2;
84
85         if (ae.magnitude() < 1.0e-6 || ea.magnitude() < 1.0e-6)
86                 return Vector(false);
87
88         // Orthogonal projection from both sides:
89         Vector ba = ae * Vector::dotP(ae, ap) / (ae.magnitude() * ae.magnitude());
90         Vector be = ea * Vector::dotP(ea, ep) / (ea.magnitude() * ea.magnitude());
91
92         return data.point1 + ba;
93 }
94
95 Vector RS_ConstructionLine::getNearestCenter(const Vector & /*coord*/, double * dist)
96 {
97         if (dist != NULL)
98                 *dist = RS_MAXDOUBLE;
99
100         return Vector(false);
101 }
102
103 Vector RS_ConstructionLine::getNearestMiddle(const Vector & /*coord*/, double * dist)
104 {
105         if (dist != NULL)
106                 *dist = RS_MAXDOUBLE;
107
108         return Vector(false);
109 }
110
111 Vector RS_ConstructionLine::getNearestDist(double /*distance*/, const Vector & /*coord*/,
112         double * dist)
113 {
114         if (dist != NULL)
115                 *dist = RS_MAXDOUBLE;
116
117         return Vector(false);
118 }
119
120 double RS_ConstructionLine::getDistanceToPoint(const Vector& coord,
121         RS_Entity** entity,
122         RS2::ResolveLevel /*level*/, double /*solidDist*/)
123 {
124         RS_DEBUG->print("RS_ConstructionLine::getDistanceToPoint");
125
126         if (entity != NULL)
127                 *entity = this;
128
129         double dist = RS_MAXDOUBLE;
130         Vector ae = data.point2-data.point1;
131         Vector ea = data.point1-data.point2;
132         Vector ap = coord-data.point1;
133         Vector ep = coord-data.point2;
134
135         if (ae.magnitude() < 1.0e-6 || ea.magnitude() < 1.0e-6)
136                 return dist;
137
138         // Orthogonal projection from both sides:
139         Vector ba = ae * Vector::dotP(ae, ap) / RS_Math::pow(ae.magnitude(), 2);
140         Vector be = ea * Vector::dotP(ea, ep) / RS_Math::pow(ea.magnitude(), 2);
141
142         RS_DEBUG->print("ba: %f", ba.magnitude());
143         RS_DEBUG->print("ae: %f", ae.magnitude());
144
145         Vector cp = Vector::crossP(ap, ae);
146         dist = cp.magnitude() / ae.magnitude();
147
148         return dist;
149 }
150
151 void RS_ConstructionLine::move(Vector offset)
152 {
153         data.point1.move(offset);
154         data.point2.move(offset);
155         //calculateBorders();
156 }
157
158 void RS_ConstructionLine::rotate(Vector center, double angle)
159 {
160         data.point1.rotate(center, angle);
161         data.point2.rotate(center, angle);
162         //calculateBorders();
163 }
164
165 void RS_ConstructionLine::scale(Vector center, Vector factor)
166 {
167         data.point1.scale(center, factor);
168         data.point2.scale(center, factor);
169         //calculateBorders();
170 }
171
172 void RS_ConstructionLine::mirror(Vector axisPoint1, Vector axisPoint2)
173 {
174         data.point1.mirror(axisPoint1, axisPoint2);
175         data.point2.mirror(axisPoint1, axisPoint2);
176 }
177
178 /**
179  * Dumps the point's data to stdout.
180  */
181 std::ostream & operator<<(std::ostream & os, const RS_ConstructionLine & l)
182 {
183         os << " ConstructionLine: " << l.getData() << "\n";
184         return os;
185 }