| 函數 | 繪製內容 | 填充 | 邊框 | 參數用途 |
| Ellipse | 完整橢圓/圓 | Brush | Pen | 僅外接矩形 |
| Pie | 扇形 (兩條半徑+弧) | Brush | Pen | 矩形+起止射線 |
| Chord | 弓形 (弦+弧) | Brush | Pen | 矩形+起止射線 |
| Arc | 僅弧線 | 無 | Pen | 矩形+起止射線 |
完整範例:五個按鈕對應五種繪製
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton; // Ellipse
Button2: TButton; // Ellipse (TRect)
Button3: TButton; // Pie
Button4: TButton; // Chord
Button5: TButton; // Arc
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var
Btn: TButton;
const
Y1 = 10;
Y2 = 80;
procedure TForm1.FormCreate(Sender: TObject);
begin
Canvas.Pen.Width := 2;
Canvas.Pen.Color := clRed;
Canvas.Brush.Color := clWhite;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Btn := TButton(Sender);
Canvas.Ellipse(Btn.Left, Y1, Btn.Left + Btn.Width, Y2);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
R: TRect;
begin
Btn := TButton(Sender);
R := Rect(Btn.Left, Y1, Btn.Left + Btn.Width, Y2);
Canvas.Ellipse(R);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Btn := TButton(Sender);
Canvas.Pie(
Btn.Left, Y1, // 矩形左上
Btn.Left + Btn.Width, Y2, // 矩形右下
Btn.Left + Btn.Width, Y1 + (Y2-Y1) div 2, // 起點:右中
Btn.Left + Btn.Width div 2, Y1 // 終點:上中
);
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
Btn := TButton(Sender);
Canvas.Chord(
Btn.Left, Y1,
Btn.Left + Btn.Width, Y2,
Btn.Left + Btn.Width, Y1 + (Y2-Y1) div 2,
Btn.Left + Btn.Width div 2, Y1
);
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
Btn := TButton(Sender);
Canvas.Arc(
Btn.Left, Y1,
Btn.Left + Btn.Width, Y2,
Btn.Left + Btn.Width, Y1 + (Y2-Y1) div 2,
Btn.Left + Btn.Width div 2, Y1
);
end;
end.
起止點幾何計算詳解
起止點 不是 矩形邊界上的點,而是 從矩形中心發出的射線與橢圓邊界的交點:
// 幾何關係
Center := Point((Left+Right)/2, (Top+Bottom)/2);
RayStart := Center + VectorTo(StartPoint); // 射線方向
Intersection := EllipseIntersect(Center, RayStart); // 實際弧起點
範例參數幾何解讀
- 矩形:按鈕區域 (寬度 = 按鈕寬,高度 = 70)
- 起點:
(Right, Top + Height/2) → 矩形右側中點 → 射線水平向右 → 交點為橢圓最右端 (0°)
- 終點:
(Left + Width/2, Top) → 矩形上側中點 → 射線垂直向上 → 交點為橢圓最上端 (90°)
- 結果:從 0° 逆時針繪製到 90° (右上象限)
視覺效果對比 (同參數下)
- Ellipse:完整白色填充橢圓 + 紅邊
- Pie:右上象限扇形填白 + 紅邊 (含兩條半徑邊)
- Chord:右上象限弓形填白 + 紅邊 (含一條弦邊,無半徑)
- Arc:右上象限紅色弧線 (無填充,無半徑/弦)
常見陷阱與避坑
- 起止點座標非邊界點:傳入矩形邊界外的點也可,GDI 計算射線方向
- Arc 無填充:Brush 設定無效,僅 Pen 生效
- 方向固定逆時針:從起點射線到終點射線逆時針方向
- 矩形寬高相等 = 圓:Ellipse 變圓,Pie/Chord/Arc 同理
- 高 DPI 座標縮放:所有座標為邏輯像素,需配合縮放
進階:計算任意角度的起止點
function EllipsePoint(const Rect: TRect; AngleDeg: Double): TPoint;
var
Cx, Cy, Rx, Ry: Double;
Rad: Double;
begin
Cx := (Rect.Left + Rect.Right) / 2;
Cy := (Rect.Top + Rect.Bottom) / 2;
Rx := (Rect.Right - Rect.Left) / 2;
Ry := (Rect.Bottom - Rect.Top) / 2;
Rad := DegToRad(AngleDeg);
Result.X := Round(Cx + Rx * Cos(Rad));
Result.Y := Round(Cy - Ry * Sin(Rad)); // Y 軸向下
end;
// 使用:從 45° 到 135°
Canvas.Pie(Rect, EllipsePoint(Rect, 45), EllipsePoint(Rect, 135));
徹底理解橢圓族函數的「外接矩形 + 射線起止點」參數模式,能精確繪製儀表盤、進度環、扇形統計圖等各類圓弧視覺元素。
- 上一篇文章: Delphi 獲取 Canvas 對象:TControl.Canvas、GetDC、TCanvas.Create 實戰
- 下一篇文章: Delphi 矩形類圖形繪製:Rectangle、RoundRect、DrawFocusRect、FrameRect 完整指南
Copyright ©
程式碼之家 All Rights Reserved