Contour.cpp 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #include "Contour.h"
  2. #include "arithmetics.hpp"
  3. namespace msdfgen {
  4. static double shoelace(const Point2 &a, const Point2 &b) {
  5. return (b.x-a.x)*(a.y+b.y);
  6. }
  7. void Contour::addEdge(const EdgeHolder &edge) {
  8. edges.push_back(edge);
  9. }
  10. #ifdef MSDFGEN_USE_CPP11
  11. void Contour::addEdge(EdgeHolder &&edge) {
  12. edges.push_back((EdgeHolder &&) edge);
  13. }
  14. #endif
  15. EdgeHolder & Contour::addEdge() {
  16. edges.resize(edges.size()+1);
  17. return edges[edges.size()-1];
  18. }
  19. void Contour::bounds(double &l, double &b, double &r, double &t) const {
  20. for (std::vector<EdgeHolder>::const_iterator edge = edges.begin(); edge != edges.end(); ++edge)
  21. (*edge)->bounds(l, b, r, t);
  22. }
  23. int Contour::winding() const {
  24. if (edges.empty())
  25. return 0;
  26. double total = 0;
  27. if (edges.size() == 1) {
  28. Point2 a = edges[0]->point(0), b = edges[0]->point(1/3.), c = edges[0]->point(2/3.);
  29. total += shoelace(a, b);
  30. total += shoelace(b, c);
  31. total += shoelace(c, a);
  32. } else if (edges.size() == 2) {
  33. Point2 a = edges[0]->point(0), b = edges[0]->point(.5), c = edges[1]->point(0), d = edges[1]->point(.5);
  34. total += shoelace(a, b);
  35. total += shoelace(b, c);
  36. total += shoelace(c, d);
  37. total += shoelace(d, a);
  38. } else {
  39. Point2 prev = edges[edges.size()-1]->point(0);
  40. for (std::vector<EdgeHolder>::const_iterator edge = edges.begin(); edge != edges.end(); ++edge) {
  41. Point2 cur = (*edge)->point(0);
  42. total += shoelace(prev, cur);
  43. prev = cur;
  44. }
  45. }
  46. return sign(total);
  47. }
  48. }