41223230 cp2023

  • Home
    • SMap
    • reveal
    • blog
  • First
  • w1
  • w2~w3
  • w4~w5
  • w6
  • w7
  • w8~9
  • w10~11
  • w12
  • w13
  • w15
  • W16
  • C_EX
  • CEX_T
  • ANSIC
  • ANSIC_T
  • 期末總結
  • Brython
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

Copyright © All rights reserved | This template is made with by Colorlib