利用 C# Windows Forms 與 GDI+,結合三角函數參數方程,僅用數十行代碼即可繪製出優雅動態的「飄帶」視覺效果。本文解析數學原理、核心代碼實作與擴展方向,適合圖形學入門與數學可視化教學。
一條寬 600×高 350 的視窗,背景愛麗絲藍,前景金色,繪製出宛如飄帶般的正弦/餘弦疊加曲線,視窗縮放自動重繪。
using System;
using System.Drawing;
using System.Windows.Forms;
public class DrawStreamerForm : Form
{
public DrawStreamerForm()
{
Text = "飄帶圖案 - 數學曲線可視化";
BackColor = Color.AliceBlue;
ForeColor = Color.Gold;
ResizeRedraw = true; // 縮放時自動觸發 OnPaint
ClientSize = new Size(600, 350);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
using (Pen pen = new Pen(ForeColor, 2))
{
// 圓心座標:視窗置中下方
float cx = ClientSize.Width / 2f;
float cy = ClientSize.Height;
// 參數方程繪製飄帶:水平線段疊加
for (double a = 0; a <= Math.PI; a += Math.PI / 380)
{
float x1 = (float)(280 * Math.Cos(1.6 * a) + cx);
float y1 = (float)(479 - (90 * Math.Sin(8 * a) * Math.Cos(a / 2.5) + cy));
float x2 = (float)(280 * Math.Cos(1.8 * a) + cx);
g.DrawLine(pen, x1, y1, x2, y1); // 水平線段
}
}
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new DrawStreamerForm());
}
}
// 參數 a ∈ [0, π],步長 π/380 → 380 段線段
x1 = 280 * cos(1.6a) + cx // 左端點 X
x2 = 280 * cos(1.8a) + cx // 右端點 X (頻率略高產生寬度變化)
y = 479 - (90 * sin(8a) * cos(a/2.5) + cy) // 共用 Y 座標
cos(1.6a)、cos(1.8a) 產生左右邊界的緩慢振盪sin(8a) 產生 8 個週期的快速起伏cos(a/2.5) 使波紋幅度從中間向兩端漸變479 - (… + cy) 將數學座標系 (Y 向上) 轉螢幕座標系 (Y 向下)每次迴圈畫一條水平線段 (x1, y) → (x2, y)。380 條線段疊加,形成視覺上連續、寬度變化、波紋豐富的飄帶狀圖形。
| 技術 | 用法 | 說明 |
|---|---|---|
| ResizeRedraw | true | 視窗大小改變自動 Invalidate → 觸發 OnPaint |
| using Pen | using 區塊 | 確保非託管 GDI 資源及時釋放 |
| e.Graphics | PaintEventArgs | 雙緩衝繪圖表面,無閃爍 |
| ClientSize | 屬性 | 取得繪圖區實際大小,排除標題列/邊框 |
private double _phase = 0;
private Timer _timer = new Timer { Interval = 16 }; // ~60 FPS
public DrawStreamerForm()
{
// ... 原有初始化
_timer.Tick += (s, e) => { _phase += 0.05; Invalidate(); };
_timer.Start();
}
protected override void OnPaint(PaintEventArgs e)
{
// ... 在公式中加入 _phase
float x1 = (float)(280 * Math.Cos(1.6 * a + _phase) + cx);
float y1 = (float)(479 - (90 * Math.Sin(8 * a + _phase) * Math.Cos(a / 2.5) + cy));
// ...
}
TrackBar 綁定 1.6、1.8、8、2.5 等參數Invalidate() 觀察參數對形狀影響
private Bitmap _buffer;
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
_buffer?.Dispose();
_buffer = new Bitmap(ClientSize.Width, ClientSize.Height);
}
protected override void OnPaint(PaintEventArgs e)
{
using (Graphics g = Graphics.FromImage(_buffer))
{
// 繪圖邏輯同前
}
e.Graphics.DrawImageUnscaled(_buffer, 0, 0);
}
PathGeometry + RenderTransform 實現 3D 飄帶動畫| 現象 | 原因 | 修正 |
|---|---|---|
| 曲線不連續/有鋸齒 | 步長過大 (π/380 太粗) | 減小步長至 π/1000 或使用 DrawCurve |
| 視窗縮放圖形變形 | 座標硬編碼未隨 ClientSize 縮放 | 所有座標乘以 scale = min(Width/600, Height/350) |
| 閃爍嚴重 | 未啟用雙緩衝 | SetStyle(ControlStyles.OptimizedDoubleBuffer, true) |
結語:數學之美,代碼即畫筆。這個飄帶範例展示了參數方程 + GDI+ 即時繪製的強大表現力。從靜態曲線到動態動畫,從 2D 到 3D,核心思維不變:將數學語言翻譯為視覺語言。下次想展示數學之美時,不妨打開 Visual Studio,讓曲線在螢幕上舞動。