]> Shamusworld >> Repos - architektonas/blob - src/base/rs_solid.cpp
Changed RS_Graphic to Drawing; this is less confusing as a drawing is
[architektonas] / src / base / rs_solid.cpp
1 // rs_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 // (C) 2010 Underground Software
7 //
8 // JLH = James L. Hammons <jlhamm@acm.org>
9 //
10 // Who  When        What
11 // ---  ----------  -----------------------------------------------------------
12 // JLH  06/02/2010  Added this text. :-)
13 //
14
15 #include "rs_solid.h"
16
17 #include "rs_graphicview.h"
18 #include "paintintf.h"
19
20 /**
21  * Default constructor.
22  */
23 RS_Solid::RS_Solid(RS_EntityContainer * parent, const RS_SolidData& d):
24         RS_AtomicEntity(parent), data(d)
25 {
26         calculateBorders();
27 }
28
29 /**
30  * @return Corner number 'num'.
31  */
32 Vector RS_Solid::getCorner(int num)
33 {
34         if (num >= 0 && num < 4)
35         {
36                 return data.corner[num];
37         }
38         else
39         {
40                 RS_DEBUG->print("Illegal corner requested from Solid", RS_Debug::D_WARNING);
41                 return Vector(false);
42         }
43 }
44
45 /**
46  * Shapes this Solid into a standard arrow (used in dimensions).
47  *
48  * @param point The point the arrow points to.
49  * @param angle Direction of the arrow.
50  * @param arrowSize Size of arrow (length).
51  */
52 void RS_Solid::shapeArrow(const Vector & point, double angle, double arrowSize)
53 {
54         double cosv1, sinv1, cosv2, sinv2;
55         double arrowSide = arrowSize/cos(0.165);
56
57         cosv1 = cos(angle+0.165)*arrowSide;
58         sinv1 = sin(angle+0.165)*arrowSide;
59         cosv2 = cos(angle-0.165)*arrowSide;
60         sinv2 = sin(angle-0.165)*arrowSide;
61
62         data.corner[0] = point;
63         data.corner[1] = Vector(point.x - cosv1, point.y - sinv1);
64         data.corner[2] = Vector(point.x - cosv2, point.y - sinv2);
65         data.corner[3] = Vector(false);
66
67         calculateBorders();
68 }
69
70 void RS_Solid::calculateBorders()
71 {
72         resetBorders();
73
74         for(int i=0; i<4; ++i)
75         {
76                 if (data.corner[i].valid)
77                 {
78                         minV = Vector::minimum(minV, data.corner[i]);
79                         maxV = Vector::maximum(maxV, data.corner[i]);
80                 }
81         }
82 }
83
84 Vector RS_Solid::getNearestEndpoint(const Vector & coord, double * dist)
85 {
86         double minDist = RS_MAXDOUBLE;
87         double curDist;
88         Vector ret;
89
90         for (int i=0; i<4; ++i)
91         {
92                 if (data.corner[i].valid)
93                 {
94                         curDist = data.corner[i].distanceTo(coord);
95
96                         if (curDist < minDist)
97                         {
98                                 ret = data.corner[i];
99                                 minDist = curDist;
100                         }
101                 }
102         }
103
104         if (dist != NULL)
105                 *dist = minDist;
106
107         return ret;
108 }
109
110 /**
111  * @todo Implement this.
112  */
113 Vector RS_Solid::getNearestPointOnEntity(const Vector & /*coord*/,
114         bool /*onEntity*/, double * /*dist*/, RS_Entity ** /*entity*/)
115 {
116         Vector ret(false);
117         return ret;
118 }
119
120 Vector RS_Solid::getNearestCenter(const Vector & /*coord*/, double * dist)
121 {
122         if (dist != NULL)
123                 *dist = RS_MAXDOUBLE;
124
125         return Vector(false);
126 }
127
128 Vector RS_Solid::getNearestMiddle(const Vector & /*coord*/, double * dist)
129 {
130     if (dist != NULL)
131         *dist = RS_MAXDOUBLE;
132
133         return Vector(false);
134 }
135
136 Vector RS_Solid::getNearestDist(double /*distance*/, const Vector & /*coord*/, double * dist)
137 {
138     if (dist != NULL)
139         *dist = RS_MAXDOUBLE;
140
141         return Vector(false);
142 }
143
144 /**
145  * @return Distance from one of the boundry lines of this solid to given point.
146  *
147  * @todo implement
148  */
149 double RS_Solid::getDistanceToPoint(const Vector & /*coord*/, RS_Entity ** /*entity*/,
150         RS2::ResolveLevel /*level*/, double /*solidDist*/)
151 {
152         return RS_MAXDOUBLE;
153 }
154
155 void RS_Solid::move(Vector offset)
156 {
157         for(int i=0; i<4; ++i)
158                 data.corner[i].move(offset);
159
160         calculateBorders();
161 }
162
163 void RS_Solid::rotate(Vector center, double angle)
164 {
165         for(int i=0; i<4; ++i)
166                 data.corner[i].rotate(center, angle);
167
168         calculateBorders();
169 }
170
171 void RS_Solid::scale(Vector center, Vector factor)
172 {
173         for(int i=0; i<4; ++i)
174                 data.corner[i].scale(center, factor);
175
176         calculateBorders();
177 }
178
179 void RS_Solid::mirror(Vector axisPoint1, Vector axisPoint2)
180 {
181         for(int i=0; i<4; ++i)
182                 data.corner[i].mirror(axisPoint1, axisPoint2);
183
184         calculateBorders();
185 }
186
187 //void RS_Solid::draw(RS_Painter* painter, RS_GraphicView* view, double /*patternOffset*/)
188 void RS_Solid::draw(PaintInterface * painter, RS_GraphicView * view, double /*patternOffset*/)
189 {
190         if (painter == NULL || view == NULL)
191                 return;
192
193         RS_SolidData d = getData();
194
195         if (isTriangle())
196                 painter->fillTriangle(view->toGui(getCorner(0)), view->toGui(getCorner(1)),
197                         view->toGui(getCorner(2)));
198 }
199
200 /**
201  * Dumps the point's data to stdout.
202  */
203 std::ostream & operator<<(std::ostream & os, const RS_Solid & p)
204 {
205         os << " Solid: " << p.getData() << "\n";
206         return os;
207 }