「プログラムソース」 11−1、------------------------------------------------------------- #include #include #include typedef struct { double x,y,z; } VECTOR; void vmulti(double, VECTOR *, VECTOR *); double vminus(VECTOR *, VECTOR *, VECTOR *); void vnormalize(VECTOR *); double innerproduct(VECTOR *, VECTOR *); void write_header(FILE *); void scan(FILE *); void back_color(FILE *); void sphere_color(VECTOR *, VECTOR *, double , FILE *); int main(void){ FILE *fp; if((fp = fopen("bunnpuzu.ppm","w")) == NULL) { fprintf(stderr, "%s not open !!\n","bunnpuzu.ppm"); exit(1); } write_header(fp); scan(fp); fclose(fp); return 0; } void write_header(FILE *fp){ fprintf(fp,"P6\n200 200\n255\n"); } void scan(FILE *fp){ double radius,b,c,d,t; double det; VECTOR from,to,vector,point; point.x = 0.0; point.y = 0.0; point.z = 5.0; radius = 1.0; from.z = 0.0; to.x = 0.0; to.y = 0.0; to.z = -1.0; for(from.y = -1.0; from.y < 1.0; from.y += 2.0/200){ for(from.x = -1.0; from.x < 1.0; from.x += 2.0/200){ vminus(&from,&point,&vector); b = innerproduct(&to,&vector); c = innerproduct(&vector,&vector) - radius*radius; d = b * b - c; if(d < 0){ back_color(fp); continue; } det = sqrt(d); t = -b + det; if(t < 0){ back_color(fp); continue; } sphere_color(&point, &from, t, fp); } } } void back_color(FILE *fp){ putc(100,fp); putc(100,fp); putc(100,fp); } void sphere_color(VECTOR *point, VECTOR *to, double t, FILE *fp){ int col; double d; VECTOR v1, v2; VECTOR l = {0.5773, -0.5773, 0.5773}; vmulti(t, to, &v1); vminus(&v1, point, &v2); vnormalize(&v2); d = innerproduct(&l, &v2); col = (int)(255.0*d) + 50; if(col > 255) col = 255; if(col < 0) col = 0; putc((char)col, fp); putc(0, fp); putc(0, fp); } void vmulti(double t, VECTOR *a, VECTOR *b){ b->x = t * a->x; b->y = t * a->y; b->z = t * a->z; } double vminus(VECTOR *a, VECTOR *b, VECTOR *c){ c->x = a->x - b->x; c->y = a->y - b->y; c->z = a->z - b->z; return 0; } void vnormalize(VECTOR *a){ double d; d = sqrt(a->x*a->x + a->y*a->y + a->z*a->z); a->x /= d; a->y /= d; a->z /= d; } double innerproduct(VECTOR *a, VECTOR *b){ return a->x * b->x + a->y * b->y + a->z * b->z; } -------------------------------------------------------------------------------- 「実行結果」 11−1 -------------------------------------------------------------------------- 実行すると、'bunnpuzu.ppm'というファイルが出力され、それを実行することで 輝度値分布図を視覚的に確認できる。 実行する際には、 % cc kidotibunnpuzu.c -lm % ./a.out とすることで、参照できる。 -------------------------------------------------------------------------------- 「考察」 テスト期間中で、あまりに時間がなかったので、ネットを相当参考にして作った。 自分で考えていない部分もあるので、時間があるときにきちんと作りなおしたい。 とりあえず、球が一つある場合での輝度値分布を考えた。 色分けにより、分布図を設計。 オブジェクトは赤い球に設定し、ランバートモデルを利用した。 平行投影として、カメラは固定し、ライトは平行光源一つ、アンビエント一つと し、出力画像のフォーマットはPPMとした。 用いたアルゴリズムは平行投影と呼ばれるもの。 例えばz軸のプラス方向の∞から見ているとすると、視線ベクトルは (0.0, 0.0, -1.0) になることを利用した。 投影するスクリーンの範囲が2*2であるので、(0.0, 0.0, 0.0)上のスクリーンで、 x方向が -1.0 ~ 1.0 y方向が -1.0 ~ 1.0 に設定すればよい。 とりあえず、出来る範囲までやりました。 --------------------------------------------------------------------------------