edge-segments.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #pragma once
  2. #include "Vector2.hpp"
  3. #include "SignedDistance.hpp"
  4. #include "EdgeColor.h"
  5. namespace msdfgen {
  6. /// An abstract edge segment.
  7. class EdgeSegment {
  8. public:
  9. EdgeColor color;
  10. static EdgeSegment *create(Point2 p0, Point2 p1, EdgeColor edgeColor = WHITE);
  11. static EdgeSegment *create(Point2 p0, Point2 p1, Point2 p2, EdgeColor edgeColor = WHITE);
  12. static EdgeSegment *create(Point2 p0, Point2 p1, Point2 p2, Point2 p3, EdgeColor edgeColor = WHITE);
  13. EdgeSegment(EdgeColor edgeColor = WHITE) : color(edgeColor) { }
  14. virtual ~EdgeSegment() { }
  15. /// Creates a copy of the edge segment.
  16. virtual EdgeSegment *clone() const = 0;
  17. /// Returns the numeric code of the edge segment's type.
  18. virtual int type() const = 0;
  19. /// Returns the array of control points.
  20. virtual const Point2 *controlPoints() const = 0;
  21. /// Returns the point on the edge specified by the parameter (between 0 and 1).
  22. virtual Point2 point(double param) const = 0;
  23. /// Returns the direction the edge has at the point specified by the parameter.
  24. virtual Vector2 direction(double param) const = 0;
  25. /// Returns the change of direction (second derivative) at the point specified by the parameter.
  26. virtual Vector2 directionChange(double param) const = 0;
  27. /// Returns the minimum signed distance between origin and the edge.
  28. virtual SignedDistance signedDistance(Point2 origin, double &param) const = 0;
  29. /// Converts a previously retrieved signed distance from origin to perpendicular distance.
  30. virtual void distanceToPerpendicularDistance(SignedDistance &distance, Point2 origin, double param) const;
  31. /// Outputs a list of (at most three) intersections (their X coordinates) with an infinite horizontal scanline at y and returns how many there are.
  32. virtual int scanlineIntersections(double x[3], int dy[3], double y) const = 0;
  33. virtual int horizontalScanlineIntersections(double x[3], int dy[3], double y) const = 0;
  34. /// Outputs a list of (at most three) intersections (their Y coordinates) with an infinite vertical scanline at x and returns how many there are.
  35. virtual int verticalScanlineIntersections(double y[3], int dx[3], double x) const = 0;
  36. /// Adjusts the bounding box to fit the edge segment.
  37. virtual void bound(double &l, double &b, double &r, double &t) const = 0;
  38. /// Reverses the edge (swaps its start point and end point).
  39. virtual void reverse() = 0;
  40. /// Moves the start point of the edge segment.
  41. virtual void moveStartPoint(Point2 to) = 0;
  42. /// Moves the end point of the edge segment.
  43. virtual void moveEndPoint(Point2 to) = 0;
  44. /// Splits the edge segments into thirds which together represent the original edge.
  45. virtual void splitInThirds(EdgeSegment *&part0, EdgeSegment *&part1, EdgeSegment *&part2) const = 0;
  46. };
  47. /// A line segment.
  48. class LinearSegment : public EdgeSegment {
  49. public:
  50. enum EdgeType {
  51. EDGE_TYPE = 1
  52. };
  53. Point2 p[2];
  54. LinearSegment(Point2 p0, Point2 p1, EdgeColor edgeColor = WHITE);
  55. LinearSegment *clone() const;
  56. int type() const;
  57. const Point2 *controlPoints() const;
  58. Point2 point(double param) const;
  59. Vector2 direction(double param) const;
  60. Vector2 directionChange(double param) const;
  61. double length() const;
  62. SignedDistance signedDistance(Point2 origin, double &param) const;
  63. int scanlineIntersections(double x[3], int dy[3], double y) const;
  64. int horizontalScanlineIntersections(double x[3], int dy[3], double y) const;
  65. int verticalScanlineIntersections(double y[3], int dx[3], double x) const;
  66. void bound(double &l, double &b, double &r, double &t) const;
  67. void reverse();
  68. void moveStartPoint(Point2 to);
  69. void moveEndPoint(Point2 to);
  70. void splitInThirds(EdgeSegment *&part0, EdgeSegment *&part1, EdgeSegment *&part2) const;
  71. };
  72. /// A quadratic Bezier curve.
  73. class QuadraticSegment : public EdgeSegment {
  74. public:
  75. enum EdgeType {
  76. EDGE_TYPE = 2
  77. };
  78. Point2 p[3];
  79. QuadraticSegment(Point2 p0, Point2 p1, Point2 p2, EdgeColor edgeColor = WHITE);
  80. QuadraticSegment *clone() const;
  81. int type() const;
  82. const Point2 *controlPoints() const;
  83. Point2 point(double param) const;
  84. Vector2 direction(double param) const;
  85. Vector2 directionChange(double param) const;
  86. double length() const;
  87. SignedDistance signedDistance(Point2 origin, double &param) const;
  88. int scanlineIntersections(double x[3], int dy[3], double y) const;
  89. int horizontalScanlineIntersections(double x[3], int dy[3], double y) const;
  90. int verticalScanlineIntersections(double y[3], int dx[3], double x) const;
  91. void bound(double &l, double &b, double &r, double &t) const;
  92. void reverse();
  93. void moveStartPoint(Point2 to);
  94. void moveEndPoint(Point2 to);
  95. void splitInThirds(EdgeSegment *&part0, EdgeSegment *&part1, EdgeSegment *&part2) const;
  96. EdgeSegment *convertToCubic() const;
  97. };
  98. /// A cubic Bezier curve.
  99. class CubicSegment : public EdgeSegment {
  100. public:
  101. enum EdgeType {
  102. EDGE_TYPE = 3
  103. };
  104. Point2 p[4];
  105. CubicSegment(Point2 p0, Point2 p1, Point2 p2, Point2 p3, EdgeColor edgeColor = WHITE);
  106. CubicSegment *clone() const;
  107. int type() const;
  108. const Point2 *controlPoints() const;
  109. Point2 point(double param) const;
  110. Vector2 direction(double param) const;
  111. Vector2 directionChange(double param) const;
  112. SignedDistance signedDistance(Point2 origin, double &param) const;
  113. int scanlineIntersections(double x[3], int dy[3], double y) const;
  114. int horizontalScanlineIntersections(double x[3], int dy[3], double y) const;
  115. int verticalScanlineIntersections(double y[3], int dx[3], double x) const;
  116. void bound(double &l, double &b, double &r, double &t) const;
  117. void reverse();
  118. void moveStartPoint(Point2 to);
  119. void moveEndPoint(Point2 to);
  120. void splitInThirds(EdgeSegment *&part0, EdgeSegment *&part1, EdgeSegment *&part2) const;
  121. };
  122. }