Library of Assembled Shared Sources
vector_2d.inl
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2022 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45#ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_VECTOR_2D_INL
46#define LASS_GUARDIAN_OF_INCLUSION_PRIM_VECTOR_2D_INL
47
48
49
50
51#include "vector_2d.h"
52#include "../num/basic_ops.h"
53#include "../num/distribution.h"
54#include <random>
55
56namespace lass
57{
58
59namespace prim
60{
61
62template<typename T> inline
63Vector2D<T>::Vector2D():
64 x(T()),
65 y(T())
66{
67}
68
69
70
71template<typename T> inline
72Vector2D<T>::Vector2D(TParam x, TParam y):
73 x(x),
74 y(y)
75{
76}
77
78
79
80template <typename T>
81template <typename U>
82Vector2D<T>::Vector2D(const Vector2D<U>& other):
83 x(static_cast<TValue>(other.x)),
84 y(static_cast<TValue>(other.y))
85{
86}
87
88
89
90template <typename T>
91template <typename U>
92Vector2D<T>::Vector2D(const U& x, const U& y):
93 x(static_cast<TValue>(x)),
94 y(static_cast<TValue>(y))
95{
96}
97
98
99
100template<typename T> inline
101typename Vector2D<T>::TConstReference Vector2D<T>::operator[](size_t index) const
102{
103 LASS_ASSERT(index < dimension);
104 return *(&x + index);
106
108
109template<typename T> inline
110typename Vector2D<T>::TReference Vector2D<T>::operator[](size_t index)
112 LASS_ASSERT(index < dimension);
113 return *(&x + index);
117
118/** Wrap index around range.
119 */
120template<typename T> inline
121typename Vector2D<T>::TConstReference Vector2D<T>::at(signed index) const
123 return *(&x + num::mod(index, dimension));
127
128/** Wrap index around range.
129 */
130template<typename T> inline
131typename Vector2D<T>::TReference Vector2D<T>::at(signed index)
133 return *(&x + num::mod(index, dimension));
134}
135
136
137
138/** A weird way to get back the same object
139 */
140template<typename T> inline
141const Vector2D<T>& Vector2D<T>::operator+() const
142{
143 return *this;
144}
145
146
147
148template<typename T> inline
149const Vector2D<T> Vector2D<T>::operator-() const
150{
151 return Vector2D(-x, -y);
152}
153
154
155
156/** componentwise addition
157 */
158template<typename T> inline
159Vector2D<T>& Vector2D<T>::operator+=(const Vector2D<T>& other)
160{
161 x += other.x;
162 y += other.y;
163 return *this;
164}
165
166
167
168/** componentwise subtraction
169 */
170template<typename T> inline
171Vector2D<T>& Vector2D<T>::operator-=(const Vector2D<T>& other)
172{
173 x -= other.x;
174 y -= other.y;
175 return *this;
176}
177
178
179
180/** Componentwise multiplication.
181 */
182template<typename T> inline
183Vector2D<T>& Vector2D<T>::operator*=(const Vector2D<T>& other)
184{
185 x *= other.x;
186 y *= other.y;
187 return *this;
188}
189
190
191
192/** Componentwise division.
193 */
194template<typename T> inline
195Vector2D<T>& Vector2D<T>::operator/=(const Vector2D<T>& other)
196{
197 x /= other.x;
198 y /= other.y;
199 return *this;
200}
201
202
203
204/** add other to each component of this.
205 */
206template<typename T> inline
207Vector2D<T>& Vector2D<T>::operator+=(TParam other)
208{
209 x += other;
210 y += other;
211 return *this;
212}
213
214
215
216/** subtract other of each component of this.
217 */
218template<typename T> inline
219Vector2D<T>& Vector2D<T>::operator-=(TParam other)
220{
221 x -= other;
222 y -= other;
223 return *this;
224}
225
226
227
228/** multiply each component of this with other.
229 */
230template<typename T> inline
231Vector2D<T>& Vector2D<T>::operator*=(TParam other)
232{
233 x *= other;
234 y *= other;
235 return *this;
236}
237
238
239
240/** divide each component of this by other.
241 */
242template<typename T> inline
243Vector2D<T>& Vector2D<T>::operator/=(TParam other)
244{
245 x /= other;
246 y /= other;
247 return *this;
248}
249
250
251
252/** Return true if all the components are (exactly!) zero
253 */
254template<typename T> inline
256{
257 return x == TNumTraits::zero && y == TNumTraits::zero;
258}
259
260
261
262/** Return true if at least one of the components is NaN
263 */
264template<typename T> inline
266{
267 return num::isNaN(x) || num::isNaN(y);
268}
269
270
271
272/** Return squared norm of vector.
273 */
274template<typename T> inline
275const typename Vector2D<T>::TValue Vector2D<T>::squaredNorm() const
276{
277 return dot(*this, *this);
278}
279
280
281
282/** Return norm of vector.
283 */
284template<typename T> inline
285const typename Vector2D<T>::TValue Vector2D<T>::norm() const
286{
287 return ::lass::num::sqrt(squaredNorm());
288}
289
290
291
292/** return a unit vector with same direction/sense as this vector.
293 *
294 * <i>The normalized vector of <b>X</b> is a vector in the same direction but with norm (length) 1.
295 * It is denoted <b>X^</b> and given by <b>X^</b> = <b>X</b> / |<b>X</b>|</i>,
296 * http://mathworld.wolfram.com/NormalizedVector.html.
297 */
298template<typename T>
299const Vector2D<T> Vector2D<T>::normal() const
300{
301 Vector2D<T> result(*this);
302 result.normalize();
303 return result;
304}
305
306
307
308/** return the reciprocal version of this vector
309 */
310template<typename T>
311const Vector2D<T> Vector2D<T>::reciprocal() const
312{
313 Vector2D<T> result(TNumTraits::one, TNumTraits::one);
314 result /= *this;
315 return result;
316}
317
318
319
320/** return the vector perpendicular to this one, 90° CCW (to the left).
321 */
322template<typename T> inline
323const Vector2D<T> Vector2D<T>::perp() const
324{
325 return Vector2D<T>(-y, x);
326}
327
328
329
330/** Project vector on this one
331 */
332template <typename T>
333const Vector2D<T> Vector2D<T>::project(const Vector2D<T>& other) const
334{
335 Vector2D<T> result(*this);
336 result *= dot(other, *this);
337 result /= squaredNorm();
338 return result;
339}
340
341
342
343/** Project vector on this one
344 */
345template<typename T> inline
346const Vector2D<T> Vector2D<T>::reject(const Vector2D<T>& other) const
347{
348 return other - project(other);
349}
350
351
352
353template<typename T> inline
354const Vector2D<T> Vector2D<T>::reflect(const Vector2D<T>& other) const
355{
356 return 2 * project(other) - other;
357}
358
359
360
361/** apply a function to every component
362 */
363template <typename T>
364const Vector2D<T> Vector2D<T>::transform(T (*op)(T)) const
365{
366 return Vector2D<T>(op(x), op(y));
367}
368
369
370
371/** Normalize vector.
372 */
373template<typename T> inline
375{
376 *this /= norm();
377}
378
379
380
381/** Random unit vector
382 */
383template <typename T>
384template <class RandomGenerator>
385Vector2D<T> Vector2D<T>::random(RandomGenerator& generator)
386{
387 std::uniform_real_distribution<T> distribution(0, 2 * TNumTraits::pi);
388 const TValue theta = distribution(generator);
389 return Vector2D<T>(num::cos(theta), num::sin(theta));
390}
391
392
393
394/** dot product.
395 * @relates lass::prim::Vector2D
396 */
397template<typename T> inline
398typename Vector2D<T>::TValue dot(const Vector2D<T>& a, const Vector2D<T>& b)
399{
400 return a.x * b.x + a.y * b.y;
401}
402
403
404
405/** returns cosine of angle between both vectors.
406 * @relates lass::prim::Vector2D
407 */
408template<typename T> inline
409typename Vector2D<T>::TValue cos(const Vector2D<T>& a, const Vector2D<T>& b)
410{
411 return dot(a, b) / num::sqrt(a.squaredNorm() * b.squaredNorm());
412}
413
414
415
416/** perp dot product (cross product for 2D vectors).
417 * @relates lass::prim::Vector2D
418 *
419 * <i>The "perp dot product" for <b>a</b> and <b>b</b> vectors in the plane is a modification of
420 * the two-dimensional dot product in which a is replaced by the perpendicular vector rotated 90°
421 * to the left defined by Hill (1994)</i>, http://mathworld.wolfram.com/PerpDotProduct.html.
422 *
423 * It reminds a lot to the 3D cross product, as its result is equal to the z-value of the
424 * cross product of a and b extended to 3D space by setting their z-value to 0:
425 * Vector3D<T> c = cross(Vector3D<T>(a.x, a.y, 0), Vector3D<T>(b.x, b.y, 0)). We know of this
426 * that c.x and c.y are both zero, and that c.z equals the perp dot product between a and b.
427 */
428template<typename T> inline
429typename Vector2D<T>::TValue perpDot(const Vector2D<T>& a, const Vector2D<T>& b)
430{
431 return a.x * b.y - a.y * b.x;
432}
433
434
435
436/** @relates lass::prim::Vector2D
437 */
438template<typename T> inline
439bool operator==(const Vector2D<T>& a, const Vector2D<T>& b)
440{
441 return a.x == b.x && a.y == b.y;
442}
443
444
445
446/** @relates lass::prim::Vector2D
447 */
448template<typename T> inline
449bool operator!=(const Vector2D<T>& a, const Vector2D<T>& b)
450{
451 return !(a == b);
452}
453
454
455
456/** componentwise addition
457 * @relates lass::prim::Vector2D
458 */
459template<typename T> inline
460Vector2D<T> operator+(const Vector2D<T>& a, const Vector2D<T>& b)
461{
462 Vector2D<T> result(a);
463 result += b;
464 return result;
465}
466
467
468
469/** componentwise subtraction
470 * @relates lass::prim::Vector2D
471 */
472template<typename T> inline
473Vector2D<T> operator-(const Vector2D<T>& a, const Vector2D<T>& b)
474{
475 Vector2D<T> result(a);
476 result -= b;
477 return result;
478}
479
480
481
482/** Componentwise multiplication
483 * @relates lass::prim::Vector2D
484 */
485template<typename T> inline
486Vector2D<T> operator*(const Vector2D<T>& a, const Vector2D<T>& b)
487{
488 Vector2D<T> result(a);
489 result *= b;
490 return result;
491}
492
493
494
495/** Componentwise division
496 * @relates lass::prim::Vector2D
497 */
498template<typename T> inline
499Vector2D<T> operator/(const Vector2D<T>& a, const Vector2D<T>& b)
500{
501 Vector2D<T> result(a);
502 result /= b;
503 return result;
504}
505
506
507
508/** add b to all components of a.
509 * @relates lass::prim::Vector2D
510 */
511template<typename T> inline
512Vector2D<T> operator+(const Vector2D<T>& a, typename Vector2D<T>::TParam b)
513{
514 Vector2D<T> result(a);
515 result += b;
516 return result;
517}
518
519
520
521/** subtract b of all components of a.
522 * @relates lass::prim::Vector2D
523 */
524template<typename T> inline
525Vector2D<T> operator-(const Vector2D<T>& a, typename Vector2D<T>::TParam b)
526{
527 Vector2D<T> result(a);
528 result -= b;
529 return result;
530}
531
532
533
534/** muliply all components of a by b
535 * @relates lass::prim::Vector2D
536 */
537template<typename T> inline
538Vector2D<T> operator*(const Vector2D<T>& a, typename Vector2D<T>::TParam b)
539{
540 Vector2D<T> result(a);
541 result *= b;
542 return result;
543}
544
545
546
547/** divide all components of a by b
548 * @relates lass::prim::Vector2D
549 */
550template<typename T> inline
551Vector2D<T> operator/(const Vector2D<T>& a, typename Vector2D<T>::TParam b)
552{
553 Vector2D<T> result(a);
554 result /= b;
555 return result;
556}
557
558
559
560/** add a to all components of b
561 * @relates lass::prim::Vector2D
562 */
563template<typename T> inline
564Vector2D<T> operator+(typename Vector2D<T>::TParam a, const Vector2D<T>& b)
565{
566 Vector2D<T> result(b);
567 result += a;
568 return result;
569}
570
571
572
573/** subtract a of all components of b
574 * @relates lass::prim::Vector2D
575 */
576template<typename T> inline
577Vector2D<T> operator-(typename Vector2D<T>::TParam a, const Vector2D<T>& b)
578{
579 Vector2D<T> result(-b);
580 result += a;
581 return result;
582}
583
584
585
586/** multiply all components of b with a
587 * @relates lass::prim::Vector2D
588 */
589template<typename T> inline
590Vector2D<T> operator*(typename Vector2D<T>::TParam a, const Vector2D<T>& b)
591{
592 Vector2D<T> result(b);
593 result *= a;
594 return result;
595}
596
597
598
599/** return a vector with, for each coordinate, the minimum value of @a a and @a b
600 * @relates lass::prim::Vector2D
601 */
602template<typename T>
603inline Vector2D<T> pointwiseMin(const Vector2D<T>& a, const Vector2D<T>& b)
604{
605 return Vector2D<T>(std::min(a.x, b.x), std::min(a.y, b.y));
606}
607
608
609
610/** return a vector with, for each coordinate, the maximum value of @a a and @a b
611 * @relates lass::prim::Vector2D
612 */
613template<typename T>
614inline Vector2D<T> pointwiseMax(const Vector2D<T>& a, const Vector2D<T>& b)
615{
616 return Vector2D<T>(std::max(a.x, b.x), std::max(a.y, b.y));
617}
618
619
620
621/** interpolate linearly between two vectors: a + t * (b - a)
622 * @relates lass::prim::Vector2D
623 */
624template<typename T>
625inline Vector2D<T> lerp(const Vector2D<T>& a, const Vector2D<T>& b, typename Vector2D<T>::TParam t)
626{
627 Vector2D<T> result = b;
628 result -= a;
629 result *= t;
630 result += a;
631 return result;
632}
633
634
635
636/** @relates lass::prim::Vector2D
637 */
638template<typename T, typename Char, typename Traits>
639std::basic_ostream<Char, Traits>& operator<<(
640 std::basic_ostream<Char, Traits>& stream, const Vector2D<T>& b)
641{
642 LASS_ENFORCE_STREAM(stream) << "(" << b.x << ", " << b.y << ")";
643
644 return stream;
645}
646
647
648
649/** @relates lass::prim::Vector2D
650 */
651template<typename T, typename Char, typename Traits>
652std::basic_istream<Char, Traits>& operator>>(
653 std::basic_istream<Char, Traits>& stream, Vector2D<T>& b)
654{
655 Vector2D<T> result;
656
657 Char c = 0;
658 stream >> c;
659 if (c != '(')
660 {
661 stream.clear(std::ios::failbit);
662 return stream;
663 }
664
665 c = 0;
666 stream >> result.x >> c;
667
668 if (c != ',')
669 {
670 stream.clear(std::ios::failbit);
671 return stream;
672 }
673
674 c = 0;
675 stream >> result.y >> c;
676 if (c != ')')
677 {
678 stream.clear(std::ios::failbit);
679 return stream;
680 }
681
682 b = result;
683 return stream;
684}
685
686
687
688/** @relates lass::prim::Vector2D
689 */
690template<typename T>
691io::XmlOStream& operator<<(io::XmlOStream& stream, const Vector2D<T>& b)
692{
693 LASS_ENFORCE_STREAM(stream)
694 << "<Vector2D>" << b.x << " " << b.y << "</Vector2D>\n";
695 return stream;
696}
697
698
699
700}
701
702}
703
704#endif
LineSegment3D< T, PP > project(const Plane3D< T, EP, NP > &plane, const LineSegment3D< T, PP > &lineSegment)
project a linesegment on a plane.
T norm(const T &x)
return norm of x as if x is real part of complex number: sqr(x)
set of geometrical primitives
Definition aabb_2d.h:81
Library for Assembled Shared Sources.
Definition config.h:53
const Vector2D< T > perp() const
return the vector perpendicular to this one, 90° CCW (to the left).
const Vector2D< T > & operator+() const
A weird way to get back the same object.
void normalize()
Normalize vector.
Vector2D< T > operator*(const Vector2D< T > &a, const Vector2D< T > &b)
Componentwise multiplication.
Vector2D< T >::TValue cos(const Vector2D< T > &a, const Vector2D< T > &b)
returns cosine of angle between both vectors.
bool isNaN() const
Return true if at least one of the components is NaN.
Vector2D< T > & operator/=(const Vector2D< T > &other)
Componentwise division.
Vector2D< T >::TValue dot(const Vector2D< T > &a, const Vector2D< T > &b)
dot product.
Vector2D< T > operator/(const Vector2D< T > &a, typename Vector2D< T >::TParam b)
divide all components of a by b
Vector2D< T > operator*(const Vector2D< T > &a, typename Vector2D< T >::TParam b)
muliply all components of a by b
const Vector2D< T > reject(const Vector2D< T > &other) const
Project vector on this one.
Vector2D< T > lerp(const Vector2D< T > &a, const Vector2D< T > &b, typename Vector2D< T >::TParam t)
interpolate linearly between two vectors: a + t * (b - a)
Vector2D::TConstReference at(signed index) const
Wrap index around range.
Vector2D< T > pointwiseMin(const Vector2D< T > &a, const Vector2D< T > &b)
return a vector with, for each coordinate, the minimum value of a and b
const TValue norm() const
Return norm of vector.
Vector2D< T > operator-(const Vector2D< T > &a, const Vector2D< T > &b)
componentwise subtraction
Vector2D< T > operator+(typename Vector2D< T >::TParam a, const Vector2D< T > &b)
add a to all components of b
const Vector2D< T > normal() const
return a unit vector with same direction/sense as this vector.
bool isZero() const
Return true if all the components are (exactly!) zero.
Vector2D< T > operator+(const Vector2D< T > &a, typename Vector2D< T >::TParam b)
add b to all components of a.
const Vector2D< T > transform(T(*iOperator)(T)) const
apply a function to every component
Vector2D< T > operator-(const Vector2D< T > &a, typename Vector2D< T >::TParam b)
subtract b of all components of a.
Vector2D< T >::TValue perpDot(const Vector2D< T > &a, const Vector2D< T > &b)
perp dot product (cross product for 2D vectors).
static Vector2D< T > random(RandomGenerator &generator)
Random unit vector.
Vector2D< T > operator*(typename Vector2D< T >::TParam a, const Vector2D< T > &b)
multiply all components of b with a
const Vector2D< T > reciprocal() const
return the reciprocal version of this vector
Vector2D< T > operator/(const Vector2D< T > &a, const Vector2D< T > &b)
Componentwise division.
const TValue squaredNorm() const
Return squared norm of vector.
Vector2D< T > & operator-=(const Vector2D< T > &other)
componentwise subtraction
Vector2D< T > operator-(typename Vector2D< T >::TParam a, const Vector2D< T > &b)
subtract a of all components of b
Vector2D< T > operator+(const Vector2D< T > &a, const Vector2D< T > &b)
componentwise addition
const Vector2D< T > project(const Vector2D< T > &other) const
Project vector on this one.
Vector2D< T > & operator+=(const Vector2D< T > &other)
componentwise addition
Vector2D< T > & operator*=(const Vector2D< T > &other)
Componentwise multiplication.
Vector2D< T > pointwiseMax(const Vector2D< T > &a, const Vector2D< T > &b)
return a vector with, for each coordinate, the maximum value of a and b