edge-segments.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #pragma once
  2. #include "Vector2.h"
  3. #include "SignedDistance.h"
  4. #include "EdgeColor.h"
  5. namespace msdfgen {
  6. // Parameters for iterative search of closest point on a cubic Bezier curve. Increase for higher precision.
  7. #define MSDFGEN_CUBIC_SEARCH_STARTS 4
  8. #define MSDFGEN_CUBIC_SEARCH_STEPS 4
  9. // Threshold of the dot product of adjacent edge directions to be considered convergent.
  10. #define MSDFGEN_CORNER_DOT_EPSILON 0.000001
  11. /// An abstract edge segment.
  12. class EdgeSegment {
  13. public:
  14. EdgeColor color;
  15. EdgeSegment(EdgeColor edgeColor = WHITE) : color(edgeColor) { }
  16. virtual ~EdgeSegment() { }
  17. /// Creates a copy of the edge segment.
  18. virtual EdgeSegment * clone() const = 0;
  19. /// Returns the point on the edge specified by the parameter (between 0 and 1).
  20. virtual Point2 point(double param) const = 0;
  21. /// Returns the direction the edge has at the point specified by the parameter.
  22. virtual Vector2 direction(double param) const = 0;
  23. /// Returns the change of direction (second derivative) at the point specified by the parameter.
  24. virtual Vector2 directionChange(double param) const = 0;
  25. /// Returns the direction tendency vector that can resolve cases where directions converge at a corner.
  26. virtual Vector2 directionTendency(double param, int polarity) const;
  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 pseudo-distance.
  30. virtual void distanceToPseudoDistance(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. /// Adjusts the bounding box to fit the edge segment.
  34. virtual void bound(double &l, double &b, double &r, double &t) const = 0;
  35. /// Moves the start point of the edge segment.
  36. virtual void moveStartPoint(Point2 to) = 0;
  37. /// Moves the end point of the edge segment.
  38. virtual void moveEndPoint(Point2 to) = 0;
  39. /// Splits the edge segments into thirds which together represent the original edge.
  40. virtual void splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const = 0;
  41. /// Converts convergent segment to a divergent segment. If NULL is returned, the object is already divergent and has been updated.
  42. virtual EdgeSegment * makeDivergent(int dStart, int dEnd) = 0;
  43. };
  44. /// A line segment.
  45. class LinearSegment : public EdgeSegment {
  46. public:
  47. Point2 p[2];
  48. LinearSegment(Point2 p0, Point2 p1, EdgeColor edgeColor = WHITE);
  49. LinearSegment * clone() const;
  50. Point2 point(double param) const;
  51. Vector2 direction(double param) const;
  52. Vector2 directionChange(double param) const;
  53. SignedDistance signedDistance(Point2 origin, double &param) const;
  54. int scanlineIntersections(double x[3], int dy[3], double y) const;
  55. void bound(double &l, double &b, double &r, double &t) const;
  56. void moveStartPoint(Point2 to);
  57. void moveEndPoint(Point2 to);
  58. void splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const;
  59. EdgeSegment * makeDivergent(int dStart, int dEnd);
  60. };
  61. /// A quadratic Bezier curve.
  62. class QuadraticSegment : public EdgeSegment {
  63. public:
  64. Point2 p[3];
  65. QuadraticSegment(Point2 p0, Point2 p1, Point2 p2, EdgeColor edgeColor = WHITE);
  66. QuadraticSegment * clone() const;
  67. Point2 point(double param) const;
  68. Vector2 direction(double param) const;
  69. Vector2 directionChange(double param) const;
  70. SignedDistance signedDistance(Point2 origin, double &param) const;
  71. int scanlineIntersections(double x[3], int dy[3], double y) const;
  72. void bound(double &l, double &b, double &r, double &t) const;
  73. void moveStartPoint(Point2 to);
  74. void moveEndPoint(Point2 to);
  75. void splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const;
  76. EdgeSegment * makeDivergent(int dStart, int dEnd);
  77. };
  78. /// A cubic Bezier curve.
  79. class CubicSegment : public EdgeSegment {
  80. public:
  81. Point2 p[4];
  82. CubicSegment(Point2 p0, Point2 p1, Point2 p2, Point2 p3, EdgeColor edgeColor = WHITE);
  83. CubicSegment * clone() const;
  84. Point2 point(double param) const;
  85. Vector2 direction(double param) const;
  86. Vector2 directionChange(double param) const;
  87. SignedDistance signedDistance(Point2 origin, double &param) const;
  88. int scanlineIntersections(double x[3], int dy[3], double y) const;
  89. void bound(double &l, double &b, double &r, double &t) const;
  90. void moveStartPoint(Point2 to);
  91. void moveEndPoint(Point2 to);
  92. void splitInThirds(EdgeSegment *&part1, EdgeSegment *&part2, EdgeSegment *&part3) const;
  93. EdgeSegment * makeDivergent(int dStart, int dEnd);
  94. };
  95. template <class BaseSegment>
  96. class DivergentEdgeSegment : public BaseSegment {
  97. public:
  98. int dStart, dEnd;
  99. explicit DivergentEdgeSegment(const BaseSegment &base, int dStart, int dEnd);
  100. SignedDistance signedDistance(Point2 origin, double &param) const;
  101. void distanceToPseudoDistance(SignedDistance &distance, Point2 origin, double param) const;
  102. EdgeSegment * makeDivergent(int dStart, int dEnd);
  103. };
  104. }