]> Shamusworld >> Repos - architektonas/blob - src/base/solid.cpp
Bugfixes related to removing Snapper class.
[architektonas] / src / base / solid.cpp
1 // solid.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  06/02/2010  Added this text. :-)
15 //
16
17 #include "solid.h"
18
19 #include "debug.h"
20 #include "graphicview.h"
21 #include "paintinterface.h"
22
23 /**
24  * Default constructor.
25  */
26 Solid::Solid(EntityContainer * parent, const SolidData & d):
27         AtomicEntity(parent), data(d)
28 {
29         calculateBorders();
30 }
31
32 /*virtual*/ Entity * Solid::clone()
33 {
34         Solid * s = new Solid(*this);
35         s->initId();
36         return s;
37 }
38
39 /**     @return RS_ENTITY_POINT */
40 /*virtual*/ RS2::EntityType Solid::rtti() const
41 {
42         return RS2::EntitySolid;
43 }
44
45 /**
46  * @return Start point of the entity.
47  */
48 /*virtual*/ Vector Solid::getStartpoint() const
49 {
50         return Vector(false);
51 }
52
53 /**
54  * @return End point of the entity.
55  */
56 /*virtual*/ Vector Solid::getEndpoint() const
57 {
58         return Vector(false);
59 }
60
61 /** @return Copy of data that defines the point. */
62 SolidData Solid::getData() const
63 {
64         return data;
65 }
66
67 /** @return true if this is a triangle. */
68 bool Solid::isTriangle()
69 {
70         return !data.corner[3].valid;
71 }
72
73 /**
74  * @return Corner number 'num'.
75  */
76 Vector Solid::getCorner(int num)
77 {
78         if (num >= 0 && num < 4)
79                 return data.corner[num];
80         else
81         {
82                 DEBUG->print("Illegal corner requested from Solid", Debug::D_WARNING);
83                 return Vector(false);
84         }
85 }
86
87 /**
88  * Shapes this Solid into a standard arrow (used in dimensions).
89  *
90  * @param point The point the arrow points to.
91  * @param angle Direction of the arrow.
92  * @param arrowSize Size of arrow (length).
93  */
94 void Solid::shapeArrow(const Vector & point, double angle, double arrowSize)
95 {
96         double cosv1, sinv1, cosv2, sinv2;
97         double arrowSide = arrowSize / cos(0.165);
98
99         cosv1 = cos(angle + 0.165) * arrowSide;
100         sinv1 = sin(angle + 0.165) * arrowSide;
101         cosv2 = cos(angle - 0.165) * arrowSide;
102         sinv2 = sin(angle - 0.165) * arrowSide;
103
104         data.corner[0] = point;
105         data.corner[1] = Vector(point.x - cosv1, point.y - sinv1);
106         data.corner[2] = Vector(point.x - cosv2, point.y - sinv2);
107         data.corner[3] = Vector(false);
108
109         calculateBorders();
110 }
111
112 void Solid::calculateBorders()
113 {
114         resetBorders();
115
116         for(int i=0; i<4; ++i)
117         {
118                 if (data.corner[i].valid)
119                 {
120                         minV = Vector::minimum(minV, data.corner[i]);
121                         maxV = Vector::maximum(maxV, data.corner[i]);
122                 }
123         }
124 }
125
126 Vector Solid::getNearestEndpoint(const Vector & coord, double * dist)
127 {
128         double minDist = RS_MAXDOUBLE;
129         double curDist;
130         Vector ret;
131
132         for(int i=0; i<4; ++i)
133         {
134                 if (data.corner[i].valid)
135                 {
136                         curDist = data.corner[i].distanceTo(coord);
137
138                         if (curDist < minDist)
139                         {
140                                 ret = data.corner[i];
141                                 minDist = curDist;
142                         }
143                 }
144         }
145
146         if (dist)
147                 *dist = minDist;
148
149         return ret;
150 }
151
152 /**
153  * @todo Implement this.
154  */
155 Vector Solid::getNearestPointOnEntity(const Vector & /*coord*/, bool /*onEntity*/,
156         double * /*dist*/, Entity ** /*entity*/)
157 {
158         Vector ret(false);
159         return ret;
160 }
161
162 Vector Solid::getNearestCenter(const Vector & /*coord*/, double * dist)
163 {
164         if (dist)
165                 *dist = RS_MAXDOUBLE;
166
167         return Vector(false);
168 }
169
170 Vector Solid::getNearestMiddle(const Vector & /*coord*/, double * dist)
171 {
172         if (dist)
173                 *dist = RS_MAXDOUBLE;
174
175         return Vector(false);
176 }
177
178 Vector Solid::getNearestDist(double /*distance*/, const Vector & /*coord*/, double * dist)
179 {
180         if (dist)
181                 *dist = RS_MAXDOUBLE;
182
183         return Vector(false);
184 }
185
186 /**
187  * @return Distance from one of the boundry lines of this solid to given point.
188  *
189  * @todo implement
190  */
191 double Solid::getDistanceToPoint(const Vector & /*coord*/, Entity ** /*entity*/,
192         RS2::ResolveLevel /*level*/, double /*solidDist*/)
193 {
194         return RS_MAXDOUBLE;
195 }
196
197 void Solid::move(Vector offset)
198 {
199         for(int i=0; i<4; ++i)
200                 data.corner[i].move(offset);
201
202         calculateBorders();
203 }
204
205 void Solid::rotate(Vector center, double angle)
206 {
207         for(int i=0; i<4; ++i)
208                 data.corner[i].rotate(center, angle);
209
210         calculateBorders();
211 }
212
213 void Solid::scale(Vector center, Vector factor)
214 {
215         for(int i=0; i<4; ++i)
216                 data.corner[i].scale(center, factor);
217
218         calculateBorders();
219 }
220
221 void Solid::mirror(Vector axisPoint1, Vector axisPoint2)
222 {
223         for(int i=0; i<4; ++i)
224                 data.corner[i].mirror(axisPoint1, axisPoint2);
225
226         calculateBorders();
227 }
228
229 void Solid::draw(PaintInterface * painter, GraphicView * view, double /*patternOffset*/)
230 {
231         if (!painter || !view)
232                 return;
233
234         SolidData d = getData();
235
236         if (isTriangle())
237                 painter->fillTriangle(view->toGui(getCorner(0)), view->toGui(getCorner(1)),
238                         view->toGui(getCorner(2)));
239 }
240
241 /**
242  * Dumps the point's data to stdout.
243  */
244 std::ostream & operator<<(std::ostream & os, const Solid & p)
245 {
246         os << " Solid: " << p.getData() << "\n";
247         return os;
248 }