예제 #1
0
    def scale(cls, x, y, z, dtype=FLOAT) -> 'Transform':
        m = np.eye(4, 4, dtype=dtype)
        m_inv = np.eye(4, 4, dtype=dtype)

        m[0][0] = x
        m[1][1] = y
        m[2][2] = z
        m_inv[0][0] = 1. / x
        m_inv[1][1] = 1. / y
        m_inv[2][2] = 1. / z

        return cls(m, m_inv, dtype)
예제 #2
0
    def translate(cls, delta: 'geo.Vector', dtype=FLOAT) -> 'Transform':
        m = np.eye(4, 4, dtype=dtype)
        m_inv = np.eye(4, 4, dtype=dtype)

        m[0][3] = delta.x
        m[1][3] = delta.y
        m[2][3] = delta.z
        m_inv[0][3] = -delta.x
        m_inv[1][3] = -delta.y
        m_inv[2][3] = -delta.z

        return cls(m, m_inv, dtype)
예제 #3
0
    def look_at(cls,
                pos: 'geo.Point',
                look: 'geo.Point',
                up: 'geo.Vector',
                dtype=FLOAT) -> 'Transform':
        """
		look_at
		Look-at transformation, from camera
		to world
		"""
        w2c = np.eye(4, 4, dtype=dtype)
        c2w = np.eye(4, 4, dtype=dtype)

        zc = geo.normalize(look - pos)
        xc = geo.normalize(geo.normalize(up).cross(zc))
        yc = zc.cross(xc)  # orthogonality

        # c2w translation
        c2w[0][3] = pos.x
        c2w[1][3] = pos.y
        c2w[2][3] = pos.z

        # c2w rotation
        c2w[0][0] = xc.x
        c2w[0][1] = xc.y
        c2w[0][2] = xc.z
        c2w[1][0] = yc.x
        c2w[1][1] = yc.y
        c2w[1][2] = yc.z
        c2w[2][0] = zc.x
        c2w[2][1] = zc.y
        c2w[2][2] = zc.z

        # w2c rotation
        # in effect as camera extrinsic
        w2c[0][0] = xc.x
        w2c[0][1] = yc.x
        w2c[0][2] = zc.x
        w2c[1][0] = xc.y
        w2c[1][1] = yc.y
        w2c[1][2] = zc.y
        w2c[2][0] = xc.z
        w2c[2][1] = yc.z
        w2c[2][2] = zc.z

        # w2c translation
        w2c[0][3] = -(pos.x * xc.x + pos.y * yc.x + pos.z * zc.x)
        w2c[1][3] = -(pos.x * xc.y + pos.y * yc.y + pos.z * zc.y)
        w2c[2][3] = -(pos.x * xc.z + pos.y * yc.z + pos.z * zc.z)

        return cls(c2w, w2c, dtype)
예제 #4
0
    def __init__(self, m=None, m_inv=None, dtype=FLOAT):
        if m is None:
            self.__m = np.eye(4, 4, dtype=dtype)
            self.__m_inv = np.eye(4, 4, dtype=dtype)
        elif m is not None and m_inv is not None:
            self.__m = m.copy()
            self.__m_inv = m_inv.copy()
        else:
            if not np.shape(m) == (4, 4):
                raise TypeError('Transform matrix must be 4x4')

            self.__m = m.copy()
            self.__m_inv = np.linalg.inv(m)
        self.__m.flags.writeable = False
        self.__m_inv.flags.writeable = False
예제 #5
0
 def rotate_z(cls, angle, dtype=FLOAT) -> 'Transform':
     m = np.eye(4, 4, dtype=dtype)
     sin_t = np.sin(np.deg2rad(angle))
     cos_t = np.cos(np.deg2rad(angle))
     m[0][0] = cos_t
     m[0][1] = -sin_t
     m[1][0] = sin_t
     m[1][1] = cos_t
     return cls(m, m.T, dtype)
예제 #6
0
    def perspective(cls, fov: FLOAT, n: FLOAT, f: FLOAT, dtype=FLOAT):
        # projective along z
        m = np.eye(4, dtype=dtype)
        m[2, 2] = f / (f - n)
        m[2, 3] = -f * n / (f - n)
        m[3, 2] = 1.
        m[3, 3] = 0.

        # scale to viewing volume
        tan_inv = 1. / np.tan(np.deg2rad(fov) / 2.)
        return cls.scale(tan_inv, tan_inv, 1.) * cls(m)
예제 #7
0
    def rotate(cls, angle, axis: 'geo.Vector', dtype=FLOAT) -> 'Transform':
        a = geo.normalize(axis)

        s = np.sin(np.deg2rad(angle))
        c = np.cos(np.deg2rad(angle))

        m = np.eye(4, 4, dtype=dtype)

        m[0][0] = a.x * a.x + (1. - a.x * a.x) * c
        m[0][1] = a.x * a.y * (1. - c) - a.z * s
        m[0][2] = a.x * a.z * (1. - c) + a.y * s
        m[1][0] = a.x * a.y * (1. - c) + a.z * s
        m[1][1] = a.y * a.y + (1. - a.y * a.y) * c
        m[1][2] = a.y * a.z * (1. - c) - a.x * s
        m[2][0] = a.x * a.z * (1. - c) - a.y * s
        m[2][1] = a.y * a.z * (1. - c) + a.x * s
        m[2][2] = a.z * a.z + (1. - a.z * a.z) * c

        return cls(m, m.T, dtype)
예제 #8
0
 def is_identity(self) -> bool:
     return np.array_equal(self.m, np.eye(4, 4))