~librecad-dev/librecad/librecad

« back to all changes in this revision

Viewing changes to librecad/src/lib/engine/rs_vector.cpp

  • Committer: Scott Howard
  • Date: 2014-02-21 19:07:55 UTC
  • Revision ID: showard@debian.org-20140221190755-csjax9wb146hgdq4
first commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** This file is part of the LibreCAD project, a 2D CAD program
 
4
**
 
5
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
 
6
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
 
7
**
 
8
**
 
9
** This file may be distributed and/or modified under the terms of the
 
10
** GNU General Public License version 2 as published by the Free Software
 
11
** Foundation and appearing in the file gpl-2.0.txt included in the
 
12
** packaging of this file.
 
13
**
 
14
** This program is distributed in the hope that it will be useful,
 
15
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
** GNU General Public License for more details.
 
18
**
 
19
** You should have received a copy of the GNU General Public License
 
20
** along with this program; if not, write to the Free Software
 
21
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
22
**
 
23
** This copyright notice MUST APPEAR in all copies of the script!
 
24
**
 
25
**********************************************************************/
 
26
 
 
27
 
 
28
#include "rs_vector.h"
 
29
 
 
30
//#include <values.h>
 
31
 
 
32
#include "rs_debug.h"
 
33
#include "rs_math.h"
 
34
#include "rs_constructionline.h"
 
35
 
 
36
#ifdef EMU_C99
 
37
#include "emu_c99.h" /* remainder() */
 
38
#endif
 
39
 
 
40
/**
 
41
 * Constructor for a point with default coordinates.
 
42
 */
 
43
RS_Vector::RS_Vector() {
 
44
    //RS_DEBUG->print("RS_Vector::RS_Vector");
 
45
 
 
46
#ifdef  RS_VECTOR2D
 
47
    set(0.0, 0.0);
 
48
#else
 
49
    set(0.0, 0.0, 0.0);
 
50
#endif
 
51
}
 
52
 
 
53
 
 
54
 
 
55
/**
 
56
 * Constructor for a point with given coordinates.
 
57
 */
 
58
#ifdef  RS_VECTOR2D
 
59
RS_Vector::RS_Vector(double vx, double vy) {
 
60
    //RS_DEBUG->print("RS_Vector::RS_Vector");
 
61
    set(vx, vy);
 
62
}
 
63
#else
 
64
RS_Vector::RS_Vector(double vx, double vy, double vz) {
 
65
    //RS_DEBUG->print("RS_Vector::RS_Vector");
 
66
    set(vx, vy, vz);
 
67
}
 
68
#endif
 
69
 
 
70
/**
 
71
 * Constructor for a unit vector with given angle
 
72
 */
 
73
RS_Vector::RS_Vector(double angle) {
 
74
    //RS_DEBUG->print("RS_Vector::RS_Vector");
 
75
    x = cos(angle);
 
76
    y = sin(angle);
 
77
#ifndef RS_VECTOR2D
 
78
    z = 0.0;
 
79
#endif
 
80
    valid = true;
 
81
}
 
82
 
 
83
 
 
84
/**
 
85
 * Constructor for a point with given coordinates in an array
 
86
 * or three doubles.
 
87
 */
 
88
//RS_Vector::RS_Vector(double v[]) {
 
89
//    set(v[0], v[1], v[2]);
 
90
//}
 
91
 
 
92
 
 
93
/**
 
94
 * Constructor for a point with given valid flag.
 
95
 *
 
96
 * @param valid true: a valid vector with default coordinates is created.
 
97
 *              false: an invalid vector is created
 
98
 */
 
99
RS_Vector::RS_Vector(bool valid) {
 
100
    //RS_DEBUG->print("RS_Vector::RS_Vector");
 
101
#ifdef  RS_VECTOR2D
 
102
    set(0.0, 0.0);
 
103
#else
 
104
    set(0.0, 0.0, 0.0);
 
105
#endif
 
106
    this->valid = valid;
 
107
}
 
108
 
 
109
 
 
110
/**
 
111
 * Destructor.
 
112
 */
 
113
RS_Vector::~RS_Vector() {
 
114
    //RS_DEBUG->print("RS_Vector::~RS_Vector");
 
115
}
 
116
 
 
117
 
 
118
/**
 
119
 * Sets to a unit vector by the direction angle
 
120
 */
 
121
void RS_Vector::set(double angle) {
 
122
    x = cos(angle);
 
123
    y = sin(angle);
 
124
#ifndef RS_VECTOR2D
 
125
    z = 0.;
 
126
#endif
 
127
    valid = true;
 
128
}
 
129
 
 
130
 
 
131
/**
 
132
 * Sets a new position for the vector.
 
133
 */
 
134
#ifdef  RS_VECTOR2D
 
135
void RS_Vector::set(double vx, double vy) {
 
136
#else
 
137
void RS_Vector::set(double vx, double vy, double vz) {
 
138
#endif
 
139
    x = vx;
 
140
    y = vy;
 
141
#ifndef RS_VECTOR2D
 
142
    z = vz;
 
143
#endif
 
144
    valid = true;
 
145
}
 
146
 
 
147
 
 
148
/**
 
149
 * Sets a new position for the vector in polar coordinates.
 
150
 */
 
151
void RS_Vector::setPolar(double radius, double angle) {
 
152
    x = radius * cos(angle);
 
153
    y = radius * sin(angle);
 
154
#ifndef RS_VECTOR2D
 
155
    z = 0.0;
 
156
#endif
 
157
    valid = true;
 
158
}
 
159
 
 
160
 
 
161
 
 
162
/**
 
163
 * @return The angle from zero to this vector (in rad).
 
164
 */
 
165
double RS_Vector::angle() const {
 
166
    return RS_Math::correctAngle(atan2(y,x));
 
167
//    double ret = 0.0;
 
168
//    double m = magnitude();
 
169
//
 
170
//    if (m>1.0e-6) {
 
171
//              double dp = dotP(*this, RS_Vector(1.0, 0.0));
 
172
//              RS_DEBUG->print("RS_Vector::angle: dp/m: %f/%f", dp, m);
 
173
//              if (dp/m>=1.0) {
 
174
//                      ret = 0.0;
 
175
//              }
 
176
//              else if (dp/m<-1.0) {
 
177
//                      ret = M_PI;
 
178
//              }
 
179
//              else {
 
180
//              ret = acos( dp / m);
 
181
//              }
 
182
//        if (y<0.0) {
 
183
//            ret = 2*M_PI - ret;
 
184
//        }
 
185
//    }
 
186
//    //std::cout<<"New angle="<<fmod(2*M_PI+atan2(y,x),2*M_PI)<<"\tatan2("<<y<<','<<x<<")"<<atan2(y,x)<<std::endl;
 
187
//
 
188
//    return ret;
 
189
}
 
190
 
 
191
 
 
192
 
 
193
/**
 
194
 * @return The angle from this and the given coordinate (in rad).
 
195
 */
 
196
double RS_Vector::angleTo(const RS_Vector& v) const {
 
197
    if (!valid || !v.valid) {
 
198
        return 0.0;
 
199
    }
 
200
    else {
 
201
        return (v-(*this)).angle();
 
202
    }
 
203
}
 
204
 
 
205
/**
 
206
 * @return The angle from between two vectors using the current vector as the center
 
207
 * return 0, if the angle is not well defined
 
208
 */
 
209
double RS_Vector::angleBetween(const RS_Vector& v1, const RS_Vector& v2) const {
 
210
    if (!valid || !v1.valid || !v2.valid) {
 
211
        return 0.0;
 
212
    }
 
213
    else {
 
214
        RS_Vector vStart(v1- (*this));
 
215
        RS_Vector vEnd(v2- (*this));
 
216
        //        if( vStart.magnitude() < RS_TOLERANCE
 
217
        //                || vEnd.magnitude() < RS_TOLERANCE) return 0.0;
 
218
        return RS_Math::correctAngle( atan2( vStart.x*vEnd.y-vStart.y*vEnd.x, vStart.x*vEnd.x+vStart.y*vEnd.y));
 
219
 
 
220
        //         std::cout<<"old algorithm:: "<<RS_Math::correctAngle(vEnd.angle() - vStart.angle())<<std::endl;
 
221
//        return RS_Math::correctAngle(vEnd.angle() - vStart.angle());
 
222
    }
 
223
}
 
224
 
 
225
 
 
226
/**
 
227
 * @return Magnitude (length) of the vector.
 
228
 */
 
229
double RS_Vector::magnitude() const {
 
230
    double ret(0.0);
 
231
    // Note that the z coordinate is also needed for 2d
 
232
    //   (due to definition of crossP())
 
233
    if (valid) {
 
234
#ifdef  RS_VECTOR2D
 
235
        ret = sqrt(x*x + y*y);
 
236
#else
 
237
        ret = sqrt(x*x + y*y + z*z);
 
238
#endif
 
239
    }
 
240
 
 
241
    return ret;
 
242
}
 
243
 
 
244
/**
 
245
  * @return square of vector length
 
246
  */
 
247
double RS_Vector::squared() const {
 
248
    // Note that the z coordinate is also needed for 2d
 
249
    //   (due to definition of crossP())
 
250
    if (valid) {
 
251
#ifdef  RS_VECTOR2D
 
252
        return x*x + y*y;
 
253
#else
 
254
        return x*x + y*y + z*z;
 
255
#endif
 
256
    }
 
257
    return RS_MAXDOUBLE;
 
258
}
 
259
 
 
260
/**
 
261
  * @return square of vector length
 
262
  */
 
263
double RS_Vector::squaredTo(const RS_Vector& v1) const
 
264
{
 
265
    if (valid && v1.valid) {
 
266
        return  (*this - v1).squared();
 
267
    }
 
268
    return RS_MAXDOUBLE;
 
269
}
 
270
 
 
271
/**
 
272
 *
 
273
 */
 
274
RS_Vector RS_Vector::lerp(const RS_Vector& v, double t) const {
 
275
    return RS_Vector(x+(v.x-x)*t, y+(v.y-y)*t);
 
276
}
 
277
 
 
278
 
 
279
/**
 
280
 * @return The distance between this and the given coordinate.
 
281
 */
 
282
double RS_Vector::distanceTo(const RS_Vector& v) const {
 
283
    if (!valid || !v.valid) {
 
284
        return RS_MAXDOUBLE;
 
285
    }
 
286
    else {
 
287
        return (*this-v).magnitude();
 
288
    }
 
289
}
 
290
 
 
291
 
 
292
 
 
293
/**
 
294
 * @return true is this vector is within the given range.
 
295
 */
 
296
bool RS_Vector::isInWindow(const RS_Vector& firstCorner,
 
297
                           const RS_Vector& secondCorner) const {
 
298
    RS_Vector vLow( std::min(firstCorner.x, secondCorner.x), std::min(firstCorner.y, secondCorner.y));
 
299
    RS_Vector vHigh( std::max(firstCorner.x, secondCorner.x), std::max(firstCorner.y, secondCorner.y));
 
300
 
 
301
if(valid==false) return false;
 
302
    return isInWindowOrdered(vLow,vHigh);
 
303
}
 
304
 
 
305
/**
 
306
 * @return true is this vector is within the given range
 
307
 * of ordered vectors
 
308
 */
 
309
bool RS_Vector::isInWindowOrdered(const RS_Vector& vLow,
 
310
                           const RS_Vector& vHigh) const {
 
311
if(valid==false) return false;
 
312
    return (x>=vLow.x && x<=vHigh.x && y>=vLow.y && y<=vHigh.y);
 
313
}
 
314
 
 
315
/**
 
316
 * move to the closest integer point
 
317
 */
 
318
RS_Vector RS_Vector::toInteger() {
 
319
    x= x - remainder(x,1.);
 
320
    y= y - remainder(y,1.);
 
321
    return *this;
 
322
}
 
323
 
 
324
/**
 
325
 * Moves this vector by the given offset. Equal to the operator +=.
 
326
 */
 
327
RS_Vector RS_Vector::move(const RS_Vector& offset) {
 
328
    *this+=offset;
 
329
    return *this;
 
330
}
 
331
 
 
332
 
 
333
 
 
334
/**
 
335
 * Rotates this vector around 0/0 by the given angle.
 
336
 */
 
337
RS_Vector RS_Vector::rotate(const double& ang) {
 
338
//    RS_DEBUG->print("RS_Vector::rotate: angle: %f", ang);
 
339
 
 
340
//    double r = magnitude();
 
341
 
 
342
//    RS_DEBUG->print("RS_Vector::rotate: r: %f", r);
 
343
 
 
344
//    double a = angle() + ang;
 
345
 
 
346
//    RS_DEBUG->print("RS_Vector::rotate: a: %f", a);
 
347
 
 
348
    //    x = cos(a) * r;
 
349
    //    y = sin(a) * r;
 
350
 
 
351
    //    RS_DEBUG->print("RS_Vector::rotate: x/y: %f/%f", x, y);
 
352
    // rotate by direction vector
 
353
    rotate(RS_Vector(ang));
 
354
    return *this;
 
355
}
 
356
 
 
357
/**
 
358
 * Rotates this vector around 0/0 by the given vector
 
359
 * if the vector is a unit, then, it's the same as rotating around
 
360
 * 0/0 by the angle of the vector
 
361
 */
 
362
RS_Vector RS_Vector::rotate(const RS_Vector& angleVector) {
 
363
//        RS_DEBUG->print("RS_Vector::rotate: rotating Vecotr: %g/%g", x,y);
 
364
//        RS_DEBUG->print("RS_Vector::rotate: rotating by Vecotr: %g/%g", angleVector.x,angleVector.y);
 
365
        double x0 = x * angleVector.x - y * angleVector.y;
 
366
        y = x * angleVector.y + y * angleVector.x;
 
367
        x = x0;
 
368
 
 
369
//        RS_DEBUG->print("RS_Vector::rotate: rotated x/y: %f/%f", x, y);
 
370
 
 
371
    return *this;
 
372
}
 
373
 
 
374
 
 
375
/**
 
376
 * Rotates this vector around the given center by the given angle.
 
377
 */
 
378
RS_Vector RS_Vector::rotate(const RS_Vector& center, const double& ang) {
 
379
    *this = center + (*this-center).rotate(ang);
 
380
    return *this;
 
381
}
 
382
RS_Vector RS_Vector::rotate(const RS_Vector& center, const RS_Vector& angleVector) {
 
383
    *this = center + (*this-center).rotate(angleVector);
 
384
    return *this;
 
385
}
 
386
 
 
387
/**
 
388
 * Scales this vector by the given factors with 0/0 as center.
 
389
 */
 
390
RS_Vector RS_Vector::scale(const double& factor) {
 
391
    x *= factor;
 
392
    y *= factor;
 
393
    return *this;
 
394
}
 
395
 
 
396
/**
 
397
 * Scales this vector by the given factors with 0/0 as center.
 
398
 */
 
399
RS_Vector RS_Vector::scale(const RS_Vector& factor) {
 
400
    x *= factor.x;
 
401
    y *= factor.y;
 
402
    return *this;
 
403
}
 
404
 
 
405
/**
 
406
 * Scales this vector by the given factors with the given center.
 
407
 */
 
408
RS_Vector RS_Vector::scale(const RS_Vector& center, const RS_Vector& factor) {
 
409
    *this = center + (*this-center).scale(factor);
 
410
    return *this;
 
411
}
 
412
 
 
413
 
 
414
 
 
415
/**
 
416
 * Mirrors this vector at the given axis, defined by two points on axis.
 
417
 */
 
418
RS_Vector RS_Vector::mirror(const RS_Vector& axisPoint1, const RS_Vector& axisPoint2) {
 
419
    /*
 
420
    RS_ConstructionLine axis(NULL,
 
421
        RS_ConstructionLineData(axisPoint1, axisPoint2));
 
422
 
 
423
    RS_Vector xp = axis.getNearestPointOnEntity(*this);
 
424
    xp = xp - (*this);
 
425
    (*this) += (xp*2);
 
426
    */
 
427
    RS_Vector direction(axisPoint2-axisPoint1);
 
428
    double a= direction.squared();
 
429
    RS_Vector ret(false);
 
430
    if(a<RS_TOLERANCE2) {
 
431
        return ret;
 
432
    }
 
433
    ret= axisPoint1 + direction* dotP(*this - axisPoint1,direction)/a; //projection point
 
434
    *this = ret + ret - *this;
 
435
 
 
436
    return *this;
 
437
}
 
438
 
 
439
 
 
440
 
 
441
/**
 
442
 * Streams the vector components to stdout. e.g.: "1/4/0"
 
443
 */
 
444
std::ostream& operator << (std::ostream& os, const RS_Vector& v) {
 
445
    if(v.valid) {
 
446
#ifdef  RS_VECTOR2D
 
447
        os << v.x << "/" << v.y ;
 
448
#else
 
449
        os << v.x << "/" << v.y << "/" << v.z;
 
450
#endif
 
451
    } else {
 
452
        os << "invalid vector";
 
453
    }
 
454
    return os;
 
455
}
 
456
 
 
457
 
 
458
 
 
459
/**
 
460
 * binary + operator.
 
461
 */
 
462
RS_Vector RS_Vector::operator + (const RS_Vector& v) const {
 
463
#ifdef  RS_VECTOR2D
 
464
    return RS_Vector(x + v.x, y + v.y);
 
465
#else
 
466
    return RS_Vector(x + v.x, y + v.y, z + v.z);
 
467
#endif
 
468
}
 
469
 
 
470
 
 
471
 
 
472
/**
 
473
 * binary - operator.
 
474
 */
 
475
RS_Vector RS_Vector::operator - (const RS_Vector& v) const {
 
476
#ifdef  RS_VECTOR2D
 
477
    return RS_Vector(x - v.x, y - v.y);
 
478
#else
 
479
    return RS_Vector(x - v.x, y - v.y, z - v.z);
 
480
#endif
 
481
}
 
482
 
 
483
 
 
484
/**
 
485
 * binary * operator.
 
486
 */
 
487
RS_Vector RS_Vector::operator * (const double& s) const {
 
488
#ifdef  RS_VECTOR2D
 
489
    return RS_Vector(x * s, y * s);
 
490
#else
 
491
    return RS_Vector(x * s, y * s, z * s);
 
492
#endif
 
493
}
 
494
 
 
495
 
 
496
 
 
497
/**
 
498
 * binary / operator.
 
499
 */
 
500
RS_Vector RS_Vector::operator / (const double& s) const {
 
501
#ifdef  RS_VECTOR2D
 
502
    return RS_Vector(x / s, y / s);
 
503
#else
 
504
    return RS_Vector(x / s, y / s, z / s);
 
505
#endif
 
506
}
 
507
 
 
508
 
 
509
 
 
510
/**
 
511
 * unary - operator.
 
512
 */
 
513
RS_Vector RS_Vector::operator - () const {
 
514
#ifdef  RS_VECTOR2D
 
515
    return RS_Vector(-x, -y);
 
516
#else
 
517
    return RS_Vector(-x, -y, -z);
 
518
#endif
 
519
}
 
520
 
 
521
 
 
522
 
 
523
/**
 
524
 * Scalarproduct (dot product).
 
525
 */
 
526
double RS_Vector::dotP(const RS_Vector& v1)
 
527
{
 
528
    return x*v1.x+y*v1.y;
 
529
}
 
530
 
 
531
double RS_Vector::dotP(const RS_Vector& v1, const RS_Vector& v2) {
 
532
#ifdef  RS_VECTOR2D
 
533
    return v1.x * v2.x + v1.y * v2.y;
 
534
#else
 
535
    return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
 
536
#endif
 
537
}
 
538
 
 
539
 
 
540
/** switch x,y for all vectors */
 
541
RS_Vector RS_Vector::flipXY(void) const{
 
542
        return RS_Vector(y,x);
 
543
}
 
544
 
 
545
/**
 
546
 * += operator. Assert: both vectors must be valid.
 
547
 */
 
548
void RS_Vector::operator += (const RS_Vector& v) {
 
549
    x += v.x;
 
550
    y += v.y;
 
551
#ifndef RS_VECTOR2D
 
552
    z += v.z;
 
553
#endif
 
554
}
 
555
 
 
556
 
 
557
/**
 
558
 * -= operator
 
559
 */
 
560
void RS_Vector::operator -= (const RS_Vector& v) {
 
561
    x -= v.x;
 
562
    y -= v.y;
 
563
#ifndef RS_VECTOR2D
 
564
    z -= v.z;
 
565
#endif
 
566
}
 
567
 
 
568
 
 
569
 
 
570
/**
 
571
 * *= operator
 
572
 */
 
573
void RS_Vector::operator *= (const double& s) {
 
574
    x *= s;
 
575
    y *= s;
 
576
#ifndef RS_VECTOR2D
 
577
    z *= s;
 
578
#endif
 
579
}
 
580
/**
 
581
 * /= operator
 
582
 */
 
583
void RS_Vector::operator /= (const double& s) {
 
584
    if(fabs(s)>RS_TOLERANCE) {
 
585
    x /= s;
 
586
    y /= s;
 
587
#ifndef RS_VECTOR2D
 
588
    z /= s;
 
589
#endif
 
590
    }
 
591
}
 
592
 
 
593
 
 
594
 
 
595
/**
 
596
 * == operator
 
597
 */
 
598
bool RS_Vector::operator == (const RS_Vector& v) const {
 
599
#ifdef  RS_VECTOR2D
 
600
    return (x==v.x && y==v.y && valid==v.valid);
 
601
#else
 
602
    return (x==v.x && y==v.y && z==v.z && valid==v.valid);
 
603
#endif
 
604
}
 
605
 
 
606
 
 
607
 
 
608
/**
 
609
 * @return A vector with the minimum components from the vectors v1 and v2.
 
610
 * These might be mixed components from both vectors.
 
611
 */
 
612
RS_Vector RS_Vector::minimum (const RS_Vector& v1, const RS_Vector& v2) {
 
613
    return RS_Vector (std::min(v1.x, v2.x),
 
614
                      std::min(v1.y, v2.y)
 
615
#ifndef RS_VECTOR2D
 
616
                      , std::min(v1.z, v2.z)
 
617
#endif
 
618
                      );
 
619
}
 
620
 
 
621
 
 
622
 
 
623
/**
 
624
 * @return A vector with the maximum values from the vectors v1 and v2
 
625
 */
 
626
RS_Vector RS_Vector::maximum (const RS_Vector& v1, const RS_Vector& v2) {
 
627
    return RS_Vector (std::max(v1.x, v2.x),
 
628
                      std::max(v1.y, v2.y)
 
629
#ifndef RS_VECTOR2D
 
630
                      , std::max(v1.z, v2.z)
 
631
#endif
 
632
                      );
 
633
}
 
634
 
 
635
 
 
636
 
 
637
/**
 
638
 * @return Cross product of two vectors.
 
639
 *  we don't need cross product for 2D vectors
 
640
 */
 
641
#ifndef RS_VECTOR2D
 
642
RS_Vector RS_Vector::crossP(const RS_Vector& v1, const RS_Vector& v2) {
 
643
    return RS_Vector(v1.y*v2.z - v1.z*v2.y,
 
644
                     v1.z*v2.x - v1.x*v2.z,
 
645
                     v1.x*v2.y - v1.y*v2.x);
 
646
}
 
647
#endif
 
648
 
 
649
 
 
650
/**
 
651
 * Constructor for no solution.
 
652
 */
 
653
RS_VectorSolutions::RS_VectorSolutions() {
 
654
    vector.clear();
 
655
    tangent=false;
 
656
}
 
657
 
 
658
 
 
659
 
 
660
/**
 
661
 * Copy constructor
 
662
 */
 
663
RS_VectorSolutions::RS_VectorSolutions(const RS_VectorSolutions& s)
 
664
    {
 
665
    setTangent(s.isTangent());
 
666
    vector=s.vector;
 
667
}
 
668
 
 
669
 
 
670
 
 
671
/**
 
672
 * Constructor for num solutions.
 
673
 */
 
674
RS_VectorSolutions::RS_VectorSolutions(int num) {
 
675
#if QT_VERSION >= 0x040700
 
676
    vector.reserve(num);
 
677
#else
 
678
        for(int i=vector.size();i<num;i++){
 
679
            vector.push_back(RS_Vector(false));
 
680
        }
 
681
#endif
 
682
}
 
683
 
 
684
 
 
685
 
 
686
/**
 
687
 * Constructor for one solution.
 
688
 */
 
689
RS_VectorSolutions::RS_VectorSolutions(const RS_Vector& v1) {
 
690
    vector.push_back(v1);
 
691
    tangent = false;
 
692
}
 
693
 
 
694
 
 
695
 
 
696
/**
 
697
 * Constructor for two solutions.
 
698
 */
 
699
RS_VectorSolutions::RS_VectorSolutions(const RS_Vector& v1,
 
700
                                       const RS_Vector& v2) {
 
701
    vector.push_back(v1);
 
702
    vector.push_back(v2);
 
703
    tangent = false;
 
704
}
 
705
 
 
706
 
 
707
 
 
708
/**
 
709
 * Constructor for three solutions.
 
710
 */
 
711
RS_VectorSolutions::RS_VectorSolutions(const RS_Vector& v1,
 
712
                                       const RS_Vector& v2,
 
713
                                       const RS_Vector& v3) {
 
714
    vector.push_back(v1);
 
715
    vector.push_back(v2);
 
716
    vector.push_back(v3);
 
717
    tangent = false;
 
718
}
 
719
 
 
720
 
 
721
/**
 
722
 * Constructor for four solutions.
 
723
 */
 
724
RS_VectorSolutions::RS_VectorSolutions(const RS_Vector& v1,
 
725
                                       const RS_Vector& v2,
 
726
                                       const RS_Vector& v3,
 
727
                                       const RS_Vector& v4) {
 
728
    vector.push_back(v1);
 
729
    vector.push_back(v2);
 
730
    vector.push_back(v3);
 
731
    vector.push_back(v4);
 
732
    tangent = false;
 
733
}
 
734
 
 
735
 
 
736
/**
 
737
 * Constructor for four solutions.
 
738
 */
 
739
RS_VectorSolutions::RS_VectorSolutions(const RS_Vector& v1,
 
740
                                       const RS_Vector& v2,
 
741
                                       const RS_Vector& v3,
 
742
                                       const RS_Vector& v4,
 
743
                                       const RS_Vector& v5) {
 
744
    vector.push_back(v1);
 
745
    vector.push_back(v2);
 
746
    vector.push_back(v3);
 
747
    vector.push_back(v4);
 
748
    vector.push_back(v5);
 
749
    tangent = false;
 
750
}
 
751
 
 
752
 
 
753
 
 
754
/**
 
755
 * Destructor.
 
756
 */
 
757
RS_VectorSolutions::~RS_VectorSolutions() {
 
758
    vector.clear();
 
759
}
 
760
 
 
761
 
 
762
/**
 
763
 * Allocates 'num' vectors.
 
764
 */
 
765
void RS_VectorSolutions::alloc(int num) {
 
766
#if QT_VERSION >= 0x040700
 
767
    vector.reserve(num);
 
768
#else
 
769
    if(vector.size() <num) {
 
770
        for(int i=vector.size();i<num;i++){
 
771
            vector.push_back(RS_Vector(false));
 
772
        }
 
773
    }
 
774
#endif
 
775
    if(vector.size()>num) {
 
776
        vector.erase(vector.begin()+num, vector.end());
 
777
    }
 
778
   // tangent = false;
 
779
}
 
780
 
 
781
/**
 
782
 * Deletes vector array and resets everything.
 
783
 */
 
784
void RS_VectorSolutions::clear() {
 
785
    vector.clear();
 
786
    tangent = false;
 
787
}
 
788
 
 
789
 
 
790
 
 
791
/**
 
792
 * @return vector solution number i or an invalid vector if there
 
793
 * are less solutions.
 
794
 */
 
795
RS_Vector RS_VectorSolutions::at(int i) const {
 
796
    if (i<vector.size()) {
 
797
        return vector[i];
 
798
    } else {
 
799
        return RS_Vector(false);
 
800
    }
 
801
}
 
802
 
 
803
 
 
804
 
 
805
/**
 
806
 * @return Number of solutions available.
 
807
 */
 
808
int RS_VectorSolutions::getNumber() const {
 
809
    return vector.size();
 
810
}
 
811
 
 
812
 
 
813
 
 
814
/**
 
815
 * @retval true There's at least one valid solution.
 
816
 * @retval false There's no valid solution.
 
817
 */
 
818
bool RS_VectorSolutions::hasValid() const {
 
819
    for (int i=0; i<vector.size(); i++) {
 
820
        if (vector[i].valid) {
 
821
            return true;
 
822
        }
 
823
    }
 
824
 
 
825
    return false;
 
826
}
 
827
 
 
828
void RS_VectorSolutions::resize(size_t n){
 
829
    vector.resize(n);
 
830
}
 
831
 
 
832
QVector<RS_Vector> RS_VectorSolutions::getVector() const {
 
833
    return vector;
 
834
}
 
835
 
 
836
void RS_VectorSolutions::push_back(const RS_Vector& v) {
 
837
        vector.push_back(v);
 
838
}
 
839
 
 
840
void RS_VectorSolutions::removeAt(const int i){
 
841
    if (vector.size()> i)
 
842
        vector.remove(i);
 
843
}
 
844
 
 
845
RS_VectorSolutions RS_VectorSolutions::appendTo(const RS_VectorSolutions& v) {
 
846
    vector += v.getVector();
 
847
    return *this;
 
848
}
 
849
 
 
850
/**
 
851
 * Sets the solution i to the given vector.
 
852
 * If i is greater than the current number of solutions available,
 
853
 * nothing happens.
 
854
 */
 
855
void RS_VectorSolutions::set(int i, const RS_Vector& v) {
 
856
    if (i<vector.size()) {
 
857
        vector[i] = v;
 
858
    }else{
 
859
//            RS_DEBUG->print(RS_Debug::D_ERROR, "set member in vector in RS_VectorSolutions: out of range, %d to size of %d", i,vector.size());
 
860
        for(int j=vector.size();j<=i;j++)
 
861
            vector.push_back(v);
 
862
    }
 
863
}
 
864
 
 
865
 
 
866
 
 
867
/**
 
868
 * Sets the tangent flag.
 
869
 */
 
870
void RS_VectorSolutions::setTangent(bool t) {
 
871
    tangent = t;
 
872
}
 
873
 
 
874
 
 
875
 
 
876
/**
 
877
 * @return true if at least one of the solutions is a double solution
 
878
 * (tangent).
 
879
 */
 
880
bool RS_VectorSolutions::isTangent() const {
 
881
    return tangent;
 
882
}
 
883
 
 
884
 
 
885
/**
 
886
 * Rotates all vectors around (0,0) by the given angle.
 
887
 */
 
888
void RS_VectorSolutions::rotate(const double& ang) {
 
889
    RS_Vector angleVector(ang);
 
890
    for (int i=0; i<vector.size(); i++) {
 
891
        if (vector[i].valid) {
 
892
            vector[i].rotate(angleVector);
 
893
        }
 
894
    }
 
895
}
 
896
 
 
897
/**
 
898
 * Rotates all vectors around (0,0) by the given angleVector.
 
899
 */
 
900
void RS_VectorSolutions::rotate(const RS_Vector& angleVector) {
 
901
    for (int i=0; i<vector.size(); i++) {
 
902
        if (vector[i].valid) {
 
903
                //To be a real rotation, the determinant of angleVector has to be 1 for a pure rotation
 
904
            vector[i].rotate(angleVector);
 
905
        }
 
906
    }
 
907
}
 
908
 
 
909
/**
 
910
 * Rotates all vectors around the given center by the given angle.
 
911
 */
 
912
void RS_VectorSolutions::rotate(const RS_Vector& center, const double& ang) {
 
913
    RS_Vector angleVector(ang);
 
914
    for (int i=0; i<vector.size(); i++) {
 
915
        if (vector[i].valid) {
 
916
            vector[i].rotate(center,angleVector);
 
917
        }
 
918
    }
 
919
}
 
920
void RS_VectorSolutions::rotate(const RS_Vector& center, const RS_Vector& angleVector) {
 
921
    for (int i=0; i<vector.size(); i++) {
 
922
        if (vector[i].valid) {
 
923
            vector[i].rotate(center,angleVector);
 
924
        }
 
925
    }
 
926
}
 
927
 
 
928
/**
 
929
 * Move all vectors around the given center by the given vector.
 
930
 */
 
931
void RS_VectorSolutions::move(const RS_Vector& vp) {
 
932
    for (int i=0; i<vector.size(); i++) {
 
933
        if (vector[i].valid) vector[i].move(vp);
 
934
    }
 
935
}
 
936
 
 
937
 
 
938
/**
 
939
 * Scales all vectors by the given factors with the given center.
 
940
 */
 
941
void RS_VectorSolutions::scale(const RS_Vector& center, const RS_Vector& factor) {
 
942
    for (int i=0; i<vector.size(); i++) {
 
943
        if (vector[i].valid) {
 
944
            vector[i].scale(center, factor);
 
945
        }
 
946
    }
 
947
}
 
948
void RS_VectorSolutions::scale( const RS_Vector& factor) {
 
949
    for (int i=0; i<vector.size(); i++) {
 
950
        if (vector[i].valid) {
 
951
            vector[i].scale(factor);
 
952
        }
 
953
    }
 
954
}
 
955
 
 
956
 
 
957
/**
 
958
 * @return vector solution which is the closest to the given coordinate.
 
959
 * dist will contain the distance if it doesn't point to NULL (default).
 
960
 */
 
961
RS_Vector RS_VectorSolutions::getClosest(const RS_Vector& coord,
 
962
                                         double* dist, int* index) const {
 
963
 
 
964
    double curDist(0.);
 
965
    double minDist = RS_MAXDOUBLE;
 
966
    RS_Vector closestPoint(false);
 
967
    int pos(0);
 
968
 
 
969
    for (int i=0; i<vector.size(); i++) {
 
970
        if (vector[i].valid) {
 
971
            curDist = (coord - vector[i]).squared();
 
972
 
 
973
            if (curDist<minDist) {
 
974
                closestPoint = vector[i];
 
975
                minDist = curDist;
 
976
                pos=i;
 
977
            }
 
978
        }
 
979
    }
 
980
    if (dist!=NULL) {
 
981
        *dist = sqrt(minDist);
 
982
    }
 
983
    if (index!=NULL) {
 
984
        *index = pos;
 
985
    }
 
986
    return closestPoint;
 
987
}
 
988
/**
 
989
  *@ return the closest distance from the first counts rs_vectors
 
990
  *@coord, distance to this point
 
991
  *@counts, only consider this many points within solution
 
992
  */
 
993
double RS_VectorSolutions::getClosestDistance(const RS_Vector& coord,
 
994
        int counts)
 
995
{
 
996
    double ret=RS_MAXDOUBLE*RS_MAXDOUBLE;
 
997
    int i=vector.size();
 
998
    if (counts<i && counts>=0) i=counts;
 
999
    for(int j=0; j<i; j++) {
 
1000
        if(vector[j].valid) {
 
1001
            double d=(coord - vector[j]).squared();
 
1002
            if(d<ret) ret=d;
 
1003
        }
 
1004
    }
 
1005
    return sqrt(ret);
 
1006
}
 
1007
 
 
1008
/** switch x,y for all vectors */
 
1009
RS_VectorSolutions RS_VectorSolutions::flipXY(void) const
 
1010
{
 
1011
        RS_VectorSolutions ret;
 
1012
        const int counts=vector.size();
 
1013
        for(int i=0;i<counts;i++) ret.push_back(vector[i].flipXY());
 
1014
        return ret;
 
1015
}
 
1016
 
 
1017
RS_VectorSolutions RS_VectorSolutions::operator = (const RS_VectorSolutions& s) {
 
1018
    setTangent(s.isTangent());
 
1019
    vector=s.vector;
 
1020
 
 
1021
    return *this;
 
1022
}
 
1023
 
 
1024
 
 
1025
std::ostream& operator << (std::ostream& os,
 
1026
                           const RS_VectorSolutions& s) {
 
1027
    for (int i=0; i<s.getNumber(); ++i) {
 
1028
        os << "(" << s.get(i) << ")\n";
 
1029
    }
 
1030
    os << " tangent: " << (int)s.isTangent() << "\n";
 
1031
    return os;
 
1032
}
 
1033
 
 
1034