w13 <<
Previous Next >> W16
w15
課堂考試第一題
#include <stdio.h>
#include <gd.h>
#include <math.h>
void draw_roc_flag(gdImagePtr img);
int main() {
int width = 1200;
int height = (int)(width * 2.0 / 3.0);
gdImagePtr img = gdImageCreateTrueColor(width, height);
gdImageAlphaBlending(img, 0);
draw_roc_flag(img);
FILE *outputFile = fopen("roc_flag_in_gd.png", "wb");
if (outputFile == NULL) {
fprintf(stderr, "Error opening the output file.\n");
return 1;
}
gdImagePngEx(img, outputFile, 9);
fclose(outputFile);
gdImageDestroy(img);
return 0;
}
void draw_roc_flag(gdImagePtr img) {
int width = gdImageSX(img);
int height = gdImageSY(img);
int red, white, blue;
int center_x = (int)(width / 4);
int center_y = (int)(height / 4);
int sun_radius = (int)(width / 8);
int white_circle_dia = sun_radius;
int blue_circle_dia = white_circle_dia + white_circle_dia * 2 / 15;
red = gdImageColorAllocate(img, 255, 0, 0);
white = gdImageColorAllocate(img, 255, 255, 255);
blue = gdImageColorAllocate(img, 0, 0, 149);
gdImageFilledRectangle(img, 0, 0, width, height, red);
gdImageFilledRectangle(img, 0, 0, (int)(width / 2.0), (int)(height / 2.0), blue);
// 利用一個藍色大圓與白色小圓畫出藍色環狀
gdImageFilledEllipse(img, center_x, center_y, blue_circle_dia, blue_circle_dia, blue);
gdImageFilledEllipse(img, center_x, center_y, white_circle_dia, white_circle_dia, white);
// 不含太陽的部分
// 連接第二組ABED的白線
int ax = 429;
int ay = 125;
int bx = 279;
int by = 165;
int ex = 170;
int ey = 274;
int dx = 170;
int dy = 274;
gdImageLine(img, ax, ay, bx, by, white);
gdImageLine(img, bx, by, ex, ey, white);
gdImageLine(img, ex, ey, dx, dy, white);
gdImageLine(img, dx, dy, ax, ay, white);
}
解釋:
1. `#include <stdio.h>`:包含標準輸入/輸出函式庫,提供對標準I/O功能的訪問。
2. `#include <gd.h>`:包含gd函式庫,這是一個用於圖形繪製的函式庫。
3. `#include <math.h>`:包含數學函式庫,這裡主要使用了M_PI,代表圓周率π。
4. `void draw_roc_flag(gdImagePtr img);` 和 `void draw_white_sun(gdImagePtr img, int x, int y, int size, int color);`:函式的聲明。
5. `int main()`:主函式開始。
6. `int width = 1200;` 和 `int height = (int)(width*2.0 / 3.0);`:定義國旗的寬度和高度,根據指定的長寬比例計算。
7. `gdImagePtr img = gdImageCreateTrueColor(width, height);`:使用gdImageCreateTrueColor函式創建了一個真彩色的gdImage對象,代表了指定寬度和高度的圖像。
8. `gdImageAlphaBlending(img, 0);`:設置圖像的Alpha混合模式為關閉。
9. `draw_roc_flag(img);`:調用`draw_roc_flag`函式,將中華民國國旗繪製在圖像上。
10. `FILE *outputFile = fopen("./../images/roc_flag_in_gd.png", "wb");`:打開一個二進制寫入文件,用於保存最終的PNG圖像。
11. `if (outputFile == NULL) { fprintf(stderr, "Error opening the output file.\n"); return 1; }`:錯誤檢查,確保成功打開文件,否則輸出錯誤消息並結束程式。
12. `gdImagePngEx(img, outputFile, 9);`:使用gdImagePngEx函式將圖像寫入已打開的文件,並指定壓縮級別為9。
13. `fclose(outputFile);`:關閉文件。
14. `gdImageDestroy(img);`:釋放由gd函式庫分配的圖像內存。
15. `return 0;`:主函式執行成功,返回0表示程式執行成功。
16. `void draw_roc_flag(gdImagePtr img)`:定義了一個函式,用於在圖像上繪製中華民國國旗。
17. `int width = gdImageSX(img);` 和 `int height = gdImageSY(img);`:獲取圖像的寬度和高度。
18. `int red, white, blue;`:定義紅色、白色和藍色的顏色索引。
19. `int center_x = (int)(width/4);` 和 `int center_y = (int)(height/4);`:計算中心點的座標,使得白日位於青天面積正中央。
20. `int sun_radius = (int)(width/8);`、`int white_circle_dia = sun_radius;` 和 `int blue_circle_dia = white_circle_dia + white_circle_dia*2/15;`:計算中央白日圓形、中央藍色圓形的半徑或直徑。
21. `red = gdImageColorAllocate(img, 255, 0, 0);`、`white = gdImageColorAllocate(img, 255, 255, 255);` 和 `blue = gdImageColorAllocate(img, 0, 0, 149);`:為紅色、白色和藍色分配顏色索引。
22. `gdImageFilledRectangle(img, 0, 0, width, height, red);` 和 `gdImageFilledRectangle(img, 0, 0, (int)(width/2.0), (int)(height/2.0), blue);`:分別使用gdImageFilledRectangle函式填充紅色和藍色的區
上課第二堂求四個焦點
// https://en.wikipedia.org/wiki/Flag_of_the_Republic_of_China
// 內政部國旗參考資料: https://www.moi.gov.tw/cp.aspx?n=10621
// cc roc_flag_in_gd.c -lgd -lm to link with gd and math library
// https://www.rapidtables.com/web/color/RGB_Color.html
// 幾何形狀著色與繪圖練習
// 以下 gd 繪圖程式嘗試畫出 ROC 國旗, 請根據下列程式內容完成後續的國旗繪圖
#include <stdio.h>
#include <gd.h>
#include <math.h>
void draw_roc_flag(gdImagePtr img);
void draw_white_sun(gdImagePtr img, int x, int y, int size, int color);
int main() {
// width 3: height 2
int width = 1200;
// 國旗長寬比為 3:2
int height = (int)(width*2.0 / 3.0);
gdImagePtr img = gdImageCreateTrueColor(width, height);
gdImageAlphaBlending(img, 0);
draw_roc_flag(img);
FILE *outputFile = fopen("roc_flag_in_gd.png", "wb");
if (outputFile == NULL) {
fprintf(stderr, "Error opening the output file.\n");
return 1;
}
gdImagePngEx(img, outputFile, 9);
fclose(outputFile);
gdImageDestroy(img);
return 0;
}
void draw_roc_flag(gdImagePtr img) {
int width = gdImageSX(img);
int height = gdImageSY(img);
int red, white, blue;
// 白日位於青天面積正中央, 因此中心點座標為長寬各 1/4 處
int center_x = (int)(width/4);
int center_y = (int)(height/4);
// gdImageFilledEllipse 需以長寬方向的 diameter 作圖
// 由於中央白日圓形的半徑為青天寬度的 1/8
// 因此中央白日圓形的直徑為青天寬度的 1/4, 也就是國旗寬度的 1/8
// 而且白日十二道光芒的外圍圓形其半徑也是國旗寬度的1/8
int sun_radius = (int)(width/8);
// 中央白日圓形的直徑等於十二道光芒外圍圓形的半徑
int white_circle_dia = sun_radius;
// 中央藍色圓形半徑為中央白日的 1又 2/15
int blue_circle_dia = white_circle_dia + white_circle_dia*2/15;
// 根據 https://www.moi.gov.tw/cp.aspx?n=10621 訂定國旗三種顏色值
red = gdImageColorAllocate(img, 255, 0, 0); // 紅色
white = gdImageColorAllocate(img, 255, 255, 255); // 白色
blue = gdImageColorAllocate(img, 0, 0, 149); // 藍色
// 根據畫布大小塗上紅色長方形區域
gdImageFilledRectangle(img, 0, 0, width, height, red);
// 青天面積為整面國旗的 1/4, 也是採用長方形塗色
gdImageFilledRectangle(img, 0, 0, (int)(width/2.0), (int)(height/2.0), blue);
{int x1 = 429;
int y1 = 125;
int x2 = 279;
int y2 = 165;
// 畫一條線連接兩個點
gdImageLine(img, x1, y1, x2, y2, white);
}
{int x1 = 170;
int y1 = 274;
int x2 = 279;
int y2 = 165;
// 畫一條線連接兩個點
gdImageLine(img, x1, y1, x2, y2, white);
}
{
int x1 = 170;
int y1 = 274;
int x2 = 429;
int y2 = 125;
// 畫一條線連接兩個點
gdImageLine(img, x1, y1, x2, y2, white);
}
// 利用一個藍色大圓與白色小圓畫出藍色環狀
gdImageFilledEllipse(img, center_x, center_y, blue_circle_dia, blue_circle_dia, blue);
gdImageFilledEllipse(img, center_x, center_y, white_circle_dia, white_circle_dia, white);
// 定義座標結構
typedef struct {
double x;
double y;
} Point;
// 計算圓與線的交點
void circleLineIntersection(double h, double k, double r, double x1, double y1, double x2, double y2) {
// 直線斜率
double m = (y2 - y1) / (x2 - x1);
// 直線方程式中的常數項
double b = y1 - m * x1;
// 圓與直線交點的計算
double A = 1 + pow(m, 2);
double B = 2 * (m * b - m * k - h);
double C = pow(k, 2) - pow(r, 2) + pow(h, 2) - 2 * b * k + pow(b, 2);
// 判斷交點個數
double discriminant = pow(B, 2) - 4 * A * C;
if (discriminant > 0) {
double x_intersect1 = (-B + sqrt(discriminant)) / (2 * A);
double y_intersect1 = m * x_intersect1 + b;
printf("交點: (%.2f, %.2f)\n", x_intersect1, y_intersect1);
double x_intersect2 = (-B - sqrt(discriminant)) / (2 * A);
double y_intersect2 = m * x_intersect2 + b;
printf("交點: (%.2f, %.2f)\n", x_intersect2, y_intersect2);
} else if (discriminant == 0) {
double x_intersect = -B / (2 * A);
double y_intersect = m * x_intersect + b;
printf("交點: (%.2f, %.2f)\n", x_intersect, y_intersect);
} else {
printf("No points.\n");
}
}
// 圓的參數
double circle_x = (int)(width/4); // 圓心 x 座標
double circle_y = (int)(height/4); // 圓心 y 座標
double radius = white_circle_dia + white_circle_dia*2/15; // 圓半徑
// 兩點座標
double x3 = 170;
double y3 = 274;
double x4 = 279;
double y4 = 165;
circleLineIntersection(circle_x, circle_y, radius, x4, y4, x3, y3);
double x5 = 279;
double y5 = 165;
double x6 = 429;
double y6 = 125;
circleLineIntersection(circle_x, circle_y, radius, x6, y6, x5, y5);
}
解釋:
1. `#include <stdio.h>`: 引入標準輸入/輸出函式庫。
2. `#include <gd.h>`: 引入gd函式庫,這是一個用於處理圖形數據的函式庫。
3. `#include <math.h>`: 引入math函式庫,這裡主要使用了數學計算相關的函式。
4. `void draw_roc_flag(gdImagePtr img);` 和 `void draw_white_sun(gdImagePtr img, int x, int y, int size, int color);`: 函式聲明。
5. `int main() {`: 主函式開始。
6. `int width = 1200;` 和 `int height = (int)(width*2.0 / 3.0);`: 設置國旗的寬度和高度,符合3:2的寬高比。
7. `gdImagePtr img = gdImageCreateTrueColor(width, height);`: 創建一個指定寬度和高度的真彩色圖像。
8. `gdImageAlphaBlending(img, 0);`: 設置圖像的Alpha混合模式為關閉。
9. `draw_roc_flag(img);`: 調用`draw_roc_flag`函式,將中華民國國旗繪製在圖像上。
10. `FILE *outputFile = fopen("roc_flag_in_gd.png", "wb");`: 打開一個二進制寫入文件,用於保存最終的PNG圖像。
11. `if (outputFile == NULL) { fprintf(stderr, "Error opening the output file.\n"); return 1; }`: 檢查文件是否成功打開,否則輸出錯誤消息並結束程式。
12. `gdImagePngEx(img, outputFile, 9);`: 使用gdImagePngEx函式將圖像寫入已打開的文件,指定壓縮級別為9。
13. `fclose(outputFile);`: 關閉文件。
14. `gdImageDestroy(img);`: 釋放由gd函式庫分配的圖像內存。
15. `return 0;`: 主函式執行成功,返回0表示程式執行成功。
16. `void draw_roc_flag(gdImagePtr img) {`: 定義了一個函式,用於在圖像上繪製中華民國國旗。
17. `int width = gdImageSX(img);` 和 `int height = gdImageSY(img);`: 獲取圖像的寬度和高度。
18. `int red, white, blue;`: 定義紅色、白色和藍色的顏色索引。
19. `int center_x = (int)(width/4);` 和 `int center_y = (int)(height/4);`: 計算中心點的座標,使白日位於青天面積正中央。
20. `int sun_radius = (int)(width/8);`: 計算中央白日圓形的半徑。
21. `int white_circle_dia = sun_radius;` 和 `int blue_circle_dia = white_circle_dia + white_circle_dia*2/15;`: 計算中央白日圓形直徑和中央藍色圓形半徑。
22. `red = gdImageColorAllocate(img, 255, 0, 0);`, `white = gdImageColorAllocate(img, 255, 255, 255);` 和 `blue = gdImageColorAllocate(img, 0, 0, 149);`: 為紅色、白色和藍色分配顏色索引。
23. `gdImageFilledRectangle(img, 0, 0, width, height, red);`: 用紅色填充整個圖像。
24. `gdImageFilledRectangle(img, 0, 0, (int)(width/2.0), (int)(height/2.0), blue);`: 用藍色填充圖像的左上角區域,即青天。
25. `{int x1 = 429; int y1 = 125; int x2 = 279; int y2 = 165; gdImageLine(img, x1, y1, x2, y2, white); }`: 繪製一條連接兩點的白色線。
26. `{int x1 = 170; int y1 = 274; int x2 = 279; int y2 = 165; gdImageLine(img, x1, y1, x2, y2, white); }`: 繪製第二條連
w13 <<
Previous Next >> W16