1 /*
2 * DISTRHO Plugin Framework (DPF)
3 * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any purpose with
6 * or without fee is hereby granted, provided that the above copyright notice and this
7 * permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #include "../Geometry.hpp"
18
19 #include <cmath>
20
21 START_NAMESPACE_DGL
22
23 static const float M_2PIf = 3.14159265358979323846f*2.0f;
24
25 // -----------------------------------------------------------------------
26 // Point
27
28 template<typename T>
Point()29 Point<T>::Point() noexcept
30 : fX(0),
31 fY(0) {}
32
33 template<typename T>
Point(const T & x,const T & y)34 Point<T>::Point(const T& x, const T& y) noexcept
35 : fX(x),
36 fY(y) {}
37
38 template<typename T>
Point(const Point<T> & pos)39 Point<T>::Point(const Point<T>& pos) noexcept
40 : fX(pos.fX),
41 fY(pos.fY) {}
42
43 template<typename T>
getX() const44 const T& Point<T>::getX() const noexcept
45 {
46 return fX;
47 }
48
49 template<typename T>
getY() const50 const T& Point<T>::getY() const noexcept
51 {
52 return fY;
53 }
54
55 template<typename T>
setX(const T & x)56 void Point<T>::setX(const T& x) noexcept
57 {
58 fX = x;
59 }
60
61 template<typename T>
setY(const T & y)62 void Point<T>::setY(const T& y) noexcept
63 {
64 fY = y;
65 }
66
67 template<typename T>
setPos(const T & x,const T & y)68 void Point<T>::setPos(const T& x, const T& y) noexcept
69 {
70 fX = x;
71 fY = y;
72 }
73
74 template<typename T>
setPos(const Point<T> & pos)75 void Point<T>::setPos(const Point<T>& pos) noexcept
76 {
77 fX = pos.fX;
78 fY = pos.fY;
79 }
80
81 template<typename T>
moveBy(const T & x,const T & y)82 void Point<T>::moveBy(const T& x, const T& y) noexcept
83 {
84 fX = static_cast<T>(fX+x);
85 fY = static_cast<T>(fY+y);
86 }
87
88 template<typename T>
moveBy(const Point<T> & pos)89 void Point<T>::moveBy(const Point<T>& pos) noexcept
90 {
91 fX = static_cast<T>(fX+pos.fX);
92 fY = static_cast<T>(fY+pos.fY);
93 }
94
95 template<typename T>
isZero() const96 bool Point<T>::isZero() const noexcept
97 {
98 return fX == 0 && fY == 0;
99 }
100
101 template<typename T>
isNotZero() const102 bool Point<T>::isNotZero() const noexcept
103 {
104 return fX != 0 || fY != 0;
105 }
106
107 template<typename T>
operator +(const Point<T> & pos)108 Point<T> Point<T>::operator+(const Point<T>& pos) noexcept
109 {
110 return Point<T>(fX+pos.fX, fY+pos.fY);
111 }
112
113 template<typename T>
operator -(const Point<T> & pos)114 Point<T> Point<T>::operator-(const Point<T>& pos) noexcept
115 {
116 return Point<T>(fX-pos.fX, fY-pos.fY);
117 }
118
119 template<typename T>
operator =(const Point<T> & pos)120 Point<T>& Point<T>::operator=(const Point<T>& pos) noexcept
121 {
122 fX = pos.fX;
123 fY = pos.fY;
124 return *this;
125 }
126
127 template<typename T>
operator +=(const Point<T> & pos)128 Point<T>& Point<T>::operator+=(const Point<T>& pos) noexcept
129 {
130 fX = static_cast<T>(fX+pos.fX);
131 fY = static_cast<T>(fY+pos.fY);
132 return *this;
133 }
134
135 template<typename T>
operator -=(const Point<T> & pos)136 Point<T>& Point<T>::operator-=(const Point<T>& pos) noexcept
137 {
138 fX = static_cast<T>(fX-pos.fX);
139 fY = static_cast<T>(fY-pos.fY);
140 return *this;
141 }
142
143 template<typename T>
operator ==(const Point<T> & pos) const144 bool Point<T>::operator==(const Point<T>& pos) const noexcept
145 {
146 return (fX == pos.fX && fY == pos.fY);
147 }
148
149 template<typename T>
operator !=(const Point<T> & pos) const150 bool Point<T>::operator!=(const Point<T>& pos) const noexcept
151 {
152 return (fX != pos.fX || fY != pos.fY);
153 }
154
155 // -----------------------------------------------------------------------
156 // Size
157
158 template<typename T>
Size()159 Size<T>::Size() noexcept
160 : fWidth(0),
161 fHeight(0) {}
162
163 template<typename T>
Size(const T & width,const T & height)164 Size<T>::Size(const T& width, const T& height) noexcept
165 : fWidth(width),
166 fHeight(height) {}
167
168 template<typename T>
Size(const Size<T> & size)169 Size<T>::Size(const Size<T>& size) noexcept
170 : fWidth(size.fWidth),
171 fHeight(size.fHeight) {}
172
173 template<typename T>
getWidth() const174 const T& Size<T>::getWidth() const noexcept
175 {
176 return fWidth;
177 }
178
179 template<typename T>
getHeight() const180 const T& Size<T>::getHeight() const noexcept
181 {
182 return fHeight;
183 }
184
185 template<typename T>
setWidth(const T & width)186 void Size<T>::setWidth(const T& width) noexcept
187 {
188 fWidth = width;
189 }
190
191 template<typename T>
setHeight(const T & height)192 void Size<T>::setHeight(const T& height) noexcept
193 {
194 fHeight = height;
195 }
196
197 template<typename T>
setSize(const T & width,const T & height)198 void Size<T>::setSize(const T& width, const T& height) noexcept
199 {
200 fWidth = width;
201 fHeight = height;
202 }
203
204 template<typename T>
setSize(const Size<T> & size)205 void Size<T>::setSize(const Size<T>& size) noexcept
206 {
207 fWidth = size.fWidth;
208 fHeight = size.fHeight;
209 }
210
211 template<typename T>
growBy(double multiplier)212 void Size<T>::growBy(double multiplier) noexcept
213 {
214 fWidth = static_cast<T>(static_cast<double>(fWidth)*multiplier);
215 fHeight = static_cast<T>(static_cast<double>(fHeight)*multiplier);
216 }
217
218 template<typename T>
shrinkBy(double divider)219 void Size<T>::shrinkBy(double divider) noexcept
220 {
221 fWidth = static_cast<T>(static_cast<double>(fWidth)/divider);
222 fHeight = static_cast<T>(static_cast<double>(fHeight)/divider);
223 }
224
225 template<typename T>
isNull() const226 bool Size<T>::isNull() const noexcept
227 {
228 return fWidth == 0 && fHeight == 0;
229 }
230
231 template<typename T>
isNotNull() const232 bool Size<T>::isNotNull() const noexcept
233 {
234 return fWidth != 0 || fHeight != 0;
235 }
236
237 template<typename T>
isValid() const238 bool Size<T>::isValid() const noexcept
239 {
240 return fWidth > 0 && fHeight > 0;
241 }
242
243 template<typename T>
isInvalid() const244 bool Size<T>::isInvalid() const noexcept
245 {
246 return fWidth <= 0 || fHeight <= 0;
247 }
248
249 template<typename T>
operator +(const Size<T> & size)250 Size<T> Size<T>::operator+(const Size<T>& size) noexcept
251 {
252 return Size<T>(fWidth+size.fWidth, fHeight+size.fHeight);
253 }
254
255 template<typename T>
operator -(const Size<T> & size)256 Size<T> Size<T>::operator-(const Size<T>& size) noexcept
257 {
258 return Size<T>(fWidth-size.fWidth, fHeight-size.fHeight);
259 }
260
261 template<typename T>
operator =(const Size<T> & size)262 Size<T>& Size<T>::operator=(const Size<T>& size) noexcept
263 {
264 fWidth = size.fWidth;
265 fHeight = size.fHeight;
266 return *this;
267 }
268
269 template<typename T>
operator +=(const Size<T> & size)270 Size<T>& Size<T>::operator+=(const Size<T>& size) noexcept
271 {
272 fWidth = static_cast<T>(fWidth+size.fWidth);
273 fHeight = static_cast<T>(fHeight+size.fHeight);
274 return *this;
275 }
276
277 template<typename T>
operator -=(const Size<T> & size)278 Size<T>& Size<T>::operator-=(const Size<T>& size) noexcept
279 {
280 fWidth = static_cast<T>(fWidth-size.fWidth);
281 fHeight = static_cast<T>(fHeight-size.fHeight);
282 return *this;
283 }
284
285 template<typename T>
operator *=(double m)286 Size<T>& Size<T>::operator*=(double m) noexcept
287 {
288 fWidth = static_cast<T>(static_cast<double>(fWidth)*m);
289 fHeight = static_cast<T>(static_cast<double>(fHeight)*m);
290 return *this;
291 }
292
293 template<typename T>
operator /=(double d)294 Size<T>& Size<T>::operator/=(double d) noexcept
295 {
296 fWidth = static_cast<T>(static_cast<double>(fWidth)/d);
297 fHeight = static_cast<T>(static_cast<double>(fHeight)/d);
298 return *this;
299 }
300
301 template<typename T>
operator ==(const Size<T> & size) const302 bool Size<T>::operator==(const Size<T>& size) const noexcept
303 {
304 return (fWidth == size.fWidth && fHeight == size.fHeight);
305 }
306
307 template<typename T>
operator !=(const Size<T> & size) const308 bool Size<T>::operator!=(const Size<T>& size) const noexcept
309 {
310 return (fWidth != size.fWidth || fHeight != size.fHeight);
311 }
312
313 // -----------------------------------------------------------------------
314 // Line
315
316 template<typename T>
Line()317 Line<T>::Line() noexcept
318 : fPosStart(0, 0),
319 fPosEnd(0, 0) {}
320
321 template<typename T>
Line(const T & startX,const T & startY,const T & endX,const T & endY)322 Line<T>::Line(const T& startX, const T& startY, const T& endX, const T& endY) noexcept
323 : fPosStart(startX, startY),
324 fPosEnd(endX, endY) {}
325
326 template<typename T>
Line(const T & startX,const T & startY,const Point<T> & endPos)327 Line<T>::Line(const T& startX, const T& startY, const Point<T>& endPos) noexcept
328 : fPosStart(startX, startY),
329 fPosEnd(endPos) {}
330
331 template<typename T>
Line(const Point<T> & startPos,const T & endX,const T & endY)332 Line<T>::Line(const Point<T>& startPos, const T& endX, const T& endY) noexcept
333 : fPosStart(startPos),
334 fPosEnd(endX, endY) {}
335
336 template<typename T>
Line(const Point<T> & startPos,const Point<T> & endPos)337 Line<T>::Line(const Point<T>& startPos, const Point<T>& endPos) noexcept
338 : fPosStart(startPos),
339 fPosEnd(endPos) {}
340
341 template<typename T>
Line(const Line<T> & line)342 Line<T>::Line(const Line<T>& line) noexcept
343 : fPosStart(line.fPosStart),
344 fPosEnd(line.fPosEnd) {}
345
346 template<typename T>
getStartX() const347 const T& Line<T>::getStartX() const noexcept
348 {
349 return fPosStart.fX;
350 }
351
352 template<typename T>
getStartY() const353 const T& Line<T>::getStartY() const noexcept
354 {
355 return fPosStart.fY;
356 }
357
358 template<typename T>
getEndX() const359 const T& Line<T>::getEndX() const noexcept
360 {
361 return fPosEnd.fX;
362 }
363
364 template<typename T>
getEndY() const365 const T& Line<T>::getEndY() const noexcept
366 {
367 return fPosEnd.fY;
368 }
369
370 template<typename T>
getStartPos() const371 const Point<T>& Line<T>::getStartPos() const noexcept
372 {
373 return fPosStart;
374 }
375
376 template<typename T>
getEndPos() const377 const Point<T>& Line<T>::getEndPos() const noexcept
378 {
379 return fPosEnd;
380 }
381
382 template<typename T>
setStartX(const T & x)383 void Line<T>::setStartX(const T& x) noexcept
384 {
385 fPosStart.fX = x;
386 }
387
388 template<typename T>
setStartY(const T & y)389 void Line<T>::setStartY(const T& y) noexcept
390 {
391 fPosStart.fY = y;
392 }
393
394 template<typename T>
setStartPos(const T & x,const T & y)395 void Line<T>::setStartPos(const T& x, const T& y) noexcept
396 {
397 fPosStart = Point<T>(x, y);
398 }
399
400 template<typename T>
setStartPos(const Point<T> & pos)401 void Line<T>::setStartPos(const Point<T>& pos) noexcept
402 {
403 fPosStart = pos;
404 }
405
406 template<typename T>
setEndX(const T & x)407 void Line<T>::setEndX(const T& x) noexcept
408 {
409 fPosEnd.fX = x;
410 }
411
412 template<typename T>
setEndY(const T & y)413 void Line<T>::setEndY(const T& y) noexcept
414 {
415 fPosEnd.fY = y;
416 }
417
418 template<typename T>
setEndPos(const T & x,const T & y)419 void Line<T>::setEndPos(const T& x, const T& y) noexcept
420 {
421 fPosEnd = Point<T>(x, y);
422 }
423
424 template<typename T>
setEndPos(const Point<T> & pos)425 void Line<T>::setEndPos(const Point<T>& pos) noexcept
426 {
427 fPosEnd = pos;
428 }
429
430 template<typename T>
moveBy(const T & x,const T & y)431 void Line<T>::moveBy(const T& x, const T& y) noexcept
432 {
433 fPosStart.moveBy(x, y);
434 fPosEnd.moveBy(x, y);
435 }
436
437 template<typename T>
moveBy(const Point<T> & pos)438 void Line<T>::moveBy(const Point<T>& pos) noexcept
439 {
440 fPosStart.moveBy(pos);
441 fPosEnd.moveBy(pos);
442 }
443
444 template<typename T>
isNull() const445 bool Line<T>::isNull() const noexcept
446 {
447 return fPosStart == fPosEnd;
448 }
449
450 template<typename T>
isNotNull() const451 bool Line<T>::isNotNull() const noexcept
452 {
453 return fPosStart != fPosEnd;
454 }
455
456 template<typename T>
operator =(const Line<T> & line)457 Line<T>& Line<T>::operator=(const Line<T>& line) noexcept
458 {
459 fPosStart = line.fPosStart;
460 fPosEnd = line.fPosEnd;
461 return *this;
462 }
463
464 template<typename T>
operator ==(const Line<T> & line) const465 bool Line<T>::operator==(const Line<T>& line) const noexcept
466 {
467 return (fPosStart == line.fPosStart && fPosEnd == line.fPosEnd);
468 }
469
470 template<typename T>
operator !=(const Line<T> & line) const471 bool Line<T>::operator!=(const Line<T>& line) const noexcept
472 {
473 return (fPosStart != line.fPosStart || fPosEnd != line.fPosEnd);
474 }
475
476 // -----------------------------------------------------------------------
477 // Circle
478
479 template<typename T>
Circle()480 Circle<T>::Circle() noexcept
481 : fPos(0, 0),
482 fSize(0.0f),
483 fNumSegments(0),
484 fTheta(0.0f),
485 fCos(0.0f),
486 fSin(0.0f) {}
487
488 template<typename T>
Circle(const T & x,const T & y,const float size,const uint numSegments)489 Circle<T>::Circle(const T& x, const T& y, const float size, const uint numSegments)
490 : fPos(x, y),
491 fSize(size),
492 fNumSegments(numSegments >= 3 ? numSegments : 3),
493 fTheta(M_2PIf / static_cast<float>(fNumSegments)),
494 fCos(std::cos(fTheta)),
495 fSin(std::sin(fTheta))
496 {
497 DISTRHO_SAFE_ASSERT(fSize > 0.0f);
498 }
499
500 template<typename T>
Circle(const Point<T> & pos,const float size,const uint numSegments)501 Circle<T>::Circle(const Point<T>& pos, const float size, const uint numSegments)
502 : fPos(pos),
503 fSize(size),
504 fNumSegments(numSegments >= 3 ? numSegments : 3),
505 fTheta(M_2PIf / static_cast<float>(fNumSegments)),
506 fCos(std::cos(fTheta)),
507 fSin(std::sin(fTheta))
508 {
509 DISTRHO_SAFE_ASSERT(fSize > 0.0f);
510 }
511
512 template<typename T>
Circle(const Circle<T> & cir)513 Circle<T>::Circle(const Circle<T>& cir) noexcept
514 : fPos(cir.fPos),
515 fSize(cir.fSize),
516 fNumSegments(cir.fNumSegments),
517 fTheta(cir.fTheta),
518 fCos(cir.fCos),
519 fSin(cir.fSin)
520 {
521 DISTRHO_SAFE_ASSERT(fSize > 0.0f);
522 }
523
524 template<typename T>
getX() const525 const T& Circle<T>::getX() const noexcept
526 {
527 return fPos.fX;
528 }
529
530 template<typename T>
getY() const531 const T& Circle<T>::getY() const noexcept
532 {
533 return fPos.fY;
534 }
535
536 template<typename T>
getPos() const537 const Point<T>& Circle<T>::getPos() const noexcept
538 {
539 return fPos;
540 }
541
542 template<typename T>
setX(const T & x)543 void Circle<T>::setX(const T& x) noexcept
544 {
545 fPos.fX = x;
546 }
547
548 template<typename T>
setY(const T & y)549 void Circle<T>::setY(const T& y) noexcept
550 {
551 fPos.fY = y;
552 }
553
554 template<typename T>
setPos(const T & x,const T & y)555 void Circle<T>::setPos(const T& x, const T& y) noexcept
556 {
557 fPos.fX = x;
558 fPos.fY = y;
559 }
560
561 template<typename T>
setPos(const Point<T> & pos)562 void Circle<T>::setPos(const Point<T>& pos) noexcept
563 {
564 fPos = pos;
565 }
566
567 template<typename T>
getSize() const568 float Circle<T>::getSize() const noexcept
569 {
570 return fSize;
571 }
572
573 template<typename T>
setSize(const float size)574 void Circle<T>::setSize(const float size) noexcept
575 {
576 DISTRHO_SAFE_ASSERT_RETURN(size > 0.0f,);
577
578 fSize = size;
579 }
580
581 template<typename T>
getNumSegments() const582 uint Circle<T>::getNumSegments() const noexcept
583 {
584 return fNumSegments;
585 }
586
587 template<typename T>
setNumSegments(const uint num)588 void Circle<T>::setNumSegments(const uint num)
589 {
590 DISTRHO_SAFE_ASSERT_RETURN(num >= 3,);
591
592 if (fNumSegments == num)
593 return;
594
595 fNumSegments = num;
596
597 fTheta = M_2PIf / static_cast<float>(fNumSegments);
598 fCos = std::cos(fTheta);
599 fSin = std::sin(fTheta);
600 }
601
602 template<typename T>
draw()603 void Circle<T>::draw()
604 {
605 _draw(false);
606 }
607
608 template<typename T>
drawOutline()609 void Circle<T>::drawOutline()
610 {
611 _draw(true);
612 }
613
614 template<typename T>
operator =(const Circle<T> & cir)615 Circle<T>& Circle<T>::operator=(const Circle<T>& cir) noexcept
616 {
617 fPos = cir.fPos;
618 fSize = cir.fSize;
619 fTheta = cir.fTheta;
620 fCos = cir.fCos;
621 fSin = cir.fSin;
622 fNumSegments = cir.fNumSegments;
623 return *this;
624 }
625
626 template<typename T>
operator ==(const Circle<T> & cir) const627 bool Circle<T>::operator==(const Circle<T>& cir) const noexcept
628 {
629 return (fPos == cir.fPos && d_isEqual(fSize, cir.fSize) && fNumSegments == cir.fNumSegments);
630 }
631
632 template<typename T>
operator !=(const Circle<T> & cir) const633 bool Circle<T>::operator!=(const Circle<T>& cir) const noexcept
634 {
635 return (fPos != cir.fPos || d_isNotEqual(fSize, cir.fSize) || fNumSegments != cir.fNumSegments);
636 }
637
638 // -----------------------------------------------------------------------
639 // Triangle
640
641 template<typename T>
Triangle()642 Triangle<T>::Triangle() noexcept
643 : fPos1(0, 0),
644 fPos2(0, 0),
645 fPos3(0, 0) {}
646
647 template<typename T>
Triangle(const T & x1,const T & y1,const T & x2,const T & y2,const T & x3,const T & y3)648 Triangle<T>::Triangle(const T& x1, const T& y1, const T& x2, const T& y2, const T& x3, const T& y3) noexcept
649 : fPos1(x1, y1),
650 fPos2(x2, y2),
651 fPos3(x3, y3) {}
652
653 template<typename T>
Triangle(const Point<T> & pos1,const Point<T> & pos2,const Point<T> & pos3)654 Triangle<T>::Triangle(const Point<T>& pos1, const Point<T>& pos2, const Point<T>& pos3) noexcept
655 : fPos1(pos1),
656 fPos2(pos2),
657 fPos3(pos3) {}
658
659 template<typename T>
Triangle(const Triangle<T> & tri)660 Triangle<T>::Triangle(const Triangle<T>& tri) noexcept
661 : fPos1(tri.fPos1),
662 fPos2(tri.fPos2),
663 fPos3(tri.fPos3) {}
664
665 template<typename T>
isNull() const666 bool Triangle<T>::isNull() const noexcept
667 {
668 return fPos1 == fPos2 && fPos1 == fPos3;
669 }
670
671 template<typename T>
isNotNull() const672 bool Triangle<T>::isNotNull() const noexcept
673 {
674 return fPos1 != fPos2 || fPos1 != fPos3;
675 }
676
677 template<typename T>
isValid() const678 bool Triangle<T>::isValid() const noexcept
679 {
680 return fPos1 != fPos2 && fPos1 != fPos3;
681 }
682
683 template<typename T>
isInvalid() const684 bool Triangle<T>::isInvalid() const noexcept
685 {
686 return fPos1 == fPos2 || fPos1 == fPos3;
687 }
688
689 template<typename T>
draw()690 void Triangle<T>::draw()
691 {
692 _draw(false);
693 }
694
695 template<typename T>
drawOutline()696 void Triangle<T>::drawOutline()
697 {
698 _draw(true);
699 }
700
701 template<typename T>
operator =(const Triangle<T> & tri)702 Triangle<T>& Triangle<T>::operator=(const Triangle<T>& tri) noexcept
703 {
704 fPos1 = tri.fPos1;
705 fPos2 = tri.fPos2;
706 fPos3 = tri.fPos3;
707 return *this;
708 }
709
710 template<typename T>
operator ==(const Triangle<T> & tri) const711 bool Triangle<T>::operator==(const Triangle<T>& tri) const noexcept
712 {
713 return (fPos1 == tri.fPos1 && fPos2 == tri.fPos2 && fPos3 == tri.fPos3);
714 }
715
716 template<typename T>
operator !=(const Triangle<T> & tri) const717 bool Triangle<T>::operator!=(const Triangle<T>& tri) const noexcept
718 {
719 return (fPos1 != tri.fPos1 || fPos2 != tri.fPos2 || fPos3 != tri.fPos3);
720 }
721
722 // -----------------------------------------------------------------------
723 // Rectangle
724
725 template<typename T>
Rectangle()726 Rectangle<T>::Rectangle() noexcept
727 : fPos(0, 0),
728 fSize(0, 0) {}
729
730 template<typename T>
Rectangle(const T & x,const T & y,const T & width,const T & height)731 Rectangle<T>::Rectangle(const T& x, const T& y, const T& width, const T& height) noexcept
732 : fPos(x, y),
733 fSize(width, height) {}
734
735 template<typename T>
Rectangle(const T & x,const T & y,const Size<T> & size)736 Rectangle<T>::Rectangle(const T& x, const T& y, const Size<T>& size) noexcept
737 : fPos(x, y),
738 fSize(size) {}
739
740 template<typename T>
Rectangle(const Point<T> & pos,const T & width,const T & height)741 Rectangle<T>::Rectangle(const Point<T>& pos, const T& width, const T& height) noexcept
742 : fPos(pos),
743 fSize(width, height) {}
744
745 template<typename T>
Rectangle(const Point<T> & pos,const Size<T> & size)746 Rectangle<T>::Rectangle(const Point<T>& pos, const Size<T>& size) noexcept
747 : fPos(pos),
748 fSize(size) {}
749
750 template<typename T>
Rectangle(const Rectangle<T> & rect)751 Rectangle<T>::Rectangle(const Rectangle<T>& rect) noexcept
752 : fPos(rect.fPos),
753 fSize(rect.fSize) {}
754
755 template<typename T>
getX() const756 const T& Rectangle<T>::getX() const noexcept
757 {
758 return fPos.fX;
759 }
760
761 template<typename T>
getY() const762 const T& Rectangle<T>::getY() const noexcept
763 {
764 return fPos.fY;
765 }
766
767 template<typename T>
getWidth() const768 const T& Rectangle<T>::getWidth() const noexcept
769 {
770 return fSize.fWidth;
771 }
772
773 template<typename T>
getHeight() const774 const T& Rectangle<T>::getHeight() const noexcept
775 {
776 return fSize.fHeight;
777 }
778
779 template<typename T>
getPos() const780 const Point<T>& Rectangle<T>::getPos() const noexcept
781 {
782 return fPos;
783 }
784
785 template<typename T>
getSize() const786 const Size<T>& Rectangle<T>::getSize() const noexcept
787 {
788 return fSize;
789 }
790
791 template<typename T>
setX(const T & x)792 void Rectangle<T>::setX(const T& x) noexcept
793 {
794 fPos.fX = x;
795 }
796
797 template<typename T>
setY(const T & y)798 void Rectangle<T>::setY(const T& y) noexcept
799 {
800 fPos.fY = y;
801 }
802
803 template<typename T>
setPos(const T & x,const T & y)804 void Rectangle<T>::setPos(const T& x, const T& y) noexcept
805 {
806 fPos.fX = x;
807 fPos.fY = y;
808 }
809
810 template<typename T>
setPos(const Point<T> & pos)811 void Rectangle<T>::setPos(const Point<T>& pos) noexcept
812 {
813 fPos = pos;
814 }
815
816 template<typename T>
moveBy(const T & x,const T & y)817 void Rectangle<T>::moveBy(const T& x, const T& y) noexcept
818 {
819 fPos.moveBy(x, y);
820 }
821
822 template<typename T>
moveBy(const Point<T> & pos)823 void Rectangle<T>::moveBy(const Point<T>& pos) noexcept
824 {
825 fPos.moveBy(pos);
826 }
827
828 template<typename T>
setWidth(const T & width)829 void Rectangle<T>::setWidth(const T& width) noexcept
830 {
831 fSize.fWidth = width;
832 }
833
834 template<typename T>
setHeight(const T & height)835 void Rectangle<T>::setHeight(const T& height) noexcept
836 {
837 fSize.fHeight = height;
838 }
839
840 template<typename T>
setSize(const T & width,const T & height)841 void Rectangle<T>::setSize(const T& width, const T& height) noexcept
842 {
843 fSize.fWidth = width;
844 fSize.fHeight = height;
845 }
846
847 template<typename T>
setSize(const Size<T> & size)848 void Rectangle<T>::setSize(const Size<T>& size) noexcept
849 {
850 fSize = size;
851 }
852
853 template<typename T>
growBy(double multiplier)854 void Rectangle<T>::growBy(double multiplier) noexcept
855 {
856 fSize.growBy(multiplier);
857 }
858
859 template<typename T>
shrinkBy(double divider)860 void Rectangle<T>::shrinkBy(double divider) noexcept
861 {
862 fSize.shrinkBy(divider);
863 }
864
865 template<typename T>
setRectangle(const Point<T> & pos,const Size<T> & size)866 void Rectangle<T>::setRectangle(const Point<T>& pos, const Size<T>& size) noexcept
867 {
868 fPos = pos;
869 fSize = size;
870 }
871
872 template<typename T>
setRectangle(const Rectangle<T> & rect)873 void Rectangle<T>::setRectangle(const Rectangle<T>& rect) noexcept
874 {
875 fPos = rect.fPos;
876 fSize = rect.fSize;
877 }
878
879 template<typename T>
contains(const T & x,const T & y) const880 bool Rectangle<T>::contains(const T& x, const T& y) const noexcept
881 {
882 return (x >= fPos.fX && y >= fPos.fY && x <= fPos.fX+fSize.fWidth && y <= fPos.fY+fSize.fHeight);
883 }
884
885 template<typename T>
contains(const Point<T> & pos) const886 bool Rectangle<T>::contains(const Point<T>& pos) const noexcept
887 {
888 return contains(pos.fX, pos.fY);
889 }
890
891 template<typename T>
containsX(const T & x) const892 bool Rectangle<T>::containsX(const T& x) const noexcept
893 {
894 return (x >= fPos.fX && x <= fPos.fX + fSize.fWidth);
895 }
896
897 template<typename T>
containsY(const T & y) const898 bool Rectangle<T>::containsY(const T& y) const noexcept
899 {
900 return (y >= fPos.fY && y <= fPos.fY + fSize.fHeight);
901 }
902
903 template<typename T>
draw()904 void Rectangle<T>::draw()
905 {
906 _draw(false);
907 }
908
909 template<typename T>
drawOutline()910 void Rectangle<T>::drawOutline()
911 {
912 _draw(true);
913 }
914
915 template<typename T>
operator =(const Rectangle<T> & rect)916 Rectangle<T>& Rectangle<T>::operator=(const Rectangle<T>& rect) noexcept
917 {
918 fPos = rect.fPos;
919 fSize = rect.fSize;
920 return *this;
921 }
922
923 template<typename T>
operator *=(double m)924 Rectangle<T>& Rectangle<T>::operator*=(double m) noexcept
925 {
926 fSize *= m;
927 return *this;
928 }
929
930 template<typename T>
operator /=(double d)931 Rectangle<T>& Rectangle<T>::operator/=(double d) noexcept
932 {
933 fSize /= d;
934 return *this;
935 }
936
937 template<typename T>
operator ==(const Rectangle<T> & rect) const938 bool Rectangle<T>::operator==(const Rectangle<T>& rect) const noexcept
939 {
940 return (fPos == rect.fPos && fSize == rect.fSize);
941 }
942
943 template<typename T>
operator !=(const Rectangle<T> & rect) const944 bool Rectangle<T>::operator!=(const Rectangle<T>& rect) const noexcept
945 {
946 return (fPos != rect.fPos || fSize != rect.fSize);
947 }
948
949 // -----------------------------------------------------------------------
950 // Possible template data types
951
952 template class Point<double>;
953 template class Point<float>;
954 template class Point<int>;
955 template class Point<uint>;
956 template class Point<short>;
957 template class Point<ushort>;
958
959 template class Size<double>;
960 template class Size<float>;
961 template class Size<int>;
962 template class Size<uint>;
963 template class Size<short>;
964 template class Size<ushort>;
965
966 template class Line<double>;
967 template class Line<float>;
968 template class Line<int>;
969 template class Line<uint>;
970 template class Line<short>;
971 template class Line<ushort>;
972
973 template class Circle<double>;
974 template class Circle<float>;
975 template class Circle<int>;
976 template class Circle<uint>;
977 template class Circle<short>;
978 template class Circle<ushort>;
979
980 template class Triangle<double>;
981 template class Triangle<float>;
982 template class Triangle<int>;
983 template class Triangle<uint>;
984 template class Triangle<short>;
985 template class Triangle<ushort>;
986
987 template class Rectangle<double>;
988 template class Rectangle<float>;
989 template class Rectangle<int>;
990 template class Rectangle<uint>;
991 template class Rectangle<short>;
992 template class Rectangle<ushort>;
993
994 // -----------------------------------------------------------------------
995
996 END_NAMESPACE_DGL
997