With this technique, convex polygons with any number of sides can be rendered, with a solid color or a background image as the fill. Click here or the image below to launch the demo.
You can probably figure it out on your own by playing with the checkboxes at the lower left corner of the pop-up, but read on to find out how it all works.
The demo renders only regular polygons, but any convex, irregular, closed area can be rendered.
We start with a list of vertices:
The five vertices of a regular pentagon at an arbitrary orientation
Then we find the bounding rectangle (minimum and maximum x and y coordinates) of the vertices and apply the fill <div> with either a solid color or a background image:
The bounding rectangle is used as the fill
Now the fill rectangle has to be masked to leave behind our filled polygon. Notice that each side of a polygon can be fitted with a right angle triangle:
The right angle triangles and rectangles that act as masks
For vertices that lie on the bounding (or fill) rectangle, the right angle triangles will be flush with the sides of the bounding rectangle (I, II and III above). For vertices that fall inside the bounding rectangle, the right angle triangles (IV and V) will leave behind rectangles (VI). The number of rectangles depends on the number of sides of the polygon and also its orientation.
What we want to do now is to place triangles and rectangles over the numbered areas so that only the actual polygon will remain visible. For rectangular masks, absolutely positioned <div> elements (with the background color) will do the trick, but for triangles we’ll have to think about the rectangles that bound them:
Bounding rectangles for triangular masks
Since we can’t have an infinite supply of right angle triangle images at all sorts of slants, we can simply resize isosceles right angle triangles to get any angle variations we want. We will need at least four different triangles, with their right angles at each corner. The filled parts of the triangles should be of the background color and the rest should be transparent:
Triangular masks for the NW, NE, SE and SW corners, respectively
Since these triangles will be resized, it’s important to make them sufficiently large to minimize aliasing. The images used in the demo are 600 x 600 in dimensions. Once the remaining areas are masked with the triangular masks, all we’re left with is our polygon:
The edges may look jagged a bit, but when the polygon is animated, it’s barely noticeable.
Concave areas can be filled if the angles don’t cause overlapping of the masks. I’ve played around with drawing n-spoked stars instead of convex polygons, but couldn’t perfect the method to entirely avoid overlaps. The technique can also be used for rendering circles, since as the side count grows, polygons eventually start to look like circles.