Did you know ... | Search Documentation: |
Pack gpc -- prolog/gpc.pl |
It is an aggregate of zero or more contours, each comprising zero or more vertices. Each vertex has two double-precision ordinates: x and y. Contours can be external, or hole.
Start with an empty polygon. Add contours. Call this the subject polygon. Do the same again with different contours. Call this the clipping polygon. Clip the subject polygon against the other. The result can be a difference, intersection, exclusive-or or union.
In Prolog terms (pardon the pun) it works like this. Use clause
gpc_empty_polygon(Polygon)
to unify Polygon with a new empty GPC polygon. Add an external contour using
gpc_polygon_add_contour(Polygon, external([vertex(0, 0), vertex(1, 1)]))
Ignore the exact vertices; it's just an example. Then add a hole using
gpc_polygon_add_contour(Polygon, hole([vertex(2, 2), vertex(3, 3)]))
Unify the polygon's contours non-deterministically using
gpc_polygon_contour(Polygon, Contour)
Intersect two polygons using
gpc_polygon_clip(int, Subject, Clip, Result)
Where the operation is one of: diff
, int
, xor
, union
.
You can also clip two polygons resulting in a triangle strip. Each strip comprises zero or more vertex lists, each representing a sub-strip of connected triangles. The interface lets you convert polygons to tristrips. You cannot directly create a tristrip.
Tristrips model in Prolog as blobs, just as polygons. You can convert from polygon to tristrip using gpc_polygon_to_tristrip/2, but polygons can clip with a tristrip result directly using
gpc_tristrip_clip(Op, Subject, Clip, Result)
where Result is a tristrip blob rather than a polygon blob. Get the number of tristrip sub-strips using
gpc_tristrip_num_strips(Tristrip, NumStrips)
and you can unify non-deterministically with the sub-strip vertex lists using
gpc_tristrip_vertices(Tristrip, Vertices)
Vertices is a list of vertex(X, Y)
compounds describing a
strip. Supplementary predicates give access to a tristrip's normalised
triangles, their determinants as well as the tristrip's total area.
vertex(X,
Y)
compounds describing either an external contour or a hole.
External contours must wind clockwise.
external
or hole
.
Fails if the polygon has no contours.
external
for exterior vertices,hole
for interior vertices, orbox(MinX,
MinY, MaxX, MaxY)
=.
Makes no assumptions about vertex orientation. The minima is not necessarily the left-most or bottom-most. That depends on the coordinate system.
There is one slight complication: hole serialisation is optional. Defaults to external contour. Applies a definite-clause grammar to the Polygon or the Codes, generating or parsing appropriately. The grammar is flexible enough to transform contours either with or without a hole flag, but always generates a serialisation with the hole flag indicating external contour or hole.
findall(Strip, gpc_tristrip_vertices(Strip), Strips), length(Strips, NumStrips)
Except that it does not enumerate and collate the actual contiguous sub-strips.
vertex(X, Y)
compounds representing a contiguous
strip of triangles. The Tristrip blob comprises multiple
discontiguous triangle strips.Important to note the tristrip's vertex ordering. The first triple in each sub-strip winds 0-1-2 (i.e. first, second, third vertex) but the second winds 1-0-2, i.e. second, first, third vertex; and so on, alternating. The implementation normalises the vertices so that first-second-third ordering correctly unwinds the triangle, as if an independent standalone triangle.
Fails for empty tristrips. Implies zero area.