DISTRHO Plugin Framework
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.

768 lines
17KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2021 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. #ifndef DGL_GEOMETRY_HPP_INCLUDED
  17. #define DGL_GEOMETRY_HPP_INCLUDED
  18. #include "Base.hpp"
  19. START_NAMESPACE_DGL
  20. // --------------------------------------------------------------------------------------------------------------------
  21. // Forward class names
  22. template<typename> class Line;
  23. template<typename> class Circle;
  24. template<typename> class Triangle;
  25. template<typename> class Rectangle;
  26. // --------------------------------------------------------------------------------------------------------------------
  27. /**
  28. DGL Point class.
  29. This class describes a single point in space, defined by an X and Y value.
  30. */
  31. template<typename T>
  32. class Point
  33. {
  34. public:
  35. /**
  36. Constructor for (0, 0) point.
  37. */
  38. Point() noexcept;
  39. /**
  40. Constructor using custom X and Y values.
  41. */
  42. Point(const T& x, const T& y) noexcept;
  43. /**
  44. Constructor using another Point class values.
  45. */
  46. Point(const Point<T>& pos) noexcept;
  47. /**
  48. Get X value.
  49. */
  50. const T& getX() const noexcept;
  51. /**
  52. Get Y value.
  53. */
  54. const T& getY() const noexcept;
  55. /**
  56. Set X value to @a x.
  57. */
  58. void setX(const T& x) noexcept;
  59. /**
  60. Set Y value to @a y.
  61. */
  62. void setY(const T& y) noexcept;
  63. /**
  64. Set X and Y values to @a x and @a y respectively.
  65. */
  66. void setPos(const T& x, const T& y) noexcept;
  67. /**
  68. Set X and Y values according to @a pos.
  69. */
  70. void setPos(const Point<T>& pos) noexcept;
  71. /**
  72. Move this point by @a x and @a y values.
  73. */
  74. void moveBy(const T& x, const T& y) noexcept;
  75. /**
  76. Move this point by @a pos.
  77. */
  78. void moveBy(const Point<T>& pos) noexcept;
  79. /**
  80. Return true if point is (0, 0).
  81. */
  82. bool isZero() const noexcept;
  83. /**
  84. Return true if point is not (0, 0).
  85. */
  86. bool isNotZero() const noexcept;
  87. Point<T> operator+(const Point<T>& pos) noexcept;
  88. Point<T> operator-(const Point<T>& pos) noexcept;
  89. Point<T>& operator=(const Point<T>& pos) noexcept;
  90. Point<T>& operator+=(const Point<T>& pos) noexcept;
  91. Point<T>& operator-=(const Point<T>& pos) noexcept;
  92. bool operator==(const Point<T>& pos) const noexcept;
  93. bool operator!=(const Point<T>& pos) const noexcept;
  94. private:
  95. T fX, fY;
  96. template<typename> friend class Line;
  97. template<typename> friend class Circle;
  98. template<typename> friend class Triangle;
  99. template<typename> friend class Rectangle;
  100. };
  101. // --------------------------------------------------------------------------------------------------------------------
  102. /**
  103. DGL Size class.
  104. This class describes a size, defined by a width and height value.
  105. */
  106. template<typename T>
  107. class Size
  108. {
  109. public:
  110. /**
  111. Constructor for null size (0x0).
  112. */
  113. Size() noexcept;
  114. /**
  115. Constructor using custom width and height values.
  116. */
  117. Size(const T& width, const T& height) noexcept;
  118. /**
  119. Constructor using another Size class values.
  120. */
  121. Size(const Size<T>& size) noexcept;
  122. /**
  123. Get width.
  124. */
  125. const T& getWidth() const noexcept;
  126. /**
  127. Get height.
  128. */
  129. const T& getHeight() const noexcept;
  130. /**
  131. Set width.
  132. */
  133. void setWidth(const T& width) noexcept;
  134. /**
  135. Set height.
  136. */
  137. void setHeight(const T& height) noexcept;
  138. /**
  139. Set size to @a width and @a height.
  140. */
  141. void setSize(const T& width, const T& height) noexcept;
  142. /**
  143. Set size.
  144. */
  145. void setSize(const Size<T>& size) noexcept;
  146. /**
  147. Grow size by @a multiplier.
  148. */
  149. void growBy(double multiplier) noexcept;
  150. /**
  151. Shrink size by @a divider.
  152. */
  153. void shrinkBy(double divider) noexcept;
  154. /**
  155. Return true if size is null (0x0).
  156. An null size is also invalid.
  157. */
  158. bool isNull() const noexcept;
  159. /**
  160. Return true if size is not null (0x0).
  161. A non-null size is still invalid if its width or height is negative.
  162. */
  163. bool isNotNull() const noexcept;
  164. /**
  165. Return true if size is valid (width and height are higher than zero).
  166. */
  167. bool isValid() const noexcept;
  168. /**
  169. Return true if size is invalid (width or height are lower or equal to zero).
  170. An invalid size might not be null under some circumstances.
  171. */
  172. bool isInvalid() const noexcept;
  173. Size<int> toInt() const noexcept;
  174. Size<T> operator+(const Size<T>& size) noexcept;
  175. Size<T> operator-(const Size<T>& size) noexcept;
  176. Size<T>& operator=(const Size<T>& size) noexcept;
  177. Size<T>& operator+=(const Size<T>& size) noexcept;
  178. Size<T>& operator-=(const Size<T>& size) noexcept;
  179. Size<T>& operator*=(double m) noexcept;
  180. Size<T>& operator/=(double d) noexcept;
  181. bool operator==(const Size<T>& size) const noexcept;
  182. bool operator!=(const Size<T>& size) const noexcept;
  183. private:
  184. T fWidth, fHeight;
  185. template<typename> friend class Rectangle;
  186. };
  187. // -----------------------------------------------------------------------
  188. /**
  189. DGL Line class.
  190. This class describes a line, defined by two points.
  191. */
  192. template<typename T>
  193. class Line
  194. {
  195. public:
  196. /**
  197. Constructor for a null line ([0,0] to [0,0]).
  198. */
  199. Line() noexcept;
  200. /**
  201. Constructor using custom start X, start Y, end X and end Y values.
  202. */
  203. Line(const T& startX, const T& startY, const T& endX, const T& endY) noexcept;
  204. /**
  205. Constructor using custom start X, start Y and end pos values.
  206. */
  207. Line(const T& startX, const T& startY, const Point<T>& endPos) noexcept;
  208. /**
  209. Constructor using custom start pos, end X and end Y values.
  210. */
  211. Line(const Point<T>& startPos, const T& endX, const T& endY) noexcept;
  212. /**
  213. Constructor using custom start and end pos values.
  214. */
  215. Line(const Point<T>& startPos, const Point<T>& endPos) noexcept;
  216. /**
  217. Constructor using another Line class values.
  218. */
  219. Line(const Line<T>& line) noexcept;
  220. /**
  221. Get start X value.
  222. */
  223. const T& getStartX() const noexcept;
  224. /**
  225. Get start Y value.
  226. */
  227. const T& getStartY() const noexcept;
  228. /**
  229. Get end X value.
  230. */
  231. const T& getEndX() const noexcept;
  232. /**
  233. Get end Y value.
  234. */
  235. const T& getEndY() const noexcept;
  236. /**
  237. Get start position.
  238. */
  239. const Point<T>& getStartPos() const noexcept;
  240. /**
  241. Get end position.
  242. */
  243. const Point<T>& getEndPos() const noexcept;
  244. /**
  245. Set start X value to @a x.
  246. */
  247. void setStartX(const T& x) noexcept;
  248. /**
  249. Set start Y value to @a y.
  250. */
  251. void setStartY(const T& y) noexcept;
  252. /**
  253. Set start X and Y values to @a x and @a y respectively.
  254. */
  255. void setStartPos(const T& x, const T& y) noexcept;
  256. /**
  257. Set start X and Y values according to @a pos.
  258. */
  259. void setStartPos(const Point<T>& pos) noexcept;
  260. /**
  261. Set end X value to @a x.
  262. */
  263. void setEndX(const T& x) noexcept;
  264. /**
  265. Set end Y value to @a y.
  266. */
  267. void setEndY(const T& y) noexcept;
  268. /**
  269. Set end X and Y values to @a x and @a y respectively.
  270. */
  271. void setEndPos(const T& x, const T& y) noexcept;
  272. /**
  273. Set end X and Y values according to @a pos.
  274. */
  275. void setEndPos(const Point<T>& pos) noexcept;
  276. /**
  277. Move this line by @a x and @a y values.
  278. */
  279. void moveBy(const T& x, const T& y) noexcept;
  280. /**
  281. Move this line by @a pos.
  282. */
  283. void moveBy(const Point<T>& pos) noexcept;
  284. #ifndef DPF_TEST_POINT_CPP
  285. /**
  286. Draw this line using the current OpenGL state.
  287. */
  288. void draw();
  289. #endif
  290. /**
  291. Return true if line is null (start and end pos are equal).
  292. */
  293. bool isNull() const noexcept;
  294. /**
  295. Return true if line is not null (start and end pos are different).
  296. */
  297. bool isNotNull() const noexcept;
  298. Line<T>& operator=(const Line<T>& line) noexcept;
  299. bool operator==(const Line<T>& line) const noexcept;
  300. bool operator!=(const Line<T>& line) const noexcept;
  301. private:
  302. Point<T> fPosStart, fPosEnd;
  303. };
  304. // -----------------------------------------------------------------------
  305. /**
  306. DGL Circle class.
  307. This class describes a circle, defined by position, size and a minimum of 3 segments.
  308. TODO: report if circle starts at top-left, bottom-right or center.
  309. and size grows from which point?
  310. */
  311. template<typename T>
  312. class Circle
  313. {
  314. public:
  315. /**
  316. Constructor for a null circle.
  317. */
  318. Circle() noexcept;
  319. /**
  320. Constructor using custom X, Y and size values.
  321. */
  322. Circle(const T& x, const T& y, const float size, const uint numSegments = 300);
  323. /**
  324. Constructor using custom position and size values.
  325. */
  326. Circle(const Point<T>& pos, const float size, const uint numSegments = 300);
  327. /**
  328. Constructor using another Circle class values.
  329. */
  330. Circle(const Circle<T>& cir) noexcept;
  331. /**
  332. Get X value.
  333. */
  334. const T& getX() const noexcept;
  335. /**
  336. Get Y value.
  337. */
  338. const T& getY() const noexcept;
  339. /**
  340. Get position.
  341. */
  342. const Point<T>& getPos() const noexcept;
  343. /**
  344. Set X value to @a x.
  345. */
  346. void setX(const T& x) noexcept;
  347. /**
  348. Set Y value to @a y.
  349. */
  350. void setY(const T& y) noexcept;
  351. /**
  352. Set X and Y values to @a x and @a y respectively.
  353. */
  354. void setPos(const T& x, const T& y) noexcept;
  355. /**
  356. Set X and Y values according to @a pos.
  357. */
  358. void setPos(const Point<T>& pos) noexcept;
  359. /**
  360. Get size.
  361. */
  362. float getSize() const noexcept;
  363. /**
  364. Set size.
  365. @note Must always be > 0
  366. */
  367. void setSize(const float size) noexcept;
  368. /**
  369. Get the current number of line segments that make this circle.
  370. */
  371. uint getNumSegments() const noexcept;
  372. /**
  373. Set the number of line segments that will make this circle.
  374. @note Must always be >= 3
  375. */
  376. void setNumSegments(const uint num);
  377. #ifndef DPF_TEST_POINT_CPP
  378. /**
  379. Draw this circle using the current OpenGL state.
  380. */
  381. void draw();
  382. /**
  383. Draw lines (outline of this circle) using the current OpenGL state.
  384. */
  385. void drawOutline();
  386. #endif
  387. Circle<T>& operator=(const Circle<T>& cir) noexcept;
  388. bool operator==(const Circle<T>& cir) const noexcept;
  389. bool operator!=(const Circle<T>& cir) const noexcept;
  390. private:
  391. Point<T> fPos;
  392. float fSize;
  393. uint fNumSegments;
  394. // cached values
  395. float fTheta, fCos, fSin;
  396. /** @internal */
  397. void _draw(const bool outline);
  398. };
  399. // -----------------------------------------------------------------------
  400. /**
  401. DGL Triangle class.
  402. This class describes a triangle, defined by 3 points.
  403. */
  404. template<typename T>
  405. class Triangle
  406. {
  407. public:
  408. /**
  409. Constructor for a null triangle.
  410. */
  411. Triangle() noexcept;
  412. /**
  413. Constructor using custom X and Y values.
  414. */
  415. Triangle(const T& x1, const T& y1, const T& x2, const T& y2, const T& x3, const T& y3) noexcept;
  416. /**
  417. Constructor using custom position values.
  418. */
  419. Triangle(const Point<T>& pos1, const Point<T>& pos2, const Point<T>& pos3) noexcept;
  420. /**
  421. Constructor using another Triangle class values.
  422. */
  423. Triangle(const Triangle<T>& tri) noexcept;
  424. /**
  425. Return true if triangle is null (all its points are equal).
  426. An null triangle is also invalid.
  427. */
  428. bool isNull() const noexcept;
  429. /**
  430. Return true if triangle is not null (one its points is different from the others).
  431. A non-null triangle is still invalid if two of its points are equal.
  432. */
  433. bool isNotNull() const noexcept;
  434. /**
  435. Return true if triangle is valid (all its points are different).
  436. */
  437. bool isValid() const noexcept;
  438. /**
  439. Return true if triangle is invalid (one or two of its points are equal).
  440. An invalid triangle might not be null under some circumstances.
  441. */
  442. bool isInvalid() const noexcept;
  443. #ifndef DPF_TEST_POINT_CPP
  444. /**
  445. Draw this triangle using the current OpenGL state.
  446. */
  447. void draw();
  448. /**
  449. Draw lines (outline of this triangle) using the current OpenGL state.
  450. */
  451. void drawOutline();
  452. #endif
  453. Triangle<T>& operator=(const Triangle<T>& tri) noexcept;
  454. bool operator==(const Triangle<T>& tri) const noexcept;
  455. bool operator!=(const Triangle<T>& tri) const noexcept;
  456. private:
  457. Point<T> fPos1, fPos2, fPos3;
  458. #ifndef DPF_TEST_POINT_CPP
  459. /** @internal */
  460. void _draw(const bool outline);
  461. #endif
  462. };
  463. // -----------------------------------------------------------------------
  464. /**
  465. DGL Rectangle class.
  466. This class describes a rectangle, defined by a starting point and a size.
  467. */
  468. template<typename T>
  469. class Rectangle
  470. {
  471. public:
  472. /**
  473. Constructor for a null rectangle.
  474. */
  475. Rectangle() noexcept;
  476. /**
  477. Constructor using custom X, Y, width and height values.
  478. */
  479. Rectangle(const T& x, const T& y, const T& width, const T& height) noexcept;
  480. /**
  481. Constructor using custom X, Y and size values.
  482. */
  483. Rectangle(const T& x, const T& y, const Size<T>& size) noexcept;
  484. /**
  485. Constructor using custom pos, width and height values.
  486. */
  487. Rectangle(const Point<T>& pos, const T& width, const T& height) noexcept;
  488. /**
  489. Constructor using custom position and size.
  490. */
  491. Rectangle(const Point<T>& pos, const Size<T>& size) noexcept;
  492. /**
  493. Constructor using another Rectangle class values.
  494. */
  495. Rectangle(const Rectangle<T>& rect) noexcept;
  496. /**
  497. Get X value.
  498. */
  499. const T& getX() const noexcept;
  500. /**
  501. Get Y value.
  502. */
  503. const T& getY() const noexcept;
  504. /**
  505. Get width.
  506. */
  507. const T& getWidth() const noexcept;
  508. /**
  509. Get height.
  510. */
  511. const T& getHeight() const noexcept;
  512. /**
  513. Get position.
  514. */
  515. const Point<T>& getPos() const noexcept;
  516. /**
  517. Get size.
  518. */
  519. const Size<T>& getSize() const noexcept;
  520. /**
  521. Set X value as @a x.
  522. */
  523. void setX(const T& x) noexcept;
  524. /**
  525. Set Y value as @a y.
  526. */
  527. void setY(const T& y) noexcept;
  528. /**
  529. Set X and Y values as @a x and @a y respectively.
  530. */
  531. void setPos(const T& x, const T& y) noexcept;
  532. /**
  533. Set X and Y values according to @a pos.
  534. */
  535. void setPos(const Point<T>& pos) noexcept;
  536. /**
  537. Move this rectangle by @a x and @a y values.
  538. */
  539. void moveBy(const T& x, const T& y) noexcept;
  540. /**
  541. Move this rectangle by @a pos.
  542. */
  543. void moveBy(const Point<T>& pos) noexcept;
  544. /**
  545. Set width.
  546. */
  547. void setWidth(const T& width) noexcept;
  548. /**
  549. Set height.
  550. */
  551. void setHeight(const T& height) noexcept;
  552. /**
  553. Set size using @a width and @a height.
  554. */
  555. void setSize(const T& width, const T& height) noexcept;
  556. /**
  557. Set size.
  558. */
  559. void setSize(const Size<T>& size) noexcept;
  560. /**
  561. Grow size by @a multiplier.
  562. */
  563. void growBy(double multiplier) noexcept;
  564. /**
  565. Shrink size by @a divider.
  566. */
  567. void shrinkBy(double divider) noexcept;
  568. /**
  569. Set rectangle using @a pos and @a size.
  570. */
  571. void setRectangle(const Point<T>& pos, const Size<T>& size) noexcept;
  572. /**
  573. Set rectangle.
  574. */
  575. void setRectangle(const Rectangle<T>& rect) noexcept;
  576. /**
  577. Check if this rectangle contains the point defined by @a X and @a Y.
  578. */
  579. bool contains(const T& x, const T& y) const noexcept;
  580. /**
  581. Check if this rectangle contains the point @a pos.
  582. */
  583. bool contains(const Point<T>& pos) const noexcept;
  584. /**
  585. Check if this rectangle contains X.
  586. */
  587. bool containsX(const T& x) const noexcept;
  588. /**
  589. Check if this rectangle contains Y.
  590. */
  591. bool containsY(const T& y) const noexcept;
  592. #ifndef DPF_TEST_POINT_CPP
  593. /**
  594. Draw this rectangle using the current OpenGL state.
  595. */
  596. void draw();
  597. /**
  598. Draw lines (outline of this rectangle) using the current OpenGL state.
  599. */
  600. void drawOutline();
  601. #endif
  602. Rectangle<T>& operator=(const Rectangle<T>& rect) noexcept;
  603. Rectangle<T>& operator*=(double m) noexcept;
  604. Rectangle<T>& operator/=(double d) noexcept;
  605. bool operator==(const Rectangle<T>& size) const noexcept;
  606. bool operator!=(const Rectangle<T>& size) const noexcept;
  607. private:
  608. Point<T> fPos;
  609. Size<T> fSize;
  610. #ifndef DPF_TEST_POINT_CPP
  611. /** @internal */
  612. void _draw(const bool outline);
  613. #endif
  614. };
  615. // -----------------------------------------------------------------------
  616. END_NAMESPACE_DGL
  617. #endif // DGL_GEOMETRY_HPP_INCLUDED