在C語言入門教學中,利用迴圈與條件判斷打印幾何圖形是經典練習。其中「桃心(愛心)圖形」因其曲線美感與邏輯挑戰性,深受初學者喜愛。本文詳細解析打印愛心圖形的數學原理、代碼實現與優化技巧。
愛心曲線可用參數方程描述:
x = 16 * sin³(t)
y = 13 * cos(t) - 5 * cos(2t) - 2 * cos(3t) - cos(4t)
其中 t ∈ [0, 2π]。在字符終端中,我們將平面離散為字符網格,對每個坐標點(i, j)判斷是否滿足愛心隱式方程:
(x² + y² - 1)³ - x²y³ ≤ 0
經縮放平移適配終端字符比例(字符寬高比約1:2)後,核心判斷邏輯為:
float x = (j - width/2) * scaleX;
float y = (i - height/2) * scaleY;
if ((x*x + y*y - 1)*(x*x + y*y - 1)*(x*x + y*y - 1) - x*x*y*y*y <= 0)
print("*");
else
print(" ");
#include <stdio.h>
#include <math.h>
int main() {
// 畫布尺寸
const int width = 60;
const int height = 30;
// 縮放因子,調整愛心大小與比例
const float scaleX = 0.05f;
const float scaleY = 0.1f;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
// 將字符坐標映射到數學坐標系
float x = (j - width/2.0f) * scaleX;
float y = (height/2.0f - i) * scaleY; // y軸向上
// 愛心隱式方程判斷
float val = (x*x + y*y - 1);
val = val*val*val - x*x*y*y*y;
if (val <= 0.0f)
printf("*");
else
printf(" ");
}
printf("\n");
}
return 0;
}
#include <stdio.h>
#include <math.h>
#include <windows.h> // Linux請用unistd.h的usleep
// 設置控制台文字顏色 (Windows)
void setColor(int color) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}
// 打印愛心幀
void printHeart(float scale, int color) {
const int width = 60, height = 30;
setColor(color);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
float x = (j - width/2.0f) * scale;
float y = (height/2.0f - i) * scale * 0.5f; // 補償字符長寬比
float val = (x*x + y*y - 1);
val = val*val*val - x*x*y*y*y;
printf(val <= 0 ? "*" : " ");
}
printf("\n");
}
setColor(7); // 恢復默認白色
}
int main() {
// 1. 靜態彩色愛心
printHeart(0.05f, 12); // 亮紅色
// 2. 跳動動畫
printf("\n按任意鍵開始跳動動畫...\n");
getchar();
for (int frame = 0; frame < 20; frame++) {
system("cls"); // Linux用 system("clear")
float scale = 0.04f + 0.01f * sin(frame * 0.5f);
printHeart(scale, 12);
Sleep(200); // Linux用 usleep(200000)
}
return 0;
}
| 問題 | 原因 | 解決方案 |
|---|---|---|
| 愛心顯示扁平/拉長 | 終端字符寬高比非1:1 | y方向縮放係數設為x方向的0.5~0.6倍 |
| 邊緣鋸齒明顯 | 離散採樣精度不足 | 增加畫布尺寸,或使用抗鋸齒字符(如▓▒░) |
| 輸出閃爍 | 頻繁清屏重繪 | 使用雙緩衝/ANSI轉義序列移動光標而非清屏 |
| 中文系統顯示亂碼 | 編碼不匹配 | 源文件保存為UTF-8,終端設置對應代碼頁 |
@%#*+=-:. 形成灰度漸變
掌握愛心打印不僅是迴圈練習,更是理解坐標映射、隱式幾何建模、終端圖形學基礎的絕佳切入點。建議初學者先實現基本版,再嘗試添加顏色、動畫、交互功能,在代碼中感受數學之美。