10
votes

I need to fill an arbitrary polygon using a near-uniform tiling of triangles. How would I do this? You may provide either references to existing algorithms or even simply ideas or hints of your own.

The following is presumed:

  • The polygon may be convex (but bonus points if you come up with an algorithm that works for concave shapes)
  • The polygon has an arbitrary number of edges (3 or more)
  • The amount of tessellation (preferably the number of vertices added by the algorithm) should be parametrized
  • The polygon's edges may be divided by the algorithm
  • Triangles should be nearly uniform in size and shape (i.e. corners will tend towards 60 degrees)
  • Preferably the number edges at a vertex should be few rather than many. This will likely follow from the previous point (I.e. the algorithm should produce a "clean mesh").

This is not an easy problem to solve and I expect that a "heuristic" solution may be the most efficient... (right?)

4
It might help to provide a bit of background on what the actual problem you're trying to solve is. Is this a mesh used in simulation? If so, what simulation method is being used?Victor Liu
Well, it sounded too much of a homework assignment posted verbatim here. It would help if you state that it is, or isn't homework. If it's a question or some sort of challenge. No need to clarify it anymore, from the comment you posted it is clear to me now, but it wasn't when you first posted your, err, challenge/question/whatever.Bart Kiers
Hehe, ok no worries guys :). It's not homework, I'm basically wrapping a shape over a terrain heightmap in a 3d simulation I'm working on. I think it's also a generally useful problem to document and discuss though. I actually didn't want people to read too much into the context because they'd give different answers...Rehno Lindeque

4 Answers

5
votes

Does Triangle do what you want?

(The explanations of the algorithms on that site are better than whatever I could come up with.)

4
votes

Doesn't actually sound that complicated, algorithmically. Or am I missing anything?

Some pseudocode:

  • Place an axis-aligned enclosing square tightly around your polygon.
  • Subdivide each square into four children (quad-tree like), where the number of iterations determines your "amount of tessellation".
  • Each resulting square is either cleanly outside your polygon (=ignore), cleanly inside your polygon (=split into two triangles of resulting tesselation along the diagonal) or intersects your polygon.
  • Exact cases for the intersection squares are left as an exercise to the reader. ;-) [At this point in time, at least.]

It will give you triangles with 45°/45°/90° angles though. If you want as close to 60° as possible, you should start with tessellating the surface of your polygon with hexagons (with the size of the hexagon being your "amount of tessellation") and then checking each of the six 60°/60°/60° triangles that make up these hexagons. For these triangles you do the same as with the squares in the above pseudocode, except for the fact that you don't need to split the ones that cleanly inside your polygon as they are already triangles themselves.

Is this of any help whatsoever? Should work for any polygon (convex/concave/with holes in them), I think, given that what exactly you do for intersecting squares/triangles handles such polygons.

3
votes

As Jason Orendorff pointed out, you should try to use Triangle to generate a quality mesh. It has lots of options that you can play with to try to get an isotropic mesh. Then, you could try to use an iterative algorithm to create a well-centered triangulation. More details are listed on this publications page. I have implemented the 2007 paper "Well-Centered Planar Triangulation -- an Iterative Approach," and it gives decent results on medium sized meshes. A well-centered triangulation is one in which all the circumcenters of triangles lie inside the respective triangle. Since you want something slightly different, you could simply try to change the error metric involved. You could find a measure of "non-congruence" among the triangles and minimize that error. Most likely such an error function will be non-convex, so the non-linear conjugate gradient optimization described is as well as you can do.

1
votes

This can be done for concave/convex polygons using a simple ear-clipping method (assuming we don't need to support holes).

This is 2 steps, so it may be more efficient to iteratively clip the 'best' ear to get more even results, so you don't have to re-arrange topology as a second pass (YMMV).
(Note that the reasons 2 steps are used here is that calculating more even distribution isn't always needed).


Full disclosure, I ran into this problem myself, when I needed a fast tessellator for polygons for a real-time modeling application.

Working implementation written in C,
which take and return POD's (float[2] array, filling in a uint[3] array):

(Note, the ear clipping is based on libgdx with spatial optimizations to the intersection checks, to scale up to thousands of sides without such a significant performance hit, since clipping every ear was checking all-other-points each time).

example output