]> Shamusworld >> Repos - architektonas/blob - src/base/vectorsolutions.cpp
Final round of dialogs/forms needing to be converted from Qt3 to 4
[architektonas] / src / base / vectorsolutions.cpp
1 // vectorsolutions.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/21/2010  Added this text. :-)
13 //
14
15 #include "vectorsolutions.h"
16
17 #include "rs.h"                                                                 // For RS_MIN/MAXDOUBLE (!)
18 #include "rs_math.h"
19
20 /**
21  * Constructor for no solution.
22  */
23 VectorSolutions::VectorSolutions(): vector(NULL)
24 {
25         clean();
26 }
27
28 /**
29  * Copy constructor
30  */
31 VectorSolutions::VectorSolutions(const VectorSolutions & s): vector(NULL)
32 {
33         alloc(s.getNumber());
34         setTangent(s.isTangent());
35
36         for(int i=0; i<s.getNumber(); ++i)
37                 set(i, s.get(i));
38 }
39
40 /**
41  * Constructor for num solutions.
42  */
43 VectorSolutions::VectorSolutions(int num): vector(NULL)
44 {
45         alloc(num);
46 }
47
48 /**
49  * Constructor for one solution.
50  */
51 VectorSolutions::VectorSolutions(const Vector & v1)
52 {
53         num = 1;
54         vector = new Vector[num];
55         vector[0] = v1;
56         tangent = false;
57 }
58
59 /**
60  * Constructor for two solutions.
61  */
62 VectorSolutions::VectorSolutions(const Vector & v1, const Vector & v2)
63 {
64         num = 2;
65         vector = new Vector[num];
66         vector[0] = v1;
67         vector[1] = v2;
68         tangent = false;
69 }
70
71 /**
72  * Constructor for three solutions.
73  */
74 VectorSolutions::VectorSolutions(const Vector & v1, const Vector & v2, const Vector & v3)
75 {
76         num = 3;
77         vector = new Vector[num];
78         vector[0] = v1;
79         vector[1] = v2;
80         vector[2] = v3;
81         tangent = false;
82 }
83
84 /**
85  * Constructor for four solutions.
86  */
87 VectorSolutions::VectorSolutions(const Vector & v1, const Vector & v2, const Vector & v3,
88         const Vector & v4)
89 {
90         num = 4;
91         vector = new Vector[num];
92         vector[0] = v1;
93         vector[1] = v2;
94         vector[2] = v3;
95         vector[3] = v4;
96         tangent = false;
97 }
98
99 /**
100  * Constructor for four solutions.
101  */
102 VectorSolutions::VectorSolutions(const Vector & v1, const Vector & v2, const Vector & v3,
103         const Vector & v4, const Vector & v5)
104 {
105         num = 5;
106         vector = new Vector[num];
107         vector[0] = v1;
108         vector[1] = v2;
109         vector[2] = v3;
110         vector[3] = v4;
111         vector[4] = v5;
112         tangent = false;
113 }
114
115 /**
116  * Destructor.
117  */
118 VectorSolutions::~VectorSolutions()
119 {
120         clean();
121 }
122
123 /**
124  * Allocates 'num' vectors.
125  */
126 void VectorSolutions::alloc(int num)
127 {
128         clean();
129         this->num = num;
130         vector = new Vector[num];
131
132         for(int i=0; i<num; ++i)
133                 vector[i] = Vector(false);
134
135         tangent = false;
136 }
137
138 /**
139  * Deletes vector array and resets everything.
140  */
141 void VectorSolutions::clean()
142 {
143         if (vector != NULL)
144                 delete[] vector;
145
146         vector = NULL;
147         num = 0;
148         tangent = false;
149 }
150
151 /**
152  * @return vector solution number i or an invalid vector if there
153  * are less solutions.
154  */
155 Vector VectorSolutions::get(int i) const
156 {
157         if (i < num)
158                 return vector[i];
159         else
160                 return Vector(false);
161 }
162
163 /**
164  * @return Number of solutions available.
165  */
166 int VectorSolutions::getNumber() const
167 {
168         return num;
169 }
170
171 /**
172  * @retval true There's at least one valid solution.
173  * @retval false There's no valid solution.
174  */
175 bool VectorSolutions::hasValid() const
176 {
177         for(int i=0; i<num; i++)
178                 if (vector[i].valid)
179                         return true;
180
181         return false;
182 }
183
184 /**
185  * Sets the solution i to the given vector.
186  * If i is greater than the current number of solutions available,
187  * nothing happens.
188  */
189 void VectorSolutions::set(int i, const Vector & v)
190 {
191         if (i < num)
192                 vector[i] = v;
193 }
194
195 /**
196  * Sets the tangent flag.
197  */
198 void VectorSolutions::setTangent(bool t)
199 {
200         tangent = t;
201 }
202
203 /**
204  * @return true if at least one of the solutions is a double solution
205  * (tangent).
206  */
207 bool VectorSolutions::isTangent() const
208 {
209         return tangent;
210 }
211
212 /**
213  * Rotates all vectors around the given center by the given angle.
214  */
215 void VectorSolutions::rotate(Vector center, double ang)
216 {
217         for(int i=0; i<num; i++)
218                 if (vector[i].valid)
219                         vector[i].rotate(center, ang);
220 }
221
222 /**
223  * Scales all vectors by the given factors with the given center.
224  */
225 void VectorSolutions::scale(Vector center, Vector factor)
226 {
227         for(int i=0; i<num; i++)
228                 if (vector[i].valid)
229                         vector[i].scale(center, factor);
230 }
231
232 /**
233  * @return vector solution which is the closest to the given coordinate.
234  * dist will contain the distance if it doesn't point to NULL (default).
235  */
236 Vector VectorSolutions::getClosest(const Vector & coord, double * dist, int * index) const
237 {
238         double curDist;
239         double minDist = RS_MAXDOUBLE;
240         Vector closestPoint(false);
241
242         for(int i=0; i<num; i++)
243         {
244                 if (vector[i].valid)
245                 {
246                         curDist = coord.distanceTo(vector[i]);
247
248                         if (curDist < minDist)
249                         {
250                                 closestPoint = vector[i];
251                                 minDist = curDist;
252
253                                 if (dist != NULL)
254                                         *dist = curDist;
255
256                                 if (index != NULL)
257                                         *index = i;
258                         }
259                 }
260         }
261
262         return closestPoint;
263 }
264
265 VectorSolutions VectorSolutions::operator=(const VectorSolutions & s)
266 {
267         alloc(s.getNumber());
268         setTangent(s.isTangent());
269
270         for (int i=0; i<s.getNumber(); ++i)
271                 set(i, s.get(i));
272
273         return *this;
274 }
275
276 std::ostream& operator << (std::ostream& os, const VectorSolutions& s)
277 {
278         for(int i=0; i<s.num; ++i)
279                 os << "(" << s.get(i) << ")\n";
280
281         os << " tangent: " << (int)s.isTangent() << "\n";
282         return os;
283 }