Vector Polygons & Path Drawing
While pixel drawing operates on discrete grid points, vector graphics use floating-point coordinates (TFloatPoint or TFixedPoint) for resolution-independent shape rendering. Graphics32 includes a high-performance Vectorial Polygon Rasterizer (VPR) that renders anti-aliased polygons and strokes with sub-pixel precision.
In this tutorial, you will learn how to build polygons, fill shapes with anti-aliasing, stroke paths with custom line thicknesses, and configure line joins and caps.
1. Floating-Point Coordinates and Points
In vector units, points are defined using single-precision floating-point coordinates (TFloatPoint or TPoint2F):
uses
GR32, GR32_VectorUtils;
var
Pt1, Pt2: TFloatPoint;
begin
// Create float point using FloatPoint(X, Y) helper
Pt1 := FloatPoint(100.5, 200.25);
Pt2 := FloatPoint(350.0, 420.75);
end;2. Drawing Anti-Aliased Polygons with VPR
To render smooth, anti-aliased filled polygons, use TPolygon32 or the high-level VPR polygon routines in GR32_Polygons.pas.
uses
GR32, GR32_Polygons, GR32_VectorUtils;
var
Bitmap: TBitmap32;
Points: TArrayOfFloatPoint;
begin
Bitmap := TBitmap32.Create;
try
Bitmap.SetSize(500, 500, False);
Bitmap.Clear(clWhite32);
// Build a star polygon using an array of float points
SetLength(Points, 5);
Points[0] := FloatPoint(250.0, 50.0);
Points[1] := FloatPoint(310.0, 400.0);
Points[2] := FloatPoint(100.0, 150.0);
Points[3] := FloatPoint(400.0, 150.0);
Points[4] := FloatPoint(190.0, 400.0);
// Fill anti-aliased polygon using VPR (Vectorial Polygon Rasterizer)
// PolygonFS performs high-quality sub-pixel anti-aliasing
PolygonFS(Bitmap, Points, clNavy32);
Bitmap.SaveToFile('vpr_star.png');
finally
Bitmap.Free;
end;
end;TIP
The above example draws a 5 point self-intersecting star.
In the GR32_VectorUtils unit you can find a versatile Star function that constructs non-self-intersecting stars with an arbitrary number of points: Star.
3. Stroking Paths with Thick Lines, Joins & Caps
To draw outlines or stroked paths with custom line width, use BuildPolyLine in GR32_VectorUtils.pas to convert line segments into closed thick outline polygons, then rasterize them with PolygonFS.
uses
GR32, GR32_Polygons, GR32_VectorUtils;
var
Bitmap: TBitmap32;
Path: TArrayOfFloatPoint;
StrokePolygon: TArrayOfFloatPoint;
begin
Bitmap := TBitmap32.Create;
try
Bitmap.SetSize(600, 400, False);
Bitmap.Clear(clWhite32);
// Define zig-zag path
SetLength(Path, 4);
Path[0] := FloatPoint(50.0, 300.0);
Path[1] := FloatPoint(200.0, 100.0);
Path[2] := FloatPoint(350.0, 300.0);
Path[3] := FloatPoint(500.0, 100.0);
// Convert path to thick stroke polygon (Line Width = 12.0 pixels)
// Parameters: Path, Closed, StrokeWidth, JoinStyle, CapStyle
StrokePolygon := BuildPolyLine(
Path, // Input contours
False, // Closed path = False
12.0, // Line thickness
jsRound, // Line Join: jsMiter, jsBevel, jsRound, jsSquare
esRound // End Cap: esButt, esSquare, esRound
);
// Fill thick stroke polygon onto bitmap
PolygonFS(Bitmap, StrokePolygon, clDarkRed32);
Bitmap.SaveToFile('thick_stroke.png');
finally
Bitmap.Free;
end;
end;4. Complex Multi-Contour Polygons and Holes
You can define complex shapes with cutouts (holes) by combining multiple closed contours into a TArrayOfArrayOfFloatPoint (poly-polygon) and selecting fill rules (pfEvenOdd vs pfNonZero).
var
OuterRing, InnerHole: TArrayOfFloatPoint;
DonutShape: TArrayOfArrayOfFloatPoint;
begin
// Build outer circle points
OuterRing := Circle(250.0, 250.0, 150.0, 64);
// Build inner hole points (clockwise or counter-clockwise)
InnerHole := Circle(250.0, 250.0, 75.0, 64);
// Combine outer shape and inner cutout
SetLength(DonutShape, 2);
DonutShape[0] := OuterRing;
DonutShape[1] := InnerHole;
// Render donut with hole cut out automatically using Even-Odd fill rule
PolyPolygonFS(Bitmap, DonutShape, clTeal32, pfEvenOdd);
end;Summary
In this tutorial, you learned:
- How to work with sub-pixel float coordinates (
TFloatPoint). - How to fill anti-aliased polygons using
PolygonFSandPolyPolygonFS. - How to stroke paths with line joins (
jsMiter,jsBevel,jsRound,jsSquare) and end caps (esButt,esSquare,esRound). - How to draw donut shapes and complex multi-contour polygons with holes using
pfEvenOdd.
Next, head to Color Gradients & Fill Samplers to discover how to fill polygons with smooth linear and radial color gradients!