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