Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Geometry.cpp 22KB

6 years ago
8 years ago
8 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2016 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. #include "../Geometry.hpp"
  17. #include <cmath>
  18. START_NAMESPACE_DGL
  19. static const float M_2PIf = 3.14159265358979323846f*2.0f;
  20. // -----------------------------------------------------------------------
  21. // Point
  22. template<typename T>
  23. Point<T>::Point() noexcept
  24. : fX(0),
  25. fY(0) {}
  26. template<typename T>
  27. Point<T>::Point(const T& x, const T& y) noexcept
  28. : fX(x),
  29. fY(y) {}
  30. template<typename T>
  31. Point<T>::Point(const Point<T>& pos) noexcept
  32. : fX(pos.fX),
  33. fY(pos.fY) {}
  34. template<typename T>
  35. const T& Point<T>::getX() const noexcept
  36. {
  37. return fX;
  38. }
  39. template<typename T>
  40. const T& Point<T>::getY() const noexcept
  41. {
  42. return fY;
  43. }
  44. template<typename T>
  45. void Point<T>::setX(const T& x) noexcept
  46. {
  47. fX = x;
  48. }
  49. template<typename T>
  50. void Point<T>::setY(const T& y) noexcept
  51. {
  52. fY = y;
  53. }
  54. template<typename T>
  55. void Point<T>::setPos(const T& x, const T& y) noexcept
  56. {
  57. fX = x;
  58. fY = y;
  59. }
  60. template<typename T>
  61. void Point<T>::setPos(const Point<T>& pos) noexcept
  62. {
  63. fX = pos.fX;
  64. fY = pos.fY;
  65. }
  66. template<typename T>
  67. void Point<T>::moveBy(const T& x, const T& y) noexcept
  68. {
  69. fX = static_cast<T>(fX+x);
  70. fY = static_cast<T>(fY+y);
  71. }
  72. template<typename T>
  73. void Point<T>::moveBy(const Point<T>& pos) noexcept
  74. {
  75. fX = static_cast<T>(fX+pos.fX);
  76. fY = static_cast<T>(fY+pos.fY);
  77. }
  78. template<typename T>
  79. bool Point<T>::isZero() const noexcept
  80. {
  81. return fX == 0 && fY == 0;
  82. }
  83. template<typename T>
  84. bool Point<T>::isNotZero() const noexcept
  85. {
  86. return fX != 0 || fY != 0;
  87. }
  88. template<typename T>
  89. Point<T> Point<T>::operator+(const Point<T>& pos) noexcept
  90. {
  91. return Point<T>(fX+pos.fX, fY+pos.fY);
  92. }
  93. template<typename T>
  94. Point<T> Point<T>::operator-(const Point<T>& pos) noexcept
  95. {
  96. return Point<T>(fX-pos.fX, fY-pos.fY);
  97. }
  98. template<typename T>
  99. Point<T>& Point<T>::operator=(const Point<T>& pos) noexcept
  100. {
  101. fX = pos.fX;
  102. fY = pos.fY;
  103. return *this;
  104. }
  105. template<typename T>
  106. Point<T>& Point<T>::operator+=(const Point<T>& pos) noexcept
  107. {
  108. fX = static_cast<T>(fX+pos.fX);
  109. fY = static_cast<T>(fY+pos.fY);
  110. return *this;
  111. }
  112. template<typename T>
  113. Point<T>& Point<T>::operator-=(const Point<T>& pos) noexcept
  114. {
  115. fX = static_cast<T>(fX-pos.fX);
  116. fY = static_cast<T>(fY-pos.fY);
  117. return *this;
  118. }
  119. template<typename T>
  120. bool Point<T>::operator==(const Point<T>& pos) const noexcept
  121. {
  122. return (fX == pos.fX && fY == pos.fY);
  123. }
  124. template<typename T>
  125. bool Point<T>::operator!=(const Point<T>& pos) const noexcept
  126. {
  127. return (fX != pos.fX || fY != pos.fY);
  128. }
  129. // -----------------------------------------------------------------------
  130. // Size
  131. template<typename T>
  132. Size<T>::Size() noexcept
  133. : fWidth(0),
  134. fHeight(0) {}
  135. template<typename T>
  136. Size<T>::Size(const T& width, const T& height) noexcept
  137. : fWidth(width),
  138. fHeight(height) {}
  139. template<typename T>
  140. Size<T>::Size(const Size<T>& size) noexcept
  141. : fWidth(size.fWidth),
  142. fHeight(size.fHeight) {}
  143. template<typename T>
  144. const T& Size<T>::getWidth() const noexcept
  145. {
  146. return fWidth;
  147. }
  148. template<typename T>
  149. const T& Size<T>::getHeight() const noexcept
  150. {
  151. return fHeight;
  152. }
  153. template<typename T>
  154. void Size<T>::setWidth(const T& width) noexcept
  155. {
  156. fWidth = width;
  157. }
  158. template<typename T>
  159. void Size<T>::setHeight(const T& height) noexcept
  160. {
  161. fHeight = height;
  162. }
  163. template<typename T>
  164. void Size<T>::setSize(const T& width, const T& height) noexcept
  165. {
  166. fWidth = width;
  167. fHeight = height;
  168. }
  169. template<typename T>
  170. void Size<T>::setSize(const Size<T>& size) noexcept
  171. {
  172. fWidth = size.fWidth;
  173. fHeight = size.fHeight;
  174. }
  175. template<typename T>
  176. void Size<T>::growBy(double multiplier) noexcept
  177. {
  178. fWidth = static_cast<T>(static_cast<double>(fWidth)*multiplier);
  179. fHeight = static_cast<T>(static_cast<double>(fHeight)*multiplier);
  180. }
  181. template<typename T>
  182. void Size<T>::shrinkBy(double divider) noexcept
  183. {
  184. fWidth = static_cast<T>(static_cast<double>(fWidth)/divider);
  185. fHeight = static_cast<T>(static_cast<double>(fHeight)/divider);
  186. }
  187. template<typename T>
  188. bool Size<T>::isNull() const noexcept
  189. {
  190. return fWidth == 0 && fHeight == 0;
  191. }
  192. template<typename T>
  193. bool Size<T>::isNotNull() const noexcept
  194. {
  195. return fWidth != 0 || fHeight != 0;
  196. }
  197. template<typename T>
  198. bool Size<T>::isValid() const noexcept
  199. {
  200. return fWidth > 1 && fHeight > 1;
  201. }
  202. template<typename T>
  203. bool Size<T>::isInvalid() const noexcept
  204. {
  205. return fWidth <= 0 || fHeight <= 0;
  206. }
  207. template<typename T>
  208. Size<T> Size<T>::operator+(const Size<T>& size) noexcept
  209. {
  210. return Size<T>(fWidth+size.fWidth, fHeight+size.fHeight);
  211. }
  212. template<typename T>
  213. Size<T> Size<T>::operator-(const Size<T>& size) noexcept
  214. {
  215. return Size<T>(fWidth-size.fWidth, fHeight-size.fHeight);
  216. }
  217. template<typename T>
  218. Size<T>& Size<T>::operator=(const Size<T>& size) noexcept
  219. {
  220. fWidth = size.fWidth;
  221. fHeight = size.fHeight;
  222. return *this;
  223. }
  224. template<typename T>
  225. Size<T>& Size<T>::operator+=(const Size<T>& size) noexcept
  226. {
  227. fWidth = static_cast<T>(fWidth+size.fWidth);
  228. fHeight = static_cast<T>(fHeight+size.fHeight);
  229. return *this;
  230. }
  231. template<typename T>
  232. Size<T>& Size<T>::operator-=(const Size<T>& size) noexcept
  233. {
  234. fWidth = static_cast<T>(fWidth-size.fWidth);
  235. fHeight = static_cast<T>(fHeight-size.fHeight);
  236. return *this;
  237. }
  238. template<typename T>
  239. Size<T>& Size<T>::operator*=(double m) noexcept
  240. {
  241. fWidth = static_cast<T>(static_cast<double>(fWidth)*m);
  242. fHeight = static_cast<T>(static_cast<double>(fHeight)*m);
  243. return *this;
  244. }
  245. template<typename T>
  246. Size<T>& Size<T>::operator/=(double d) noexcept
  247. {
  248. fWidth = static_cast<T>(static_cast<double>(fWidth)/d);
  249. fHeight = static_cast<T>(static_cast<double>(fHeight)/d);
  250. return *this;
  251. }
  252. template<typename T>
  253. bool Size<T>::operator==(const Size<T>& size) const noexcept
  254. {
  255. return (fWidth == size.fWidth && fHeight == size.fHeight);
  256. }
  257. template<typename T>
  258. bool Size<T>::operator!=(const Size<T>& size) const noexcept
  259. {
  260. return (fWidth != size.fWidth || fHeight != size.fHeight);
  261. }
  262. // -----------------------------------------------------------------------
  263. // Line
  264. template<typename T>
  265. Line<T>::Line() noexcept
  266. : fPosStart(0, 0),
  267. fPosEnd(0, 0) {}
  268. template<typename T>
  269. Line<T>::Line(const T& startX, const T& startY, const T& endX, const T& endY) noexcept
  270. : fPosStart(startX, startY),
  271. fPosEnd(endX, endY) {}
  272. template<typename T>
  273. Line<T>::Line(const T& startX, const T& startY, const Point<T>& endPos) noexcept
  274. : fPosStart(startX, startY),
  275. fPosEnd(endPos) {}
  276. template<typename T>
  277. Line<T>::Line(const Point<T>& startPos, const T& endX, const T& endY) noexcept
  278. : fPosStart(startPos),
  279. fPosEnd(endX, endY) {}
  280. template<typename T>
  281. Line<T>::Line(const Point<T>& startPos, const Point<T>& endPos) noexcept
  282. : fPosStart(startPos),
  283. fPosEnd(endPos) {}
  284. template<typename T>
  285. Line<T>::Line(const Line<T>& line) noexcept
  286. : fPosStart(line.fPosStart),
  287. fPosEnd(line.fPosEnd) {}
  288. template<typename T>
  289. const T& Line<T>::getStartX() const noexcept
  290. {
  291. return fPosStart.fX;
  292. }
  293. template<typename T>
  294. const T& Line<T>::getStartY() const noexcept
  295. {
  296. return fPosStart.fY;
  297. }
  298. template<typename T>
  299. const T& Line<T>::getEndX() const noexcept
  300. {
  301. return fPosEnd.fX;
  302. }
  303. template<typename T>
  304. const T& Line<T>::getEndY() const noexcept
  305. {
  306. return fPosEnd.fY;
  307. }
  308. template<typename T>
  309. const Point<T>& Line<T>::getStartPos() const noexcept
  310. {
  311. return fPosStart;
  312. }
  313. template<typename T>
  314. const Point<T>& Line<T>::getEndPos() const noexcept
  315. {
  316. return fPosEnd;
  317. }
  318. template<typename T>
  319. void Line<T>::setStartX(const T& x) noexcept
  320. {
  321. fPosStart.fX = x;
  322. }
  323. template<typename T>
  324. void Line<T>::setStartY(const T& y) noexcept
  325. {
  326. fPosStart.fY = y;
  327. }
  328. template<typename T>
  329. void Line<T>::setStartPos(const T& x, const T& y) noexcept
  330. {
  331. fPosStart = Point<T>(x, y);
  332. }
  333. template<typename T>
  334. void Line<T>::setStartPos(const Point<T>& pos) noexcept
  335. {
  336. fPosStart = pos;
  337. }
  338. template<typename T>
  339. void Line<T>::setEndX(const T& x) noexcept
  340. {
  341. fPosEnd.fX = x;
  342. }
  343. template<typename T>
  344. void Line<T>::setEndY(const T& y) noexcept
  345. {
  346. fPosEnd.fY = y;
  347. }
  348. template<typename T>
  349. void Line<T>::setEndPos(const T& x, const T& y) noexcept
  350. {
  351. fPosEnd = Point<T>(x, y);
  352. }
  353. template<typename T>
  354. void Line<T>::setEndPos(const Point<T>& pos) noexcept
  355. {
  356. fPosEnd = pos;
  357. }
  358. template<typename T>
  359. void Line<T>::moveBy(const T& x, const T& y) noexcept
  360. {
  361. fPosStart.moveBy(x, y);
  362. fPosEnd.moveBy(x, y);
  363. }
  364. template<typename T>
  365. void Line<T>::moveBy(const Point<T>& pos) noexcept
  366. {
  367. fPosStart.moveBy(pos);
  368. fPosEnd.moveBy(pos);
  369. }
  370. template<typename T>
  371. void Line<T>::draw()
  372. {
  373. DISTRHO_SAFE_ASSERT_RETURN(fPosStart != fPosEnd,);
  374. glBegin(GL_LINES);
  375. {
  376. glVertex2d(fPosStart.fX, fPosStart.fY);
  377. glVertex2d(fPosEnd.fX, fPosEnd.fY);
  378. }
  379. glEnd();
  380. }
  381. template<typename T>
  382. bool Line<T>::isNull() const noexcept
  383. {
  384. return fPosStart == fPosEnd;
  385. }
  386. template<typename T>
  387. bool Line<T>::isNotNull() const noexcept
  388. {
  389. return fPosStart != fPosEnd;
  390. }
  391. template<typename T>
  392. Line<T>& Line<T>::operator=(const Line<T>& line) noexcept
  393. {
  394. fPosStart = line.fPosStart;
  395. fPosEnd = line.fPosEnd;
  396. return *this;
  397. }
  398. template<typename T>
  399. bool Line<T>::operator==(const Line<T>& line) const noexcept
  400. {
  401. return (fPosStart == line.fPosStart && fPosEnd == line.fPosEnd);
  402. }
  403. template<typename T>
  404. bool Line<T>::operator!=(const Line<T>& line) const noexcept
  405. {
  406. return (fPosStart != line.fPosStart || fPosEnd != line.fPosEnd);
  407. }
  408. // -----------------------------------------------------------------------
  409. // Circle
  410. template<typename T>
  411. Circle<T>::Circle() noexcept
  412. : fPos(0, 0),
  413. fSize(0.0f),
  414. fNumSegments(0),
  415. fTheta(0.0f),
  416. fCos(0.0f),
  417. fSin(0.0f) {}
  418. template<typename T>
  419. Circle<T>::Circle(const T& x, const T& y, const float size, const uint numSegments)
  420. : fPos(x, y),
  421. fSize(size),
  422. fNumSegments(numSegments >= 3 ? numSegments : 3),
  423. fTheta(M_2PIf / static_cast<float>(fNumSegments)),
  424. fCos(std::cos(fTheta)),
  425. fSin(std::sin(fTheta))
  426. {
  427. DISTRHO_SAFE_ASSERT(fSize > 0.0f);
  428. }
  429. template<typename T>
  430. Circle<T>::Circle(const Point<T>& pos, const float size, const uint numSegments)
  431. : fPos(pos),
  432. fSize(size),
  433. fNumSegments(numSegments >= 3 ? numSegments : 3),
  434. fTheta(M_2PIf / static_cast<float>(fNumSegments)),
  435. fCos(std::cos(fTheta)),
  436. fSin(std::sin(fTheta))
  437. {
  438. DISTRHO_SAFE_ASSERT(fSize > 0.0f);
  439. }
  440. template<typename T>
  441. Circle<T>::Circle(const Circle<T>& cir) noexcept
  442. : fPos(cir.fPos),
  443. fSize(cir.fSize),
  444. fNumSegments(cir.fNumSegments),
  445. fTheta(cir.fTheta),
  446. fCos(cir.fCos),
  447. fSin(cir.fSin)
  448. {
  449. DISTRHO_SAFE_ASSERT(fSize > 0.0f);
  450. }
  451. template<typename T>
  452. const T& Circle<T>::getX() const noexcept
  453. {
  454. return fPos.fX;
  455. }
  456. template<typename T>
  457. const T& Circle<T>::getY() const noexcept
  458. {
  459. return fPos.fY;
  460. }
  461. template<typename T>
  462. const Point<T>& Circle<T>::getPos() const noexcept
  463. {
  464. return fPos;
  465. }
  466. template<typename T>
  467. void Circle<T>::setX(const T& x) noexcept
  468. {
  469. fPos.fX = x;
  470. }
  471. template<typename T>
  472. void Circle<T>::setY(const T& y) noexcept
  473. {
  474. fPos.fY = y;
  475. }
  476. template<typename T>
  477. void Circle<T>::setPos(const T& x, const T& y) noexcept
  478. {
  479. fPos.fX = x;
  480. fPos.fY = y;
  481. }
  482. template<typename T>
  483. void Circle<T>::setPos(const Point<T>& pos) noexcept
  484. {
  485. fPos = pos;
  486. }
  487. template<typename T>
  488. float Circle<T>::getSize() const noexcept
  489. {
  490. return fSize;
  491. }
  492. template<typename T>
  493. void Circle<T>::setSize(const float size) noexcept
  494. {
  495. DISTRHO_SAFE_ASSERT_RETURN(size > 0.0f,);
  496. fSize = size;
  497. }
  498. template<typename T>
  499. uint Circle<T>::getNumSegments() const noexcept
  500. {
  501. return fNumSegments;
  502. }
  503. template<typename T>
  504. void Circle<T>::setNumSegments(const uint num)
  505. {
  506. DISTRHO_SAFE_ASSERT_RETURN(num >= 3,);
  507. if (fNumSegments == num)
  508. return;
  509. fNumSegments = num;
  510. fTheta = M_2PIf / static_cast<float>(fNumSegments);
  511. fCos = std::cos(fTheta);
  512. fSin = std::sin(fTheta);
  513. }
  514. template<typename T>
  515. void Circle<T>::draw()
  516. {
  517. _draw(false);
  518. }
  519. template<typename T>
  520. void Circle<T>::drawOutline()
  521. {
  522. _draw(true);
  523. }
  524. template<typename T>
  525. Circle<T>& Circle<T>::operator=(const Circle<T>& cir) noexcept
  526. {
  527. fPos = cir.fPos;
  528. fSize = cir.fSize;
  529. fTheta = cir.fTheta;
  530. fCos = cir.fCos;
  531. fSin = cir.fSin;
  532. fNumSegments = cir.fNumSegments;
  533. return *this;
  534. }
  535. template<typename T>
  536. bool Circle<T>::operator==(const Circle<T>& cir) const noexcept
  537. {
  538. return (fPos == cir.fPos && d_isEqual(fSize, cir.fSize) && fNumSegments == cir.fNumSegments);
  539. }
  540. template<typename T>
  541. bool Circle<T>::operator!=(const Circle<T>& cir) const noexcept
  542. {
  543. return (fPos != cir.fPos || d_isNotEqual(fSize, cir.fSize) || fNumSegments != cir.fNumSegments);
  544. }
  545. template<typename T>
  546. void Circle<T>::_draw(const bool outline)
  547. {
  548. DISTRHO_SAFE_ASSERT_RETURN(fNumSegments >= 3 && fSize > 0.0f,);
  549. double t, x = fSize, y = 0.0;
  550. glBegin(outline ? GL_LINE_LOOP : GL_POLYGON);
  551. for (uint i=0; i<fNumSegments; ++i)
  552. {
  553. glVertex2d(x + fPos.fX, y + fPos.fY);
  554. t = x;
  555. x = fCos * x - fSin * y;
  556. y = fSin * t + fCos * y;
  557. }
  558. glEnd();
  559. }
  560. // -----------------------------------------------------------------------
  561. // Triangle
  562. template<typename T>
  563. Triangle<T>::Triangle() noexcept
  564. : fPos1(0, 0),
  565. fPos2(0, 0),
  566. fPos3(0, 0) {}
  567. template<typename T>
  568. Triangle<T>::Triangle(const T& x1, const T& y1, const T& x2, const T& y2, const T& x3, const T& y3) noexcept
  569. : fPos1(x1, y1),
  570. fPos2(x2, y2),
  571. fPos3(x3, y3) {}
  572. template<typename T>
  573. Triangle<T>::Triangle(const Point<T>& pos1, const Point<T>& pos2, const Point<T>& pos3) noexcept
  574. : fPos1(pos1),
  575. fPos2(pos2),
  576. fPos3(pos3) {}
  577. template<typename T>
  578. Triangle<T>::Triangle(const Triangle<T>& tri) noexcept
  579. : fPos1(tri.fPos1),
  580. fPos2(tri.fPos2),
  581. fPos3(tri.fPos3) {}
  582. template<typename T>
  583. void Triangle<T>::draw()
  584. {
  585. _draw(false);
  586. }
  587. template<typename T>
  588. void Triangle<T>::drawOutline()
  589. {
  590. _draw(true);
  591. }
  592. template<typename T>
  593. bool Triangle<T>::isNull() const noexcept
  594. {
  595. return fPos1 == fPos2 && fPos1 == fPos3;
  596. }
  597. template<typename T>
  598. bool Triangle<T>::isNotNull() const noexcept
  599. {
  600. return fPos1 != fPos2 || fPos1 != fPos3;
  601. }
  602. template<typename T>
  603. bool Triangle<T>::isValid() const noexcept
  604. {
  605. return fPos1 != fPos2 && fPos1 != fPos3;
  606. }
  607. template<typename T>
  608. bool Triangle<T>::isInvalid() const noexcept
  609. {
  610. return fPos1 == fPos2 || fPos1 == fPos3;
  611. }
  612. template<typename T>
  613. Triangle<T>& Triangle<T>::operator=(const Triangle<T>& tri) noexcept
  614. {
  615. fPos1 = tri.fPos1;
  616. fPos2 = tri.fPos2;
  617. fPos3 = tri.fPos3;
  618. return *this;
  619. }
  620. template<typename T>
  621. bool Triangle<T>::operator==(const Triangle<T>& tri) const noexcept
  622. {
  623. return (fPos1 == tri.fPos1 && fPos2 == tri.fPos2 && fPos3 == tri.fPos3);
  624. }
  625. template<typename T>
  626. bool Triangle<T>::operator!=(const Triangle<T>& tri) const noexcept
  627. {
  628. return (fPos1 != tri.fPos1 || fPos2 != tri.fPos2 || fPos3 != tri.fPos3);
  629. }
  630. template<typename T>
  631. void Triangle<T>::_draw(const bool outline)
  632. {
  633. DISTRHO_SAFE_ASSERT_RETURN(fPos1 != fPos2 && fPos1 != fPos3,);
  634. glBegin(outline ? GL_LINE_LOOP : GL_TRIANGLES);
  635. {
  636. glVertex2d(fPos1.fX, fPos1.fY);
  637. glVertex2d(fPos2.fX, fPos2.fY);
  638. glVertex2d(fPos3.fX, fPos3.fY);
  639. }
  640. glEnd();
  641. }
  642. // -----------------------------------------------------------------------
  643. // Rectangle
  644. template<typename T>
  645. Rectangle<T>::Rectangle() noexcept
  646. : fPos(0, 0),
  647. fSize(0, 0) {}
  648. template<typename T>
  649. Rectangle<T>::Rectangle(const T& x, const T& y, const T& width, const T& height) noexcept
  650. : fPos(x, y),
  651. fSize(width, height) {}
  652. template<typename T>
  653. Rectangle<T>::Rectangle(const T& x, const T& y, const Size<T>& size) noexcept
  654. : fPos(x, y),
  655. fSize(size) {}
  656. template<typename T>
  657. Rectangle<T>::Rectangle(const Point<T>& pos, const T& width, const T& height) noexcept
  658. : fPos(pos),
  659. fSize(width, height) {}
  660. template<typename T>
  661. Rectangle<T>::Rectangle(const Point<T>& pos, const Size<T>& size) noexcept
  662. : fPos(pos),
  663. fSize(size) {}
  664. template<typename T>
  665. Rectangle<T>::Rectangle(const Rectangle<T>& rect) noexcept
  666. : fPos(rect.fPos),
  667. fSize(rect.fSize) {}
  668. template<typename T>
  669. const T& Rectangle<T>::getX() const noexcept
  670. {
  671. return fPos.fX;
  672. }
  673. template<typename T>
  674. const T& Rectangle<T>::getY() const noexcept
  675. {
  676. return fPos.fY;
  677. }
  678. template<typename T>
  679. const T& Rectangle<T>::getWidth() const noexcept
  680. {
  681. return fSize.fWidth;
  682. }
  683. template<typename T>
  684. const T& Rectangle<T>::getHeight() const noexcept
  685. {
  686. return fSize.fHeight;
  687. }
  688. template<typename T>
  689. const Point<T>& Rectangle<T>::getPos() const noexcept
  690. {
  691. return fPos;
  692. }
  693. template<typename T>
  694. const Size<T>& Rectangle<T>::getSize() const noexcept
  695. {
  696. return fSize;
  697. }
  698. template<typename T>
  699. void Rectangle<T>::setX(const T& x) noexcept
  700. {
  701. fPos.fX = x;
  702. }
  703. template<typename T>
  704. void Rectangle<T>::setY(const T& y) noexcept
  705. {
  706. fPos.fY = y;
  707. }
  708. template<typename T>
  709. void Rectangle<T>::setPos(const T& x, const T& y) noexcept
  710. {
  711. fPos.fX = x;
  712. fPos.fY = y;
  713. }
  714. template<typename T>
  715. void Rectangle<T>::setPos(const Point<T>& pos) noexcept
  716. {
  717. fPos = pos;
  718. }
  719. template<typename T>
  720. void Rectangle<T>::moveBy(const T& x, const T& y) noexcept
  721. {
  722. fPos.moveBy(x, y);
  723. }
  724. template<typename T>
  725. void Rectangle<T>::moveBy(const Point<T>& pos) noexcept
  726. {
  727. fPos.moveBy(pos);
  728. }
  729. template<typename T>
  730. void Rectangle<T>::setWidth(const T& width) noexcept
  731. {
  732. fSize.fWidth = width;
  733. }
  734. template<typename T>
  735. void Rectangle<T>::setHeight(const T& height) noexcept
  736. {
  737. fSize.fHeight = height;
  738. }
  739. template<typename T>
  740. void Rectangle<T>::setSize(const T& width, const T& height) noexcept
  741. {
  742. fSize.fWidth = width;
  743. fSize.fHeight = height;
  744. }
  745. template<typename T>
  746. void Rectangle<T>::setSize(const Size<T>& size) noexcept
  747. {
  748. fSize = size;
  749. }
  750. template<typename T>
  751. void Rectangle<T>::growBy(double multiplier) noexcept
  752. {
  753. fSize.growBy(multiplier);
  754. }
  755. template<typename T>
  756. void Rectangle<T>::shrinkBy(double divider) noexcept
  757. {
  758. fSize.shrinkBy(divider);
  759. }
  760. template<typename T>
  761. void Rectangle<T>::setRectangle(const Point<T>& pos, const Size<T>& size) noexcept
  762. {
  763. fPos = pos;
  764. fSize = size;
  765. }
  766. template<typename T>
  767. void Rectangle<T>::setRectangle(const Rectangle<T>& rect) noexcept
  768. {
  769. fPos = rect.fPos;
  770. fSize = rect.fSize;
  771. }
  772. template<typename T>
  773. bool Rectangle<T>::contains(const T& x, const T& y) const noexcept
  774. {
  775. return (x >= fPos.fX && y >= fPos.fY && x <= fPos.fX+fSize.fWidth && y <= fPos.fY+fSize.fHeight);
  776. }
  777. template<typename T>
  778. bool Rectangle<T>::contains(const Point<T>& pos) const noexcept
  779. {
  780. return contains(pos.fX, pos.fY);
  781. }
  782. template<typename T>
  783. bool Rectangle<T>::containsX(const T& x) const noexcept
  784. {
  785. return (x >= fPos.fX && x <= fPos.fX + fSize.fWidth);
  786. }
  787. template<typename T>
  788. bool Rectangle<T>::containsY(const T& y) const noexcept
  789. {
  790. return (y >= fPos.fY && y <= fPos.fY + fSize.fHeight);
  791. }
  792. template<typename T>
  793. void Rectangle<T>::draw()
  794. {
  795. _draw(false);
  796. }
  797. template<typename T>
  798. void Rectangle<T>::drawOutline()
  799. {
  800. _draw(true);
  801. }
  802. template<typename T>
  803. Rectangle<T>& Rectangle<T>::operator=(const Rectangle<T>& rect) noexcept
  804. {
  805. fPos = rect.fPos;
  806. fSize = rect.fSize;
  807. return *this;
  808. }
  809. template<typename T>
  810. Rectangle<T>& Rectangle<T>::operator*=(double m) noexcept
  811. {
  812. fSize *= m;
  813. return *this;
  814. }
  815. template<typename T>
  816. Rectangle<T>& Rectangle<T>::operator/=(double d) noexcept
  817. {
  818. fSize /= d;
  819. return *this;
  820. }
  821. template<typename T>
  822. bool Rectangle<T>::operator==(const Rectangle<T>& rect) const noexcept
  823. {
  824. return (fPos == rect.fPos && fSize == rect.fSize);
  825. }
  826. template<typename T>
  827. bool Rectangle<T>::operator!=(const Rectangle<T>& rect) const noexcept
  828. {
  829. return (fPos != rect.fPos || fSize != rect.fSize);
  830. }
  831. template<typename T>
  832. void Rectangle<T>::_draw(const bool outline)
  833. {
  834. DISTRHO_SAFE_ASSERT_RETURN(fSize.isValid(),);
  835. glBegin(outline ? GL_LINE_LOOP : GL_QUADS);
  836. {
  837. glTexCoord2f(0.0f, 0.0f);
  838. glVertex2d(fPos.fX, fPos.fY);
  839. glTexCoord2f(1.0f, 0.0f);
  840. glVertex2d(fPos.fX+fSize.fWidth, fPos.fY);
  841. glTexCoord2f(1.0f, 1.0f);
  842. glVertex2d(fPos.fX+fSize.fWidth, fPos.fY+fSize.fHeight);
  843. glTexCoord2f(0.0f, 1.0f);
  844. glVertex2d(fPos.fX, fPos.fY+fSize.fHeight);
  845. }
  846. glEnd();
  847. }
  848. // -----------------------------------------------------------------------
  849. // Possible template data types
  850. template class Point<double>;
  851. template class Point<float>;
  852. template class Point<int>;
  853. template class Point<uint>;
  854. template class Point<short>;
  855. template class Point<ushort>;
  856. template class Size<double>;
  857. template class Size<float>;
  858. template class Size<int>;
  859. template class Size<uint>;
  860. template class Size<short>;
  861. template class Size<ushort>;
  862. template class Line<double>;
  863. template class Line<float>;
  864. template class Line<int>;
  865. template class Line<uint>;
  866. template class Line<short>;
  867. template class Line<ushort>;
  868. template class Circle<double>;
  869. template class Circle<float>;
  870. template class Circle<int>;
  871. template class Circle<uint>;
  872. template class Circle<short>;
  873. template class Circle<ushort>;
  874. template class Triangle<double>;
  875. template class Triangle<float>;
  876. template class Triangle<int>;
  877. template class Triangle<uint>;
  878. template class Triangle<short>;
  879. template class Triangle<ushort>;
  880. template class Rectangle<double>;
  881. template class Rectangle<float>;
  882. template class Rectangle<int>;
  883. template class Rectangle<uint>;
  884. template class Rectangle<short>;
  885. template class Rectangle<ushort>;
  886. // -----------------------------------------------------------------------
  887. END_NAMESPACE_DGL