いよいよ地獄の窯が開きます。これまでの中間総集編となる内容です。
1.画像回転を処理するにあたり、まず「何処に」転送するかから考えていきます
前回の線の描画ルーチンを元に、縦方向の転送先座標を順に計算していきます。
次いで、90度(128度法で32度)角度を進めて横方向の座標を求める計算を入れ子して求めていきます。
2.次に「どこから」転送するかを考えていきます
転送先が斜めになった際、縦幅にしろ横幅にしろ、元の幅より狭くなります。
つまり、そのまま転送するのではなく数ドット間引きして縮めて送る必要が出てきます。
第一回で行ったブレゼンハムアルゴリズムは「長辺を元に短辺の位置」を算出していましたが、
今回は逆に短い幅を元に長い幅(元画像の幅)を求めなくてはなりません。
このため、第一回で作ったアルゴリズムを主体が短辺の時も対応できるように改造します。
ソースここから
import pyxel
my_table = (
※第三回参照
def my_sin(angle,r):
※第三回参照
def my_cos(angle,r):
※第三回参照
class VBresenham:
※第二回参照
class Bresenham:
def __init__(self):
self.l_side = 0
self.s_side = 0
self.counter = 0
self.adder = 0
# Src side is longer
self.b_long_ss = True
def setup(self,Dest_side,Src_side):
self.counter = 0
self.adder = 0
if Dest_side > Src_side:
self.b_long_ss = False
self.l_side = Dest_side+1
self.s_side = Src_side+1
return self.l_side
self.b_long_ss = True
self.l_side = Src_side+1
self.s_side = Dest_side+1
return self.s_side
def step(self):
ret = self.adder
if self.b_long_ss:
while self.counter <= self.l_side:
self.adder += 1
self.counter += self.s_side
self.counter -= self.l_side
else:
self.counter += self.s_side
i = self.counter - self.l_side
if i >= 0:
self.counter = i
self.adder += 1
return ret
class App:
def __init__(self):
# 画面サイズ 160x120 で初期化
pyxel.init(160, 120, title="RollBlt")
self.add_x = 0
pyxel.load("yajirushi.pyxres")
self.x = 0
self.y = 0
self.angle = 0
self.vbre_v = VBresenham()
self.vbre_h = VBresenham()
self.bre_v = Bresenham()
self.bre_h = Bresenham()
pyxel.run(self.update, self.draw)
def update(self):
self.angle += 1
self.angle &= 127
self.x = my_sin(self.angle,15)+80
self.y = my_cos(self.angle,15)+60
def draw(self):
# 画面を黒(色番号0)でクリア
pyxel.cls(0)
# 画像縦方向ループ
reg_v = self.vbre_v.setup(80,60,self.x,self.y)
self.bre_v.setup(reg_v-1,15)
for i in range (reg_v):
x_v,y_v = self.vbre_v.step()
src_y = self.bre_v.step()
# 画像横方向ループ
x_h = my_sin(self.angle+32,31)+x_v
y_h = my_cos(self.angle+32,31)+y_v
reg_h = self.vbre_h.setup(x_v,y_v,x_h,y_h)
self.bre_h.setup(reg_h-1,31)
for j in range (reg_h):
x,y = self.vbre_h.step()
src_x = self.bre_h.step()
pyxel.blt(x, y, 0, src_x, src_y, 1, 1)
App()
ソースここまで
※紫色にしている部分が短辺主体に追加した部分
そして出力
…はい、理屈の上でのアルゴリズムは間違っていません。ただ、ブレゼンハムアルゴリズムは本来アナログな直線を整数に区切るアルゴリズムです。
当然、ある程度のズレが生じます。45度付近になると顕著にズレるため、このような表示になります。
いよいよ地獄が見えてきました。
正直に言えばこうなる事は最初から解っていましたが、段階を踏むとはこう言う事です。
次は更に踏み込んでいくのですが…今回のプログラムだけでも半日かかっていまして…次からはほぼ未知の領域なので予定がたたないのですよね…。
















