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.

833 lines
20KB

  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 x, y;
  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 are 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. /**
  285. Return true if line is null (start and end pos are equal).
  286. */
  287. bool isNull() const noexcept;
  288. /**
  289. Return true if line is not null (start and end pos are different).
  290. */
  291. bool isNotNull() const noexcept;
  292. #ifndef DPF_TEST_POINT_CPP
  293. /**
  294. Draw this line using the provided graphics context, optionally specifying line width.
  295. */
  296. void draw(const GraphicsContext& context, T width = 1);
  297. #endif
  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. #ifndef DPF_TEST_POINT_CPP
  302. /**
  303. Draw this line using the current OpenGL state.@n
  304. DEPRECATED Please use draw(const GraphicsContext&) instead.
  305. */
  306. DISTRHO_DEPRECATED_BY("draw(const GraphicsContext&)")
  307. void draw();
  308. #endif
  309. private:
  310. Point<T> posStart, posEnd;
  311. };
  312. // -----------------------------------------------------------------------
  313. /**
  314. DGL Circle class.
  315. This class describes a circle, defined by position, size and a minimum of 3 segments.
  316. TODO: report if circle starts at top-left, bottom-right or center.
  317. and size grows from which point?
  318. */
  319. template<typename T>
  320. class Circle
  321. {
  322. public:
  323. /**
  324. Constructor for a null circle.
  325. */
  326. Circle() noexcept;
  327. /**
  328. Constructor using custom X, Y and size values.
  329. */
  330. Circle(const T& x, const T& y, const float size, const uint numSegments = 300);
  331. /**
  332. Constructor using custom position and size values.
  333. */
  334. Circle(const Point<T>& pos, const float size, const uint numSegments = 300);
  335. /**
  336. Constructor using another Circle class values.
  337. */
  338. Circle(const Circle<T>& cir) noexcept;
  339. /**
  340. Get X value.
  341. */
  342. const T& getX() const noexcept;
  343. /**
  344. Get Y value.
  345. */
  346. const T& getY() const noexcept;
  347. /**
  348. Get position.
  349. */
  350. const Point<T>& getPos() const noexcept;
  351. /**
  352. Set X value to @a x.
  353. */
  354. void setX(const T& x) noexcept;
  355. /**
  356. Set Y value to @a y.
  357. */
  358. void setY(const T& y) noexcept;
  359. /**
  360. Set X and Y values to @a x and @a y respectively.
  361. */
  362. void setPos(const T& x, const T& y) noexcept;
  363. /**
  364. Set X and Y values according to @a pos.
  365. */
  366. void setPos(const Point<T>& pos) noexcept;
  367. /**
  368. Get size.
  369. */
  370. float getSize() const noexcept;
  371. /**
  372. Set size.
  373. @note Must always be > 0
  374. */
  375. void setSize(const float size) noexcept;
  376. /**
  377. Get the current number of line segments that make this circle.
  378. */
  379. uint getNumSegments() const noexcept;
  380. /**
  381. Set the number of line segments that will make this circle.
  382. @note Must always be >= 3
  383. */
  384. void setNumSegments(const uint num);
  385. /**
  386. Draw this circle using the provided graphics context.
  387. */
  388. void draw(const GraphicsContext& context);
  389. /**
  390. Draw lines (outline of this circle) using the provided graphics context, optionally specifying line width.
  391. */
  392. void drawOutline(const GraphicsContext& context, T lineWidth = 1);
  393. Circle<T>& operator=(const Circle<T>& cir) noexcept;
  394. bool operator==(const Circle<T>& cir) const noexcept;
  395. bool operator!=(const Circle<T>& cir) const noexcept;
  396. #ifndef DPF_TEST_POINT_CPP
  397. /**
  398. Draw this circle using the current OpenGL state.@n
  399. DEPRECATED Please use draw(const GraphicsContext&) instead.
  400. */
  401. DISTRHO_DEPRECATED_BY("draw(const GraphicsContext&)")
  402. void draw();
  403. /**
  404. Draw lines (outline of this circle) using the current OpenGL state.@n
  405. DEPRECATED Please use drawOutline(const GraphicsContext&,T) instead.
  406. */
  407. DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)")
  408. void drawOutline();
  409. #endif
  410. private:
  411. Point<T> fPos;
  412. float fSize;
  413. uint fNumSegments;
  414. // cached values
  415. float fTheta, fCos, fSin;
  416. };
  417. // -----------------------------------------------------------------------
  418. /**
  419. DGL Triangle class.
  420. This class describes a triangle, defined by 3 points.
  421. */
  422. template<typename T>
  423. class Triangle
  424. {
  425. public:
  426. /**
  427. Constructor for a null triangle.
  428. */
  429. Triangle() noexcept;
  430. /**
  431. Constructor using custom X and Y values.
  432. */
  433. Triangle(const T& x1, const T& y1, const T& x2, const T& y2, const T& x3, const T& y3) noexcept;
  434. /**
  435. Constructor using custom position values.
  436. */
  437. Triangle(const Point<T>& pos1, const Point<T>& pos2, const Point<T>& pos3) noexcept;
  438. /**
  439. Constructor using another Triangle class values.
  440. */
  441. Triangle(const Triangle<T>& tri) noexcept;
  442. /**
  443. Return true if triangle is null (all its points are equal).
  444. An null triangle is also invalid.
  445. */
  446. bool isNull() const noexcept;
  447. /**
  448. Return true if triangle is not null (one its points is different from the others).
  449. A non-null triangle is still invalid if two of its points are equal.
  450. */
  451. bool isNotNull() const noexcept;
  452. /**
  453. Return true if triangle is valid (all its points are different).
  454. */
  455. bool isValid() const noexcept;
  456. /**
  457. Return true if triangle is invalid (one or two of its points are equal).
  458. An invalid triangle might not be null under some circumstances.
  459. */
  460. bool isInvalid() const noexcept;
  461. /**
  462. Draw this triangle using the provided graphics context.
  463. */
  464. void draw(const GraphicsContext& context);
  465. /**
  466. Draw lines (outline of this triangle) using the provided graphics context, optionally specifying line width.
  467. */
  468. void drawOutline(const GraphicsContext& context, T lineWidth = 1);
  469. Triangle<T>& operator=(const Triangle<T>& tri) noexcept;
  470. bool operator==(const Triangle<T>& tri) const noexcept;
  471. bool operator!=(const Triangle<T>& tri) const noexcept;
  472. #ifndef DPF_TEST_POINT_CPP
  473. /**
  474. Draw this triangle using the current OpenGL state.@n
  475. DEPRECATED Please use draw(const GraphicsContext&) instead.
  476. */
  477. DISTRHO_DEPRECATED_BY("draw(const GraphicsContext&)")
  478. void draw();
  479. /**
  480. Draw lines (outline of this triangle) using the current OpenGL state.@n
  481. DEPRECATED Please use drawOutline(const GraphicsContext&,T) instead.
  482. */
  483. DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)")
  484. void drawOutline();
  485. #endif
  486. private:
  487. Point<T> pos1, pos2, pos3;
  488. };
  489. // -----------------------------------------------------------------------
  490. /**
  491. DGL Rectangle class.
  492. This class describes a rectangle, defined by a starting point and a size.
  493. */
  494. template<typename T>
  495. class Rectangle
  496. {
  497. public:
  498. /**
  499. Constructor for a null rectangle.
  500. */
  501. Rectangle() noexcept;
  502. /**
  503. Constructor using custom X, Y, width and height values.
  504. */
  505. Rectangle(const T& x, const T& y, const T& width, const T& height) noexcept;
  506. /**
  507. Constructor using custom X, Y and size values.
  508. */
  509. Rectangle(const T& x, const T& y, const Size<T>& size) noexcept;
  510. /**
  511. Constructor using custom pos, width and height values.
  512. */
  513. Rectangle(const Point<T>& pos, const T& width, const T& height) noexcept;
  514. /**
  515. Constructor using custom position and size.
  516. */
  517. Rectangle(const Point<T>& pos, const Size<T>& size) noexcept;
  518. /**
  519. Constructor using another Rectangle class values.
  520. */
  521. Rectangle(const Rectangle<T>& rect) noexcept;
  522. /**
  523. Get X value.
  524. */
  525. const T& getX() const noexcept;
  526. /**
  527. Get Y value.
  528. */
  529. const T& getY() const noexcept;
  530. /**
  531. Get width.
  532. */
  533. const T& getWidth() const noexcept;
  534. /**
  535. Get height.
  536. */
  537. const T& getHeight() const noexcept;
  538. /**
  539. Get position.
  540. */
  541. const Point<T>& getPos() const noexcept;
  542. /**
  543. Get size.
  544. */
  545. const Size<T>& getSize() const noexcept;
  546. /**
  547. Set X value as @a x.
  548. */
  549. void setX(const T& x) noexcept;
  550. /**
  551. Set Y value as @a y.
  552. */
  553. void setY(const T& y) noexcept;
  554. /**
  555. Set X and Y values as @a x and @a y respectively.
  556. */
  557. void setPos(const T& x, const T& y) noexcept;
  558. /**
  559. Set X and Y values according to @a pos.
  560. */
  561. void setPos(const Point<T>& pos) noexcept;
  562. /**
  563. Move this rectangle by @a x and @a y values.
  564. */
  565. void moveBy(const T& x, const T& y) noexcept;
  566. /**
  567. Move this rectangle by @a pos.
  568. */
  569. void moveBy(const Point<T>& pos) noexcept;
  570. /**
  571. Set width.
  572. */
  573. void setWidth(const T& width) noexcept;
  574. /**
  575. Set height.
  576. */
  577. void setHeight(const T& height) noexcept;
  578. /**
  579. Set size using @a width and @a height.
  580. */
  581. void setSize(const T& width, const T& height) noexcept;
  582. /**
  583. Set size.
  584. */
  585. void setSize(const Size<T>& size) noexcept;
  586. /**
  587. Grow size by @a multiplier.
  588. */
  589. void growBy(double multiplier) noexcept;
  590. /**
  591. Shrink size by @a divider.
  592. */
  593. void shrinkBy(double divider) noexcept;
  594. /**
  595. Set rectangle using @a pos and @a size.
  596. */
  597. void setRectangle(const Point<T>& pos, const Size<T>& size) noexcept;
  598. /**
  599. Set rectangle.
  600. */
  601. void setRectangle(const Rectangle<T>& rect) noexcept;
  602. /**
  603. Check if this rectangle contains the point defined by @a X and @a Y.
  604. */
  605. bool contains(const T& x, const T& y) const noexcept;
  606. /**
  607. Check if this rectangle contains the point @a pos.
  608. */
  609. bool contains(const Point<T>& pos) const noexcept;
  610. /**
  611. Check if this rectangle contains the point @a pos of another type.
  612. */
  613. template<typename T2>
  614. bool contains(const Point<T2>& pos) const noexcept;
  615. /**
  616. Check if this rectangle contains X.
  617. */
  618. bool containsX(const T& x) const noexcept;
  619. /**
  620. Check if this rectangle contains Y.
  621. */
  622. bool containsY(const T& y) const noexcept;
  623. /**
  624. Return true if size is null (0x0).
  625. An null size is also invalid.
  626. */
  627. bool isNull() const noexcept;
  628. /**
  629. Return true if size is not null (0x0).
  630. A non-null size is still invalid if its width or height are negative.
  631. */
  632. bool isNotNull() const noexcept;
  633. /**
  634. Return true if size is valid (width and height are higher than zero).
  635. */
  636. bool isValid() const noexcept;
  637. /**
  638. Return true if size is invalid (width or height are lower or equal to zero).
  639. An invalid size might not be null under some circumstances.
  640. */
  641. bool isInvalid() const noexcept;
  642. /**
  643. Draw this rectangle using the provided graphics context.
  644. */
  645. void draw(const GraphicsContext& context);
  646. /**
  647. Draw lines (outline of this rectangle) using the provided graphics context, optionally specifying line width.
  648. */
  649. void drawOutline(const GraphicsContext& context, T lineWidth = 1);
  650. Rectangle<T>& operator=(const Rectangle<T>& rect) noexcept;
  651. Rectangle<T>& operator*=(double m) noexcept;
  652. Rectangle<T>& operator/=(double d) noexcept;
  653. bool operator==(const Rectangle<T>& size) const noexcept;
  654. bool operator!=(const Rectangle<T>& size) const noexcept;
  655. /**
  656. Draw this rectangle using the current OpenGL state.@n
  657. DEPRECATED Please use draw(const GraphicsContext&) instead.
  658. */
  659. DISTRHO_DEPRECATED_BY("draw(const GraphicsContext&)")
  660. void draw();
  661. /**
  662. Draw lines (outline of this rectangle) using the current OpenGL state.@n
  663. DEPRECATED Please use drawOutline(const GraphicsContext&,T) instead.
  664. */
  665. DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)")
  666. void drawOutline();
  667. private:
  668. Point<T> pos;
  669. Size<T> size;
  670. };
  671. // -----------------------------------------------------------------------
  672. END_NAMESPACE_DGL
  673. #endif // DGL_GEOMETRY_HPP_INCLUDED