/src.core/toxi/geom/GridTesselator.java

https://bitbucket.org/postspectacular/toxiclibs/ · Java · 93 lines · 45 code · 11 blank · 37 comment · 8 complexity · 9b9bf3a106fbe57003688ebfd8d1c403 MD5 · raw file

  1. package toxi.geom;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import toxi.geom.mesh2d.DelaunayTriangulation;
  5. import toxi.geom.mesh2d.Voronoi;
  6. import toxi.math.MathUtils;
  7. /**
  8. * This is an implementation of the {@link PolygonTesselator} interface and
  9. * abstract parent class for tesselating 2D polygons using a grid of additional
  10. * points created within the polygon. These inlier points are connected to the
  11. * original polygon vertices using a {@link DelaunayTriangulation}. The quality
  12. * and final amount of triangles used can be adjusted via the number of
  13. * additional grid points. This class currently has two concrete
  14. * implementations: {@link GlobalGridTesselator} and {@link LocalGridTesselator}
  15. * .
  16. */
  17. public abstract class GridTesselator implements PolygonTesselator {
  18. protected float res;
  19. private float rootSize;
  20. /**
  21. * Creates a new instance with the given grid resolution.
  22. *
  23. * @param res
  24. * snap distance for grid points
  25. */
  26. public GridTesselator(float res) {
  27. this(res, Voronoi.DEFAULT_SIZE);
  28. }
  29. /**
  30. * Creates a new instance with the given grid resolution.
  31. *
  32. * @param res
  33. * snap distance for grid points
  34. */
  35. public GridTesselator(float res, float rootSize) {
  36. this.res = res;
  37. this.rootSize = rootSize;
  38. }
  39. protected abstract List<Vec2D> createInsidePoints(Polygon2D poly,
  40. Rect bounds);
  41. public float getResolution() {
  42. return res;
  43. }
  44. public void setResolution(float res) {
  45. this.res = res;
  46. }
  47. /**
  48. * Tesselates/decomposes the given polygon into a list of 2D triangles using
  49. * the currently set grid resolution.
  50. *
  51. * @param poly
  52. * polygon to be tesselated
  53. * @return list of triangles
  54. */
  55. public List<Triangle2D> tesselatePolygon(Polygon2D poly) {
  56. List<Triangle2D> triangles = new ArrayList<Triangle2D>();
  57. Rect bounds = poly.getBounds();
  58. // a Voronoi diagram relies on a Delaunay triangulation behind the
  59. // scenes
  60. Voronoi voronoi = new Voronoi(rootSize);
  61. // add perimeter points
  62. for (Vec2D v : poly.vertices) {
  63. voronoi.addPoint(v);
  64. }
  65. // add random inliers
  66. for (Vec2D v : createInsidePoints(poly, bounds)) {
  67. voronoi.addPoint(v);
  68. }
  69. // get filtered delaunay triangles:
  70. // ignore any triangles which share a vertex with the initial root
  71. // triangle or whose centroid is outside the polygon
  72. for (Triangle2D t : voronoi.getTriangles()) {
  73. if (MathUtils.abs(t.a.x) != Voronoi.DEFAULT_SIZE
  74. && MathUtils.abs(t.a.y) != Voronoi.DEFAULT_SIZE) {
  75. if (poly.containsPoint(t.computeCentroid())) {
  76. triangles.add(t);
  77. }
  78. }
  79. }
  80. return triangles;
  81. }
  82. }