w15 <<
Previous Next >> C_EX
W16
#include <stdio.h>
#include <gd.h>
// Function to draw the mass-spring-damper system
void draw_system(const char* filename) {
int width = 600;
int height = 300;
int x_margin = 50;
int y_margin = 50;
int mass_radius = 20;
int spring_width = 4;
int damper_width = 4;
gdImagePtr img = gdImageCreate(width, height);
int background_color = gdImageColorAllocate(img, 255, 255, 255);
int mass_color = gdImageColorAllocate(img, 0, 0, 0);
int spring_color = gdImageColorAllocate(img, 0, 0, 0);
int damper_color = gdImageColorAllocate(img, 0, 0, 0);
int wall_color = gdImageColorAllocate(img, 0, 0, 0);
// Draw left wall
gdImageLine(img, x_margin, y_margin, x_margin, height - y_margin, wall_color);
// Draw mass 1
int x1 = x_margin + 2 * mass_radius;
int y1 = height / 2;
gdImageFilledEllipse(img, x1, y1, mass_radius, mass_radius, mass_color);
// Draw spring 1
int spring1_start_x = x_margin;
int spring1_end_x = x1 - mass_radius;
int spring1_y = y1;
gdImageLine(img, spring1_start_x, spring1_y, spring1_end_x, spring1_y, spring_color);
gdImageSetThickness(img, spring_width);
gdImageLine(img, spring1_start_x, spring1_y, spring1_end_x, spring1_y, spring_color);
gdImageSetThickness(img, 1);
// Draw damper 1
int damper1_start_x = x_margin / 2;
int damper1_end_x = x1 - mass_radius;
int damper1_y = y1;
gdImageLine(img, damper1_start_x, damper1_y, damper1_end_x, damper1_y, damper_color);
gdImageSetThickness(img, damper_width);
gdImageLine(img, damper1_start_x, damper1_y, damper1_end_x, damper1_y, damper_color);
gdImageSetThickness(img, 1);
// Draw mass 2
int x2 = width - x_margin - 2 * mass_radius;
int y2 = height / 2;
gdImageFilledEllipse(img, x2, y2, mass_radius, mass_radius, mass_color);
// Draw spring 2
int spring2_start_x = x2 + mass_radius;
int spring2_end_x = width - x_margin;
int spring2_y = y2;
gdImageLine(img, spring2_start_x, spring2_y, spring2_end_x, spring2_y, spring_color);
gdImageSetThickness(img, spring_width);
gdImageLine(img, spring2_start_x, spring2_y, spring2_end_x, spring2_y, spring_color);
gdImageSetThickness(img, 1);
// Draw damper 2
int damper2_start_x = width - x_margin + mass_radius;
int damper2_end_x = x2 + mass_radius;
int damper2_y = y2;
gdImageLine(img, damper2_start_x, damper2_y, damper2_end_x, damper2_y, damper_color);
gdImageSetThickness(img, damper_width);
gdImageLine(img, damper2_start_x, damper2_y, damper2_end_x, damper2_y, damper_color);
gdImageSetThickness(img, 1);
// Draw right wall
gdImageLine(img, width - x_margin, y_margin, width - x_margin, height - y_margin, wall_color);
// Save the image to a file
FILE *output_file = fopen(filename, "wb");
gdImagePng(img, output_file);
fclose(output_file);
// Free the memory used by the image
gdImageDestroy(img);
}
int main() {
draw_system("mass_spring_damper_system.png");
return 0;
}
解釋:
1. `#include <stdio.h>`: 引入標準輸入/輸出函式庫。
2. `#include <gd.h>`: 引入gd函式庫,這是一個用於處理圖形數據的函式庫。
3. `void draw_system(const char* filename) {`: 定義了一個名為`draw_system`的函式,用於繪製質點-彈簧-減震器系統。
4. `int width = 600;`, `int height = 300;`: 定義圖像的寬度和高度。
5. `int x_margin = 50;`, `int y_margin = 50;`: 定義圖像邊緣的水平和垂直邊距。
6. `int mass_radius = 20;`, `int spring_width = 4;`, `int damper_width = 4;`: 定義質點、彈簧和減震器的相關尺寸。
7. `gdImagePtr img = gdImageCreate(width, height);`: 創建一個指定寬度和高度的圖像。
8. `int background_color = gdImageColorAllocate(img, 255, 255, 255);`, `int mass_color = gdImageColorAllocate(img, 0, 0, 0);`, `int spring_color = gdImageColorAllocate(img, 0, 0, 0);`, `int damper_color = gdImageColorAllocate(img, 0, 0, 0);`, `int wall_color = gdImageColorAllocate(img, 0, 0, 0);`: 分別為背景、質點、彈簧、減震器和牆分配顏色。
9. `gdImageLine(img, x_margin, y_margin, x_margin, height - y_margin, wall_color);`: 畫左牆,從圖像的左邊緣到底部。
10. `int x1 = x_margin + 2 * mass_radius;`, `int y1 = height / 2;`: 設置質點1的座標。
11. `gdImageFilledEllipse(img, x1, y1, mass_radius, mass_radius, mass_color);`: 在圖像上畫一個填充的橢圓,代表質點1。
12. `int spring1_start_x = x_margin;`, `int spring1_end_x = x1 - mass_radius;`, `int spring1_y = y1;`: 設置彈簧1的起點、終點和y座標。
13. `gdImageLine(img, spring1_start_x, spring1_y, spring1_end_x, spring1_y, spring_color);`: 畫彈簧1。
14. `gdImageSetThickness(img, spring_width);`, `gdImageLine(img, spring1_start_x, spring1_y, spring1_end_x, spring1_y, spring_color);`, `gdImageSetThickness(img, 1);`: 設置彈簧1的寬度,畫彈簧,然後將寬度恢復為1。
15. `int damper1_start_x = x_margin / 2;`, `int damper1_end_x = x1 - mass_radius;`, `int damper1_y = y1;`: 設置減震器1的起點、終點和y座標。
16. `gdImageLine(img, damper1_start_x, damper1_y, damper1_end_x, damper1_y, damper_color);`: 畫減震器1。
17. `gdImageSetThickness(img, damper_width);`, `gdImageLine(img, damper1_start_x, damper1_y, damper1_end_x, damper1_y, damper_color);`, `gdImageSetThickness(img, 1);`: 設置減震器1的寬度,畫減震器,然後將寬度恢復為1。
18. 類似地,繪製了質點2、彈簧2和減震器2的元素,坐標分別為`x2`、`y2`、`spring2_start_x`、`spring2_end_x`
#include <stdio.h>
// System parameters
#define M1 2.0
#define M2 3.0
#define K1 0.5
#define K2 1.0
#define K3 15.0
#define C1 0.25
#define C2 0.33
#define C3 0.5
// Function to calculate the derivative of the state
void calculate_derivative(double t, double state[4], double derivative[4]) {
derivative[0] = state[2]; // dx1/dt = v1
derivative[1] = state[3]; // dx2/dt = v2
double delta_x = state[0] - state[1];
// dv1/dt
derivative[2] = -(K1 * state[0] + K2 * delta_x) / M1;
// dv2/dt
derivative[3] = -(K3 * state[1] - K2 * delta_x) / M2;
}
// Euler's Method for solving the system
void euler_method(double t_initial, double t_final, double dt, double initial_conditions[4]) {
FILE *output_file;
output_file = fopen("trajectory_data.txt", "w");
double t = t_initial;
double state[4];
for (int i = 0; i < 4; ++i) {
state[i] = initial_conditions[i];
}
while (t <= t_final) {
fprintf(output_file, "%f %f %f %f %f\n", t, state[0], state[1], state[2], state[3]);
double derivative[4];
calculate_derivative(t, state, derivative);
for (int i = 0; i < 4; ++i) {
state[i] += derivative[i] * dt;
}
t += dt;
}
fclose(output_file);
}
int main() {
// Define the initial conditions
double initial_conditions[4] = {1.0, -0.5, 0.0, 0.0}; // x1, x2, v1, v2
// Time parameters
double t_initial = 0.0;
double t_final = 10.0;
double dt = 0.01;
// Solve the system using Euler's Method
euler_method(t_initial, t_final, dt, initial_conditions);
return 0;
}
解釋:
1. `#include <stdio.h>`: 引入標準輸入/輸出函式庫。
2. `#define M1 2.0`, `#define M2 3.0`, `#define K1 0.5`, `#define K2 1.0`, `#define K3 15.0`, `#define C1 0.25`, `#define C2 0.33`, `#define C3 0.5`: 定義了系統的一些參數,包括質量(M1、M2)、彈簧常數(K1、K2、K3)和阻尼常數(C1、C2、C3)。
3. `void calculate_derivative(double t, double state[4], double derivative[4]) {`: 定義了一個函式`calculate_derivative`,用於計算狀態的導數。該函式接受時間`t`、當前狀態`state`和計算得到的導數`derivative`。
4. `derivative[0] = state[2];`, `derivative[1] = state[3];`: 賦值給導數,其中`derivative[0]`和`derivative[1]`分別等於速度`v1`和`v2`。
5. `double delta_x = state[0] - state[1];`: 計算兩質點之間的位移。
6. `derivative[2] = -(K1 * state[0] + K2 * delta_x) / M1;`: 計算質點1速度`v1`的導數。
7. `derivative[3] = -(K3 * state[1] - K2 * delta_x) / M2;`: 計算質點2速度`v2`的導數。
8. `void euler_method(double t_initial, double t_final, double dt, double initial_conditions[4]) {`: 定義了一個使用歐拉法求解系統的函式`euler_method`。它接受初始時間、最終時間、時間步長和初始條件。
9. `FILE *output_file;`, `output_file = fopen("trajectory_data.txt", "w");`: 定義了一個文件指針`output_file`,並打開了一個名為"trajectory_data.txt"的文件,用於存儲計算的軌跡數據。
10. `double t = t_initial;`, `double state[4];`: 初始化時間`t`和狀態`state`。
11. `for (int i = 0; i < 4; ++i) { state[i] = initial_conditions[i]; }`: 將初始條件複製到狀態中。
12. `while (t <= t_final) {`: 進入時間迴圈,計算直到達到最終時間。
13. `fprintf(output_file, "%f %f %f %f %f\n", t, state[0], state[1], state[2], state[3]);`: 將當前時間和狀態寫入文件。
14. `calculate_derivative(t, state, derivative);`: 計算當前時間的導數。
15. `for (int i = 0; i < 4; ++i) { state[i] += derivative[i] * dt; }`: 使用歐拉法更新狀態。
16. `t += dt;`: 更新時間。
17. `fclose(output_file);`: 關閉文件。
18. `int main() {`: 定義`main`函式。
19. `double initial_conditions[4] = {1.0, -0.5, 0.0, 0.0};`: 定義初始條件,包括兩個質點的初始位置和速度。
20. `double t_initial = 0.0;`, `double t_final = 10.0;`, `double dt = 0.01;`: 定義時間參數,包括初始時間、最終時間和時間步長。
21. `euler_method(t_initial, t_final, dt, initial_conditions);`: 調用`euler_method`函式求解系統。
22. `return 0;`: 返回0,表示程序運行成功。
w15 <<
Previous Next >> C_EX