「画面」にdrawLine(x1, y1, x2, y2)して、pgm画像ファイルとして出力する C のソースコードを5分で書けるか?

頭の体操、ということで、試してみた。これくらい5分で書けなきゃ駄目だろ。

  • 「drawLine.exe [x1] [y1] [x2] [y2]」で起動、(x1, y1) - (x2, y2) の線を仮想画面に描く。
  • 画面サイズは決め打ち(320x240)で、pgmファイル(グレースケール255階調)を出力。
  • 座標系は左上が(0,0)原点。右下が(319, 239)。
#include <stdio.h>
#define SCR_WIDTH  (320)
#define SCR_HEIGHT (240)
unsigned char b[SCR_WIDTH * SCR_HEIGHT];
int drawLine(int x1, int y1, int x2, int y2, unsigned char color, unsigned char * b)
{
  int i = 0, j = 0;
  int xdiff, ydiff;
  double rate;
  xdiff = x2 - x1;
  ydiff = y2 - y1;
  if (xdiff == 0 && ydiff == 0) {
    b[x1 + SCR_WIDTH * y1] = color;
    return 0;
  }
  if (xdiff < 0) xdiff = -xdiff;
  if (ydiff < 0) ydiff = -ydiff;
  if (xdiff > ydiff) {
	int startx = x1;
	int starty = y1;
	if (x1 < x2) {
	  rate = (y2 - y1) / (double)xdiff;
	} else {
	  startx = x2;
	  starty = y2;
	  rate = (y1 - y2) / (double)xdiff;
	}
	/* xを変化させて線を描く */
	for (i = 0; i <= xdiff; i++) {
	  j = i * rate + starty;
	  b[startx + i + SCR_WIDTH * j] = color;
	}
  } else {
	int startx = x1;
	int starty = y1;
	if (y1 < y2) {
	  rate = (x2 - x1) / (double)ydiff;
	} else {
	  startx = x2;
	  starty = y2;
	  rate = (x1 - x2) / (double)ydiff;
	}
	/* yを変化させて線を描く */
	for (i = 0; i <= ydiff; i++) {
	  j = i * rate + startx;
	  b[j + SCR_WIDTH * (starty + i)] = color;
	}
  }
  return 0;
}
int main(int ac, char ** av)
{
  FILE * out = fopen("foo.pgm", "w");
  int x1, y1, x2, y2;
  x1 = atoi(av[1]);
  y1 = atoi(av[2]);
  x2 = atoi(av[3]);
  y2 = atoi(av[4]);
  
  fprintf(out, "P5\n%d %d\n255\n", SCR_WIDTH, SCR_HEIGHT);
  memset(b, 128, sizeof(b));
  drawLine(x1, y1, x2, y2, 0xff, b);
  fwrite(b, 1, sizeof(b), out);
  fclose(out);
  return 0;
}

作業時間 : 1時間20分 (22:41.53〜00:01.58)

…一時間以上かかったよ orz

何か線を描画して、pgmファイルで出力するところまでは5分で書けたけど、デバッグに1時間以上かかった…駄目過ぎ >> 俺

…精進せねば。