/* CG の基本プログラム */ #include #include #include #define WIDTH 320 // 画像の横幅 #define HEIGHT 240 // 画像の高さ /* 画像を初期化するための関数 * v:画素値(0 or 1) */ void Clear(int pbm[HEIGHT][WIDTH], int v) { int x, y; for (y = 0; y < HEIGHT; y++) { for (x = 0; x < WIDTH; x++) { pbm[y][x] = v; } } } /* 点を描くための関数 * x, y:点の位置 * v:画素値(0 or 1) */ void DrawPoint(int pbm[HEIGHT][WIDTH], int x, int y, int v) { if (x < 0) return; // はみ出し禁止 if (x >= WIDTH) return; // (セグメントエラー防止) if (y < 0) return; if (y >= HEIGHT) return; pbm[y][x] = v; } /* 直線を描くための関数 * x1, y1:始点 * x2, y2:終点 * v:画素値(0 or 1) */ void DrawLine(int pbm[HEIGHT][WIDTH], int x1, int y1, int x2, int y2, int v) { int x, y; int dx, dy; int i; dx = abs(x2 - x1); // 直線の x 方向の距離 dy = abs(y2 - y1); // 直線の y 方向の距離 if ((dx == 0) && (dy == 0)) { // 始点 == 終点 の場合 DrawPoint(pbm, x1, y1, v); } else if (dx > dy) { // 傾きの小さい直線の場合 for (i = 0; i <= dx; i++) { // x 方向に 1 ずつ進みながら点を描く x = (x1*(dx - i) + x2*i)/dx; y = (y1*(dx - i) + y2*i)/dx; DrawPoint(pbm, x, y, v); } } else { // 傾きの大きい直線の場合 for (i = 0; i <= dy; i++) { // y 方向に 1 ずつ進みながら点を描く x = (x1*(dy - i) + x2*i)/dy; y = (y1*(dy - i) + y2*i)/dy; DrawPoint(pbm, x, y, v); } } } /* 円を描くための関数 * x0, y0:中心点 * r:半径 * v:画素値(0 or 1) */ void DrawCircle(int pbm[HEIGHT][WIDTH], int x0, int y0, int r, int v) { int x1, y1, x2, y2; int a; for (a = 0; a < 360; a += 10) { // 角度を 10 度ずつ変えながら直線を描く x1 = x0 + r*cos (M_PI*a/180.0) + 0.5; // M_PI は円周率 3.1415... y1 = y0 + r*sin (M_PI*a/180.0) + 0.5; // + 0.5 は四捨五入のため x2 = x0 + r*cos (M_PI*(a + 10)/180.0) + 0.5; y2 = y0 + r*sin (M_PI*(a + 10)/180.0) + 0.5; DrawLine(pbm, x1, y1, x2, y2, v); } } /* 画像を出力するための関数 */ void Output(int pbm[HEIGHT][WIDTH]) { int x, y, i; printf("P1\n"); printf("%d %d\n", WIDTH, HEIGHT); i = 0; for (y = 0; y < HEIGHT; y++) { for (x = 0; x < WIDTH; x++) { printf ("%1d", pbm[y][x]); i++; if (i >= 70) { printf("\n"); i = 0; } // 70 個毎に改行 } } } int main() { int pbm[HEIGHT][WIDTH]; Clear(pbm, 0); DrawLine(pbm, 60, 120, 260, 120, 1); // 横線 DrawLine(pbm, 160, 20, 160, 220, 1); // 縦線 DrawCircle(pbm, 110, 70, 40, 1); // 左上の円 DrawCircle(pbm, 210, 170, 40, 1); // 右下の円 Output(pbm); return (EXIT_SUCCESS); }