ブレゼンハムの線分描画アルゴリズム
文章:syun
日付:2005/9/10

目次
1.はじめに
2.入力と出力
3.アルゴリズム






1.はじめに
ブレゼンハムの線分描画アルゴリズムとは、
描画座標が「整数値」を取る場合に有効なアルゴリズムです。

例えば、青丸から緑丸への線分は以下のようになって欲しいですよね。
線分描画
こういった線分を描画するアルゴリズムがブレゼンハムです。

このアルゴリズムを使えば、例えば戦術シミュレーションゲームでの
「最短経路の探索」などに応用することができます。




2.入力と出力
まず、入力と出力を押さえておきます。 入力となるのは、 となります。

これを元に、 例えば、開始座標を(1,1)、終了座標(4,6)とすると、
ret[0]→(1,1)
ret[1]→(2,2)
ret[2]→(2,3)
ret[3]→(3,4)
ret[4]→(3,5)
ret[5]→(4,6)
が出力となります。





3.アルゴリズム
以下の一時変数が必要になります。

そして、準備として以下の処理を行います。
  1. vNextに開始座標を代入
  2. vDeltaに(終了座標−開始座標)を代入
  3. vDeltaの値を元に、vStepに値を代入
    1. vDelta.x/yが0以上であれば、vStep.x/yに1を代入
    2. vDelta.x/yが0より小さければ、vStep.x/yに-1を代入
  4. vDeltaの値を2倍する
…で、メインアルゴリズムなのですが、、、。
その先は、次のソースコードを見て理解してください、、、。

手抜きでスミマセン…(´Д`;

例えば、Pythonで実装すると以下のようになります。
class Vec2D:
	def __init__(self, x=0, y=0):
		self.x = x
		self.y = y
	
	# インスタンスのコピーを返す
	def clone(self):
		return Vec2D(self.x, self.y)
	
	# ブレゼンハムの線分描画
	# @return selfからvEndへのポイントリスト
	def bresenham(self, vEnd):
		# 準備
		vNext  = Vec2D(self.x, self.y)
		vDelta = Vec2D(vEnd.x-self.x, vEnd.y-self.y)
		vStep  = Vec2D(1, 1)
		if vDelta.x < 0:
			vStep.x = -1
		if vDelta.y < 0:
			vStep.y = -1
		vDelta.x = abs(vDelta.x*2)
		vDelta.y = abs(vDelta.y*2)
		
		pList = []
		pList.append(vNext.clone())
		
		# 線分の座標リストを作る
		if vDelta.x > vDelta.y:
			frac = vDelta.y*2 - vDelta.x
			while vNext.x != vEnd.x:
				if frac >= 0:
					vNext.y += vStep.y
					frac -= vDelta.x
				vNext.x += vStep.x
				frac += vDelta.y
				pList.append(vNext.clone())
		else:
			frac = vDelta.x*2 - vDelta.y
			while vNext.y != vEnd.y:
				if frac >= 0:
					vNext.x += vStep.x
					frac -= vDelta.y
				vNext.y += vStep.y
				frac += vDelta.x
				pList.append(vNext.clone())
		return pList

大まかな流れとしては、
vDeltaのxとyを比較して、処理を2つに分けます。

そして、vDeltaをfracから引いたり足したりして、
ある条件を満たす・満たさないの場合分けをして、
vStepをvNextに足しこんでいます。