0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

微分の概念を動く接線で体感 y=x^2

Posted at

output.gif

test@test-fujitsu:~/kaihatsu/butsuri$ gcc diff_anim.c -o diff_anim -lSDL2 -lm
test@test-fujitsu:~/kaihatsu/butsuri$ ./diff_anim
diff_anim.c
#include <SDL2/SDL.h>
#include <stdio.h>
#include <math.h>

const int WIDTH = 800;
const int HEIGHT = 600;

// 物理空間の範囲
const float X_MIN = -10.0f;
const float X_MAX = 10.0f;
const float Y_MIN = -5.0f;
const float Y_MAX = 105.0f; // x^2 なので最大100くらい

// 関数と微分
float f(float x) { return x * x; }
float f_prime(float x) { return 2 * x; } // x²の微分後

// 物理座標 → 画面座標変換
int to_screen_x(float x) {
    return (int)((x - X_MIN) / (X_MAX - X_MIN) * WIDTH);
}

int to_screen_y(float y) {
    return (int)(HEIGHT - (y - Y_MIN) / (Y_MAX - Y_MIN) * HEIGHT);
}

int main(int argc, char* argv[]) {
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window* window = SDL_CreateWindow("微分可視化",
                                          SDL_WINDOWPOS_CENTERED,
                                          SDL_WINDOWPOS_CENTERED,
                                          WIDTH, HEIGHT, 0);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

    float x0 = X_MIN;      // 直線の描画開始位置
    float speed = 0.05f;   // 物理空間での移動量

    int running = 1;
    SDL_Event e;

    // 曲線の事前描画用の枠を準備
    SDL_Texture* curve_texture = SDL_CreateTexture(renderer,
                                SDL_PIXELFORMAT_RGBA8888,
                                SDL_TEXTUREACCESS_TARGET,
                                WIDTH, HEIGHT);

    // 描画用前準備
    SDL_SetRenderTarget(renderer, curve_texture);
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); // 背景白設定
    SDL_RenderClear(renderer); // 白で塗り潰す

    // x²の曲線をcurve_textureに描画 毎回書き直さなくて良い用にここに入れておく
    SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); // 青: 曲線 (赤, 緑, 青, 透明度)
    for (float x = X_MIN; x <= X_MAX; x += 0.01f) {
        int sx = to_screen_x(x);
        int sy = to_screen_y(f(x));
        SDL_RenderDrawPoint(renderer, sx, sy);
    }

    SDL_SetRenderTarget(renderer, NULL); // 元のレンダラーに戻す

    while (running) {
        while (SDL_PollEvent(&e)) {
            if (e.type == SDL_QUIT) running = 0;
        }

        SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
        SDL_RenderClear(renderer);

        // curve_textureに描画した曲線を画面上へ描画
        SDL_RenderCopy(renderer, curve_texture, NULL, NULL);

        // 接線描画(点周辺 ±1 の範囲のみ)
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); // 赤: 接線
        float y0 = f(x0);
        float slope = f_prime(x0); // 傾きを計算する
        for (float dx = -1.0f; dx <= 1.0f; dx += 0.01f) { // -1〜1の範囲で点を描画し直線にする
            float x = x0 + dx;
            float y_line = y0 + slope * dx;
            SDL_RenderDrawPoint(renderer, to_screen_x(x), to_screen_y(y_line));
        }

        // 画面に描いたものを実際に表示する
        SDL_RenderPresent(renderer);

        SDL_Delay(16); // 約60FPS
        x0 += speed;
        if (x0 > X_MAX) x0 = X_MIN;
    }

    SDL_DestroyTexture(curve_texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?