Source code for dent.transforms

# THE FOLLOWING CODE FALLS UNDER THE LICENCE BELOW:
#
# Copyright (c) 2015, authors of Vispy
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
#   notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in the
#   documentation and/or other materials provided with the distribution.
# * Neither the name of Vispy Development Team nor the names of its
#   contributors may be used to endorse or promote products
#   derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import numpy as np


[docs]def translate(M, x, y=None, z=None): """ translate produces a translation by (x, y, z) . Parameters ---------- x, y, z Specify the x, y, and z coordinates of a translation vector. """ if y is None: y = x if z is None: z = x T = [[ 1, 0, 0, x], [ 0, 1, 0, y], [ 0, 0, 1, z], [ 0, 0, 0, 1]] T = np.array(T, dtype=np.float32).T M[...] = np.dot(M,T)
[docs]def translate2(x, y=None, z=None): """ translate produces a translation by (x, y, z) . Parameters ---------- x, y, z Specify the x, y, and z coordinates of a translation vector. """ if y is None: y = x if z is None: z = x T = [[ 1, 0, 0, x], [ 0, 1, 0, y], [ 0, 0, 1, z], [ 0, 0, 0, 1]] T = np.array(T, dtype=np.float32).T return T
[docs]def scale(M, x, y=None, z=None): """ scale produces a non uniform scaling along the x, y, and z axes. The three parameters indicate the desired scale factor along each of the three axes. Parameters ---------- x, y, z Specify scale factors along the x, y, and z axes, respectively. """ if y is None: y = x if z is None: z = x S = [[ x, 0, 0, 0], [ 0, y, 0, 0], [ 0, 0, z, 0], [ 0, 0, 0, 1]] S = np.array(S,dtype=np.float32).T M[...] = np.dot(M,S)
[docs]def xrotate(M,theta): t = np.pi*theta/180 cosT = np.cos( t ) sinT = np.sin( t ) R = np.array( [[ 1.0, 0.0, 0.0, 0.0 ], [ 0.0, cosT,-sinT, 0.0 ], [ 0.0, sinT, cosT, 0.0 ], [ 0.0, 0.0, 0.0, 1.0 ]], dtype=np.float32) M[...] = np.dot(M,R)
[docs]def yrotate(M,theta): t = np.pi*theta/180 cosT = np.cos( t ) sinT = np.sin( t ) R = np.array( [[ cosT, 0.0, sinT, 0.0 ], [ 0.0, 1.0, 0.0, 0.0 ], [-sinT, 0.0, cosT, 0.0 ], [ 0.0, 0.0, 0.0, 1.0 ]], dtype=np.float32) M[...] = np.dot(M,R)
[docs]def zrotate(M,theta): t = np.pi*theta/180 cosT = np.cos( t ) sinT = np.sin( t ) R = np.array( [[ cosT,-sinT, 0.0, 0.0 ], [ sinT, cosT, 0.0, 0.0 ], [ 0.0, 0.0, 1.0, 0.0 ], [ 0.0, 0.0, 0.0, 1.0 ]], dtype=np.float32) M[...] = np.dot(M,R)
[docs]def rotate(M, angle, x, y, z, point=None): """ rotate produces a rotation of angle degrees around the vector (x, y, z). Parameters ---------- M Current transformation as a numpy array angle Specifies the angle of rotation, in degrees. x, y, z Specify the x, y, and z coordinates of a vector, respectively. """ angle = np.pi*angle/180 c,s = np.cos(angle), np.sin(angle) n = np.sqrt(x*x+y*y+z*z) x /= n y /= n z /= n cx,cy,cz = (1-c)*x, (1-c)*y, (1-c)*z R = np.array([[ cx*x + c , cy*x - z*s, cz*x + y*s, 0], [ cx*y + z*s, cy*y + c , cz*y - x*s, 0], [ cx*z - y*s, cy*z + x*s, cz*z + c, 0], [ 0, 0, 0, 1]]).T M[...] = np.dot(M,R)
[docs]def ortho( left, right, bottom, top, znear, zfar ): assert( right != left ) assert( bottom != top ) assert( znear != zfar ) M = np.zeros((4,4), dtype=np.float32) M[0,0] = +2.0/(right-left) M[3,0] = -(right+left)/float(right-left) M[1,1] = +2.0/(top-bottom) M[3,1] = -(top+bottom)/float(top-bottom) M[2,2] = -2.0/(zfar-znear) M[3,2] = -(zfar+znear)/float(zfar-znear) M[3,3] = 1.0 return M
[docs]def frustum( left, right, bottom, top, znear, zfar ): assert( right != left ) assert( bottom != top ) assert( znear != zfar ) M = np.zeros((4,4), dtype=np.float32) M[0,0] = +2.0*znear/(right-left) M[2,0] = (right+left)/(right-left) M[1,1] = +2.0*znear/(top-bottom) M[3,1] = (top+bottom)/(top-bottom) M[2,2] = -(zfar+znear)/(zfar-znear) M[3,2] = -2.0*znear*zfar/(zfar-znear) M[2,3] = -1.0 return M
[docs]def perspective(fovy, aspect, znear, zfar): assert( znear != zfar ) h = np.tan(fovy / 360.0 * np.pi) * znear w = h * aspect return frustum( -w, w, -h, h, znear, zfar )
# THE FOLLOWING CODE FALLS UNDER THE LICENCE BELOW: # # Copyright (c) 2006-2017, Christoph Gohlke # Copyright (c) 2006-2017, The Regents of the University of California # Produced at the Laboratory for Fluorescence Dynamics # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the copyright holders nor the names of any # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE.
[docs]def quaternion_matrix(quaternion): """Return homogeneous rotation matrix from quaternion. >>> M = quaternion_matrix([0.99810947, 0.06146124, 0, 0]) >>> numpy.allclose(M, rotation_matrix(0.123, [1, 0, 0])) True >>> M = quaternion_matrix([1, 0, 0, 0]) >>> numpy.allclose(M, numpy.identity(4)) True >>> M = quaternion_matrix([0, 1, 0, 0]) >>> numpy.allclose(M, numpy.diag([1, -1, -1, 1])) True """ q = np.array(quaternion, dtype=np.float64, copy=True) n = np.dot(q, q) if n < 1e-6: return np.identity(4) q *= np.sqrt(2.0 / n) q = np.outer(q, q) return np.array([ [(1.0-q[2, 2]-q[3, 3]), ( q[1, 2]-q[3, 0]),( q[1, 3]+q[2, 0]), 0.0], [( q[1, 2]+q[3, 0]), (1.0-q[1, 1]-q[3, 3]),( q[2, 3]-q[1, 0]), 0.0], [( q[1, 3]-q[2, 0]), ( q[2, 3]+q[1, 0]),( 1.0-q[1, 1]-q[2, 2]), 0.0], [ 0.0, 0.0, 0.0, 1.0]])