エルミート曲線の描写

C を覚えたての2003年頃に書いたエルミート曲線の描写プログラムです。グラフィックライブラリの使い方も知らなかった為、モノクロビットマップ画像を直に書いています。( 実行には 256×256 の 256 色ビットマップ画像を head.dat という名前で同一ディレクトリに配置しておく必要があります。 )

////////////////////////////////////////////////
//  エルミート曲線描写テスト
////////////////////////////////////////////////
 
#define BG_COLOR 0xFF           //初期化カラー
#define GL_COLOR 0xD0           //グリッドカラー
#define GL_SCALE 20             //グリッド幅px
#define VC_COLOR 0x80           //ベクトルカラー
#define LN_ACRCY 0.001          //曲線描写精度
#define BITMAP_X 256            //画像横px
#define BITMAP_Y 256            //画像縦px
#define IMAGE_FILE "data.bmp"   //出力画像ファイル名
 
#define HEADER_SIZE 0x435       //Bitmapファイルヘッダサイズ
 
#define X 0
#define Y 1
 
#include<stdio.h>
#include<stdlib.h>
 
void main(void)
{
    FILE *fp,*fread;
    int x,y,i,j,k;
    int vram[256][256],vramt[256][256];
 
    for(y=0;y<BITMAP_Y;y++)      //イメージバッファを念のため初期化
        for(x=0;x<BITMAP_X;x++)
            vram[x][y]=BG_COLOR;
 
////////////////////////////////////////////////
//グリッド描写
 
    for(i=0;i<256;i+=GL_SCALE)   //縦線
    {
        for(j=0;j<256;j++)
            vram[i][j]=GL_COLOR;
    }
    for(i=0;i<256;i+=GL_SCALE)   //横線
    {
        for(j=0;j<256;j++)
            vram[j][i]=GL_COLOR;
    }
 
 
////////////////////////////////////////////////
//メイン描写
 
    float t,fx,fy;
    int v[2][2],p[2][2];
 
    p[0][X]=3;
    p[0][Y]=4;
 
    v[0][X]=6;
    v[0][Y]=-3;
 
    p[1][X]=10;
    p[1][Y]=10;
 
    v[1][X]=-8;
    v[1][Y]=1;
 
    for(t=0;t<1.0;t+=LN_ACRCY)   //エルミート曲線描写
    {
        fx=p[0][X]*((2*t+1)*((1-t)*(1-t)))+v[0][X]*(t*((1-t)*(1-t)))+v[1][X]*((-t)*(-t)*(1-t))+p[1][X]*(t*t*(3-2*t));
        fy=p[0][Y]*((2*t+1)*((1-t)*(1-t)))+v[0][Y]*(t*((1-t)*(1-t)))+v[1][Y]*((-t)*(-t)*(1-t))+p[1][Y]*(t*t*(3-2*t));
        fx=fx*GL_SCALE;
        fy=fy*GL_SCALE;
        x=fx;
        y=fy;
        vram[x][y]=0x00;
        if(LN_ACRCY>=0.01)   //描写精度が低ければ座標を表示。
            printf("%5.5f\t%5.5f\t%d\t%d\n",fx,fy,x,y);
    }
 
//ベクトル(ハンドル?)描写
    for(k=0;k<2;k++)
    {
        p[k][X]=GL_SCALE*p[k][X];
        p[k][Y]=GL_SCALE*p[k][Y];
        v[k][X]=p[k][X]+GL_SCALE*v[k][X];
        v[k][Y]=p[k][Y]+GL_SCALE*v[k][Y];
        if(p[k][X]>v[k][X])
        {
            i=v[k][X];
            j=p[k][X];
        }
        else
        {
            i=p[k][X];
            j=v[k][X];
        }
        for(x=i;x<j;x++)
        {
            y=x*(p[k][Y]-v[k][Y])/(p[k][X]-v[k][X])+p[k][Y]-p[k][X]*(p[k][Y]-v[k][Y])/(p[k][X]-v[k][X]);
            if(x>=0&&x<256&&y>=0&&y<256)
                vram[x][y]=VC_COLOR;
        }
        vram[v[k][X]][v[k][Y]]=0xFF;
        vram[v[k][X]][v[k][Y]+1]=0x00;
        vram[v[k][X]][v[k][Y]-1]=0x00;
        vram[v[k][X]+1][v[k][Y]]=0x00;
        vram[v[k][X]+1][v[k][Y]+1]=0x00;
        vram[v[k][X]+1][v[k][Y]-1]=0x00;
        vram[v[k][X]-1][v[k][Y]]=0x00;
        vram[v[k][X]-1][v[k][Y]+1]=0x00;
        vram[v[k][X]-1][v[k][Y]-1]=0x00;
    }
 
////////////////////////////////////////////////
//Y軸座標の問題解決(天地入れ替え)
 
    for(i=0;i<256;i++)
    {
        for(j=0;j<256;j++)
        {
        vramt[i][j]=vram[i][255-j];
        }
    }
 
    for(i=0;i<256;i++)
    {
        for(j=0;j<256;j++)
        {
        vram[i][j]=vramt[i][j];
        }
    }
 
////////////////////////////////////////////////
 
    for(y=0;y<BITMAP_Y;y++)      //カラーデータを念のため校正(0x00~0xFF)
    {
        for(x=0;x<BITMAP_X;x++)
        {
            if(vram[x][y]>0xFF)
                vram[x][y]=0xFF;
            if(vram[x][y]<0x00)
                vram[x][y]=0x00;
        }
    }
 
////////////////////////////////////////////////
 
//書込ビットマップファイルをバイナリモードでオープン。
    if( (fp=fopen(IMAGE_FILE,"wb"))==NULL){
        printf("Image File Open Error.\n");
        exit( EXIT_FAILURE );}
 
//ヘッダファイル読み込み
    if((fread=fopen("head.dat","rb"))==NULL){
        printf("Header File Open Error.\n");
        exit( EXIT_FAILURE );}
 
//ヘッダーファイルからヘッダーを読み取り出力。
    rewind(fread);
    rewind(fp);
    for(i=0;i<HEADER_SIZE;i++)
        putc(getc(fread),fp);
 
//ドット描写
    for(x=BITMAP_X;x>0;x--)
        for(y=0;y<BITMAP_Y;y++)
            fprintf(fp,"%c",vram[y][x]);
 
    for(y=0;y<2;y++)             //最後(必要?)
        fprintf(fp,"%x",0);
    fclose(fp);
    printf("ビットマップ画像を出力しました。\n");
    exit( EXIT_SUCCESS );
////////////////////////////////////////////////
 }

無駄が多いし、汚いプログラムですね…。
実行すると、以下のようなビットマップ画像が出力されます。

投稿者:

dyama

佐世保のシステムエンジニアです。詳しいプロフィールやこのブログについてはこちらをご覧ください。

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください