| 特性 | Polygon | Polyline |
| 是否閉合 | 自動連接終點到起點 | 不閉合,端點分離 |
| 填充 | 使用 Brush 填充內部 | 不填充 (僅線條) |
| 邊框 | 使用 Pen 畫邊框 | 使用 Pen 畫線條 |
| 最少點數 | 3 (三角形) | 2 (線段) |
| 參數類型 | array of TPoint | array of TPoint |
完整範例:菱形多邊形 vs 折線
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Canvas.Pen.Width := 2;
Canvas.Pen.Color := clRed;
Canvas.Brush.Color := clYellow;
end;
// 繪製填充多邊形 (菱形)
procedure TForm1.Button1Click(Sender: TObject);
const
Pts: array[0..3] of TPoint = (
(X: 10; Y: 40), // 左
(X: 46; Y: 120), // 下
(X: 82; Y: 40), // 右
(X: 46; Y: 10) // 上
);
begin
Canvas.Polygon(Pts); // 自動閉合:上→左,並用黃色填充
end;
// 繪製開放折線 (相同頂點,平移 82 像素)
procedure TForm1.Button2Click(Sender: TObject);
const
Pts: array[0..3] of TPoint = (
(X: 10+82; Y: 40),
(X: 46+82; Y: 120),
(X: 82+82; Y: 40),
(X: 46+82; Y: 10)
);
begin
Canvas.Polyline(Pts); // 不閉合:上點不連回左點,無填充
end;
end.
視覺效果對比
- Polygon:黃色填充菱形 + 紅色邊框 (四條邊)
- Polyline:紅色三段折線 (左→下→右→上),無填充,首尾不連接
座標陣列構建技巧
靜態常量陣列 (編譯期已知)
const
Triangle: array[0..2] of TPoint = (
(X: 50; Y: 10),
(X: 10; Y: 80),
(X: 90; Y: 80)
);
Canvas.Polygon(Triangle);
動態陣列 (運行時計算)
var
Pts: array of TPoint;
i, N: Integer;
Center: TPoint;
Radius: Integer;
begin
N := 6; // 六邊形
Center := Point(100, 100);
Radius := 50;
SetLength(Pts, N);
for i := 0 to N - 1 do
begin
Pts[i].X := Center.X + Round(Radius * Cos(2 * Pi * i / N));
Pts[i].Y := Center.Y + Round(Radius * Sin(2 * Pi * i / N));
end;
Canvas.Polygon(Pts);
end;
從 TPointF (浮點) 轉換
var
FPts: array of TPointF;
Pts: array of TPoint;
i: Integer;
begin
SetLength(Pts, Length(FPts));
for i := 0 to High(FPts) do
Pts[i] := Point(Round(FPts[i].X), Round(FPts[i].Y));
Canvas.Polyline(Pts);
end;
進階:Polygon 多環 (帶洞多邊形)
// 需使用 WinAPI Polygon + SetPolyFillMode (ALTERNATE/WINDING)
Canvas.Pen.Color := clRed;
Canvas.Brush.Color := clYellow;
SetPolyFillMode(Canvas.Handle, ALTERNATE); // 奇偶規則:重疊區域不填充
// 先畫外環,再畫內環 (洞)
Canvas.Polygon(OuterRing);
Canvas.Polygon(InnerRing); // 內環順序相反 (逆時針)
常見陷阱與避坑
- Polygon 自動閉合:陣列最後一點不需重複第一點,GDI 內部自動連接
- Polyline 不填充:即使 Brush.Style = bsSolid 也不填充,需用 Polygon
- 點數過少:Polygon < 3 點不繪製,Polyline < 2 點不繪製
- 座標超出 Canvas 範圍:GDI 會裁剪,但極大座標可能溢位
- Width > 1 時邊框向內外擴展:psInsideFrame 可控制向內
效能建議
- 批次繪製多個多邊形:合併為單一
PolyPolygon (WinAPI) 調用
- 頂點數極大 (>10000):考慮簡化算法 (Douglas-Peucker) 或分塊繪製
- 動畫逐幀重繪:預計算頂點陣列,幀間僅調用
Polygon/Polyline
Polygon 與 Polyline 是構建複雜 2D 圖形的基石,配合動態頂點生成、畫筆畫刷樣式,能繪製從幾何圖形到地圖邊界、圖表曲線的各類視覺元素。
- 上一篇文章: Delphi 貝塞爾曲線繪製:PolyBezier 與 PolyBezierTo 完整指南
- 下一篇文章: Delphi 獲取 Canvas 對象:TControl.Canvas、GetDC、TCanvas.Create 實戰
Copyright ©
程式碼之家 All Rights Reserved