投稿日: Jun 15, 2019 1:11:1 PM
ブレセンハムのアルゴリズムを使わず、大真面目にベクトル計算をしてラインを引いたらどうなんだろうか。
という実験。
原点(0,0)からx , y へ線を引く。
角度を知る。
math.atan2(x, y)
math.atan2(x, y) xとyがそれぞれ1なら角度は45度であるはず。
0.7853981633974483
という数字が返ってくる。
本当に45度なのか見てみる
>>> x = y = 1
>>> math.degrees( math.atan2(x, y) )
45.0
2点間の距離を求める。
math.sqrt(x**2 + y**2)
√2 = 1.414ってのはもう覚えちゃってますよねー。
ので正しく計算できてるか見てみます。
>>> math.sqrt( 1 ** 2 + 1 ** 2 )
1.4142135623730951
座標を求めた角度と長さで回転する。
実際に正しい角度になるかという実験です。
def rot( l, rad ):
rr = rad
xx = l * math.sin(rr)
yy = l * math.cos(rr)
return xx, yy
x = 100
y = 50
xx, yy = rot(math.sqrt(x**2 + y**2), math.atan2(x, y))
部分的に抜き出しました。
このように求めた長さと角度で座標を回転し、試しに直接ラインを引いたもの(赤)と計算結果(緑)を描画してます。
問題なくできてるようです。 ※ちなみに重なるとわからないので赤いラインはちょっとずらして描画してます。
回転の式が不思議? と思ったかもしれないけれど座標系をあわせるためです。
3D座標系になってるといろいろ面倒くさいので。
ドットでラインを描く。
ブレセンハムのアルゴリズムでは長い方のステップ数を知り処理を分けないといけませんでした。
今回はベクトルで処理をしていますので、移動距離を1にして長さ分繰り返せばOKです。
これによってムダも発生するんですが今回のそもそもの狙いはそこまで頑張らなくても速度出るんじゃね? っていうものですので。あまり考えず。実験です実験。
x = 100
y = 50
xx, yy = rot(1, math.atan2(x, y))
step = int(math.sqrt(x**2 + y**2))
xs = xx
ys = yy
xp = 0
yp = 0
for i in range( step ):
pyg.gfx.pixel(pyg.surface, int(xp), int(yp), pyg.Color(0,255,0))
xp += xs
yp += ys
移動距離を1にして回転、線の長さ分のステップ数でドットを描画。
例のごとく緑色が今回の結果ですが、ちょっとずらして描いた普通のライン命令による赤色の線と何もかわりはしないようです。
一応描画するという目的はこれで達成できましたね。
ソースコードもかなりシンプルな気がします。
描画速度が実際どうなのか試す必要があるような気がしなくもないんですが、一旦ここまで。
嘘です、長さ足りてませんよね。
実際の長さに満たないのはちょっと問題です。
もうすこし考えないといけないようですねー。
浮上する「そもそもベクトル計算しなくていいんじゃ」疑惑
x = 100
y = 50
step = max(x,y)
xs = x / step
ys = y / step
xp = 0
yp = 0
for i in range( step+1 ):
pyg.gfx.pixel(pyg.surface, int(xp), int(yp), pyg.Color(0,255,0))
xp += xs
yp += ys
長さが足りなくなるのはまず、forループだから+1しないといけないところで一つ。
そして、実際の座標から長さで割って・・とかやってたらそもそもベクトル計算必要ないじゃんってところにたどり着きました。
やばい、ぐんぐんブレセンハムのアルゴリズムに近づいてきました。
こういうことですよね…。
まあ簡単に書ける以外にメリットはあまりない気がしますが・・・。
速度テストは近いうちにやってみましょう。