メインコンテンツへスキップ
見出し画像
Photo bytomomimau

A#02 フラクタル図形

    こちらも以前に作成したもの。ライフゲームに似たやつ。

    基本情報技術者試験…!

    IT、プログラミング等を自習した記念に、FE試験を受験しようと思っていました。R2年度春はコロナの影響で中止になってしまい、そのままに。。
    久しく調べてみると、現在はCBT形式で月1くらいで受けれるようになってた!またやるか。

    勉強していた当時、午後のC言語対策に下の本勉強している中で平成28年度春の問題でフラクタル図形を描く問題があったので、写経・編集しつつ、動かしてみました。

    フラクタルを描画するプログラム

    プログラム内で単位図形となる部分を与えています。 フラクタルを生成する深さd(回数)は画面から入力して、深さ毎の datファイル を出力。 0は黒、1は白として Gnuplotで描画して、gifファイル を作成。

    出力例(d=6)

    画像
    例1 単位図形 = { { 1, 1 },
             { 1, 0 }, };
    画像
    例2 単位図形 = { { 1, 1, 1 },
             { 1, 0, 1 },
                { 1, 1, 1 }, };
    画像
    例3 単位図形 = { { 1, 1, 1 },
             { 0, 1, 0 },
                { 0, 1, 0 }, };

    ソースコード

    c

    #include <stdio.h>
    #include <stdlib.h>
    
    /* 単位図形,例1の場合 */
    int pat[2][2] = {
        { 1, 1 },
        { 1, 0 },      
    };  
    
    /*2D配列のサイズ / 2D配列の行[0]のサイズ(列数) = 与えた行列の行数 */
    int p_rn = sizeof pat / sizeof pat[0]; 
    /* 2D配列の行[0]のサイズ / 2D配列の要素[0][0]のサイズ = 与えた行列の列数 */
    int p_cn = sizeof pat[0] / sizeof pat[0][0];
    
    
    /* プロトタイプ宣言*/
    int exists_at(int, int, int);  
    
    int main(void) {
    int i, j, k, rn, cn, d; 
    char filename[256];   
    FILE *fp;
    
    /* フラクタル作成ループ*/
    printf("Fractalの生成回数(d)を入力.\n");
    scanf("%d", &d);         
    rn = cn = 1; 
        for (k = 0; k < d; k++) {
            sprintf(filename, "frac%d.dat", k);
            fp = fopen(filename, "w");
                if (fp == NULL) {
                    printf("ファイルをオープンできません.\n");
                    exit(1);
                }       
            rn *= p_rn;
            cn *= p_cn;
            for (i = 0; i < rn; i++) {
                for (j = 0; j < cn; j++) {
                    fprintf(fp, exists_at(i, j, d) ? "0 " : "1 ");
                        /* cmd画面確認用:putchar(exists_at(i, j, d) ? '*': ' '); */                 
                }
                fprintf(fp, "\n");
            }
            fprintf(fp, "\n");          
        }
    fclose(fp);
    return 0;
    }
    
    int exists_at(int i, int j, int d) {
        if (d == 0) { 
            return 1;
        } else if (exists_at(i / p_rn, j / p_cn, d - 1) == 0) {
            return 0;
        } else {
            return pat[i % p_rn][j % p_cn];
        }
    }

    gnuplot

    cd '「.datが入っているディレクトリのパス」'
    d = 7
    set term gif size 400, 400
    
    set size square
    set nozeroaxis
    unset colorbox
    set palette grey                     #gray0 = 黒
    set title font "Arial,20"
    set key center below 
    
    do for [i=0:d-1] {
       set output sprintf("frac%d.gif", i)
       set notics   
       data = sprintf("frac%d.dat", i)
       plot data matrix with image title sprintf("Fractal %d", i)
    }
    
    set output


    当時のメモも残っていました。

    • できなかったこと

    ・単位図形の部分を画面から入力、単位図形のサイズも自由に。
    ・コンパイルから描画までを走らせるバッチファイルを作成。深さdはコマンドプロンプト上でcからgnuplotに渡す。

    • わからなかったこと

    ・入力値を配列に格納する場合の配列の動的確保がいまいちわからない。
    ・サイズが変わるマトリックスのGnuplotでの描画がうまくいかない。
    ・コマンドプロンプト上の変数の受け渡しがわからない。

    発展

    これもこれも同じ原理…? 美しすぎる。。

     
     
    2026/8~世界周遊中|理系大学院卒 男 会社員|技術士(建設・河川)|防災士|G検定|世界遺産検定2級|読書、旅行、土木・河川、解析、AIなど|2016年~ブクログ(https://booklog.jp/users/shino424)

    あなたへのおすすめ