2012年5月17日木曜日

[Python, pylab]how to transform graphics with 3-by-3 transformation matrix.

pylabでベジエ曲線が描けたので、今度は変換行列で、変換を行ってみます。
# -*- coding: utf-8 -*-
import pylab
from math import radians, sin, cos, tan

def make_bezier(p0, p1, p2, p3):
    # ベジエ曲線の公式
    # t: 0.0~1.0までの値 0.0のとき、始点をplotし、1.0のとき、終点をplotする。
    def formula(t, p0, p1, p2, p3):
        return ((1-t)**3)*p0 + (3*t)*((1-t)**2)*p1 + 3*(t**2)*(1-t)*p2 +(t**3)*p3
    def _bezier(t):
        return [formula(t, p0[i],p1[i],p2[i],p3[i]) for i in (0, 1)]
    return _bezier

def transform(x, y, m):
    return (x*m[0] + y*m[3] + m[6], \
            x*m[1] + y*m[4] + m[7], \
            x*m[2] + y*m[5] + m[8])

if __name__ == '__main__':
    t = pylab.arange(0.0, 1.001, 0.01)
    bazier = make_bezier((0, 0), (0, 3), (3, 0), (3, 3))

    # 変換なし
    m = (1, 0, 0, \
         0, 1, 0, \
         0, 0, 1)

    coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))]
    (xs,ys) = zip(*coordinates)
    pylab.plot(xs, ys)
    
    # 平行移動 (3, 3)
    m = (1, 0, 0, \
         0, 1, 0, \
         3, 3, 1)

    coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))]
    (xs,ys) = zip(*coordinates)
    pylab.plot(xs, ys)

    # 拡大 (-1.5, -1.5) ※原点対照に反転し、1.5培する。
    m = (-1.5, 0, 0, \
         0, -1.5, 0, \
         0, 0, 1)

    coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))]
    (xs,ys) = zip(*coordinates)
    pylab.plot(xs, ys)

    # 回転 60°
    r = radians(60)
    m = (cos(r), sin(r), 0, \
         -sin(r), cos(r), 0, \
         -5, 5, 1)

    coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))]
    (xs,ys) = zip(*coordinates)
    pylab.plot(xs, ys)

    # 傾斜 a=15° b=20°
    a = radians(-15)
    b = radians(-20)
    m = (1, tan(a), 0, \
         tan(b), 1, 0, \
         -5, 5, 1)

    coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))]
    (xs,ys) = zip(*coordinates)
    pylab.plot(xs, ys)

    pylab.grid()
    pylab.axis([-15, 15, -15, 15])
    pylab.show()

0 件のコメント:

コメントを投稿