<s> """<STR_LIT>""" <EOL> from __future__ import division , print_function <EOL> import math <EOL> import numpy <EOL> __version__ = '<STR_LIT>' <EOL> __docformat__ = '<STR_LIT>' <EOL> __all__ = [ ] <EOL> def identity_matrix ( ) : <EOL> """<STR_LIT>""" <EOL> return numpy . identity ( <NUM_LIT:4> ) <EOL> def translation_matrix ( direction ) : <EOL> """<STR_LIT>""" <EOL> M = numpy . identity ( <NUM_LIT:4> ) <EOL> M [ : <NUM_LIT:3> , <NUM_LIT:3> ] = direction [ : <NUM_LIT:3> ] <EOL> return M <EOL> def translation_from_matrix ( matrix ) : <EOL> """<STR_LIT>""" <EOL> return numpy . array ( matrix , copy = False ) [ : <NUM_LIT:3> , <NUM_LIT:3> ] . copy ( ) <EOL> def reflection_matrix ( point , normal ) : <EOL> """<STR_LIT>""" <EOL> normal = unit_vector ( normal [ : <NUM_LIT:3> ] ) <EOL> M = numpy . identity ( <NUM_LIT:4> ) <EOL> M [ : <NUM_LIT:3> , : <NUM_LIT:3> ] -= <NUM_LIT> * numpy . outer ( normal , normal ) <EOL> M [ : <NUM_LIT:3> , <NUM_LIT:3> ] = ( <NUM_LIT> * numpy . dot ( point [ : <NUM_LIT:3> ] , normal ) ) * normal <EOL> return M <EOL> def reflection_from_matrix ( matrix ) : <EOL> """<STR_LIT>""" <EOL> M = numpy . array ( matrix , dtype = numpy . float64 , copy = False ) <EOL> w , V = numpy . linalg . eig ( M [ : <NUM_LIT:3> , : <NUM_LIT:3> ] ) <EOL> i = numpy . where ( abs ( numpy . real ( w ) + <NUM_LIT:1.0> ) < <NUM_LIT> ) [ <NUM_LIT:0> ] <EOL> if not len ( i ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> normal = numpy . real ( V [ : , i [ <NUM_LIT:0> ] ] ) . squeeze ( ) <EOL> w , V = numpy . linalg . eig ( M ) <EOL> i = numpy . where ( abs ( numpy . real ( w ) - <NUM_LIT:1.0> ) < <NUM_LIT> ) [ <NUM_LIT:0> ] <EOL> if not len ( i ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> point = numpy . real ( V [ : , i [ - <NUM_LIT:1> ] ] ) . squeeze ( ) <EOL> point /= point [ <NUM_LIT:3> ] <EOL> return point , normal <EOL> def rotation_matrix ( angle , direction , point = None ) : <EOL> """<STR_LIT>""" <EOL> sina = math . sin ( angle ) <EOL> cosa = math . cos ( angle ) <EOL> direction = unit_vector ( direction [ : <NUM_LIT:3> ] ) <EOL> R = numpy . diag ( [ cosa , cosa , cosa ] ) <EOL> R += numpy . outer ( direction , direction ) * ( <NUM_LIT:1.0> - cosa ) <EOL> direction *= sina <EOL> R += numpy . array ( [ [ <NUM_LIT:0.0> , - direction [ <NUM_LIT:2> ] , direction [ <NUM_LIT:1> ] ] , <EOL> [ direction [ <NUM_LIT:2> ] , <NUM_LIT:0.0> , - direction [ <NUM_LIT:0> ] ] , <EOL> [ - direction [ <NUM_LIT:1> ] , direction [ <NUM_LIT:0> ] , <NUM_LIT:0.0> ] ] ) <EOL> M = numpy . identity ( <NUM_LIT:4> ) <EOL> M [ : <NUM_LIT:3> , : <NUM_LIT:3> ] = R <EOL> if point is not None : <EOL> point = numpy . array ( point [ : <NUM_LIT:3> ] , dtype = numpy . float64 , copy = False ) <EOL> M [ : <NUM_LIT:3> , <NUM_LIT:3> ] = point - numpy . dot ( R , point ) <EOL> return M <EOL> def rotation_from_matrix ( matrix ) : <EOL> """<STR_LIT>""" <EOL> R = numpy . array ( matrix , dtype = numpy . float64 , copy = False ) <EOL> R33 = R [ : <NUM_LIT:3> , : <NUM_LIT:3> ] <EOL> w , W = numpy . linalg . eig ( R33 . T ) <EOL> i = numpy . where ( abs ( numpy . real ( w ) - <NUM_LIT:1.0> ) < <NUM_LIT> ) [ <NUM_LIT:0> ] <EOL> if not len ( i ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> direction = numpy . real ( W [ : , i [ - <NUM_LIT:1> ] ] ) . squeeze ( ) <EOL> w , Q = numpy . linalg . eig ( R ) <EOL> i = numpy . where ( abs ( numpy . real ( w ) - <NUM_LIT:1.0> ) < <NUM_LIT> ) [ <NUM_LIT:0> ] <EOL> if not len ( i ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> point = numpy . real ( Q [ : , i [ - <NUM_LIT:1> ] ] ) . squeeze ( ) <EOL> point /= point [ <NUM_LIT:3> ] <EOL> cosa = ( numpy . trace ( R33 ) - <NUM_LIT:1.0> ) / <NUM_LIT> <EOL> if abs ( direction [ <NUM_LIT:2> ] ) > <NUM_LIT> : <EOL> sina = ( R [ <NUM_LIT:1> , <NUM_LIT:0> ] + ( cosa - <NUM_LIT:1.0> ) * direction [ <NUM_LIT:0> ] * direction [ <NUM_LIT:1> ] ) / direction [ <NUM_LIT:2> ] <EOL> elif abs ( direction [ <NUM_LIT:1> ] ) > <NUM_LIT> : <EOL> sina = ( R [ <NUM_LIT:0> , <NUM_LIT:2> ] + ( cosa - <NUM_LIT:1.0> ) * direction [ <NUM_LIT:0> ] * direction [ <NUM_LIT:2> ] ) / direction [ <NUM_LIT:1> ] <EOL> else : <EOL> sina = ( R [ <NUM_LIT:2> , <NUM_LIT:1> ] + ( cosa - <NUM_LIT:1.0> ) * direction [ <NUM_LIT:1> ] * direction [ <NUM_LIT:2> ] ) / direction [ <NUM_LIT:0> ] <EOL> angle = math . atan2 ( sina , cosa ) <EOL> return angle , direction , point <EOL> def scale_matrix ( factor , origin = None , direction = None ) : <EOL> """<STR_LIT>""" <EOL> if direction is None : <EOL> M = numpy . diag ( [ factor , factor , factor , <NUM_LIT:1.0> ] ) <EOL> if origin is not None : <EOL> M [ : <NUM_LIT:3> , <NUM_LIT:3> ] = origin [ : <NUM_LIT:3> ] <EOL> M [ : <NUM_LIT:3> , <NUM_LIT:3> ] *= <NUM_LIT:1.0> - factor <EOL> else : <EOL> direction = unit_vector ( direction [ : <NUM_LIT:3> ] ) <EOL> factor = <NUM_LIT:1.0> - factor <EOL> M = numpy . identity ( <NUM_LIT:4> ) <EOL> M [ : <NUM_LIT:3> , : <NUM_LIT:3> ] -= factor * numpy . outer ( direction , direction ) <EOL> if origin is not None : <EOL> M [ : <NUM_LIT:3> , <NUM_LIT:3> ] = ( factor * numpy . dot ( origin [ : <NUM_LIT:3> ] , direction ) ) * direction <EOL> return M <EOL> def scale_from_matrix ( matrix ) : <EOL> """<STR_LIT>""" <EOL> M = numpy . array ( matrix , dtype = numpy . float64 , copy = False ) <EOL> M33 = M [ : <NUM_LIT:3> , : <NUM_LIT:3> ] <EOL> factor = numpy . trace ( M33 ) - <NUM_LIT> <EOL> try : <EOL> w , V = numpy . linalg . eig ( M33 ) <EOL> i = numpy . where ( abs ( numpy . real ( w ) - factor ) < <NUM_LIT> ) [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] <EOL> direction = numpy . real ( V [ : , i ] ) . squeeze ( ) <EOL> direction /= vector_norm ( direction ) <EOL> except IndexError : <EOL> factor = ( factor + <NUM_LIT> ) / <NUM_LIT> <EOL> direction = None <EOL> w , V = numpy . linalg . eig ( M ) <EOL> i = numpy . where ( abs ( numpy . real ( w ) - <NUM_LIT:1.0> ) < <NUM_LIT> ) [ <NUM_LIT:0> ] <EOL> if not len ( i ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> origin = numpy . real ( V [ : , i [ - <NUM_LIT:1> ] ] ) . squeeze ( ) <EOL> origin /= origin [ <NUM_LIT:3> ] <EOL> return factor , origin , direction <EOL> def projection_matrix ( point , normal , direction = None , <EOL> perspective = None , pseudo = False ) : <EOL> """<STR_LIT>""" <EOL> M = numpy . identity ( <NUM_LIT:4> ) <EOL> point = numpy . array ( point [ : <NUM_LIT:3> ] , dtype = numpy . float64 , copy = False ) <EOL> normal = unit_vector ( normal [ : <NUM_LIT:3> ] ) <EOL> if perspective is not None : <EOL> perspective = numpy . array ( perspective [ : <NUM_LIT:3> ] , dtype = numpy . float64 , <EOL> copy = False ) <EOL> M [ <NUM_LIT:0> , <NUM_LIT:0> ] = M [ <NUM_LIT:1> , <NUM_LIT:1> ] = M [ <NUM_LIT:2> , <NUM_LIT:2> ] = numpy . dot ( perspective - point , normal ) <EOL> M [ : <NUM_LIT:3> , : <NUM_LIT:3> ] -= numpy . outer ( perspective , normal ) <EOL> if pseudo : <EOL> M [ : <NUM_LIT:3> , : <NUM_LIT:3> ] -= numpy . outer ( normal , normal ) <EOL> M [ : <NUM_LIT:3> , <NUM_LIT:3> ] = numpy . dot ( point , normal ) * ( perspective + normal ) <EOL> else : <EOL> M [ : <NUM_LIT:3> , <NUM_LIT:3> ] = numpy . dot ( point , normal ) * perspective <EOL> M [ <NUM_LIT:3> , : <NUM_LIT:3> ] = - normal <EOL> M [ <NUM_LIT:3> , <NUM_LIT:3> ] = numpy . dot ( perspective , normal ) <EOL> elif direction is not None : <EOL> direction = numpy . array ( direction [ : <NUM_LIT:3> ] , dtype = numpy . float64 , copy = False ) <EOL> scale = numpy . dot ( direction , normal ) <EOL> M [ : <NUM_LIT:3> , : <NUM_LIT:3> ] -= numpy . outer ( direction , normal ) / scale <EOL> M [ : <NUM_LIT:3> , <NUM_LIT:3> ] = direction * ( numpy . dot ( point , normal ) / scale ) <EOL> else : <EOL> M [ : <NUM_LIT:3> , : <NUM_LIT:3> ] -= numpy . outer ( normal , normal ) <EOL> M [ : <NUM_LIT:3> , <NUM_LIT:3> ] = numpy . dot ( point , normal ) * normal <EOL> return M <EOL> def projection_from_matrix ( matrix , pseudo = False ) : <EOL> """<STR_LIT>""" <EOL> M = numpy . array ( matrix , dtype = numpy . float64 , copy = False ) <EOL> M33 = M [ : <NUM_LIT:3> , : <NUM_LIT:3> ] <EOL> w , V = numpy . linalg . eig ( M ) <EOL> i = numpy . where ( abs ( numpy . real ( w ) - <NUM_LIT:1.0> ) < <NUM_LIT> ) [ <NUM_LIT:0> ] <EOL> if not pseudo and len ( i ) : <EOL> point = numpy . real ( V [ : , i [ - <NUM_LIT:1> ] ] ) . squeeze ( ) <EOL> point /= point [ <NUM_LIT:3> ] <EOL> w , V = numpy . linalg . eig ( M33 ) <EOL> i = numpy . where ( abs ( numpy . real ( w ) ) < <NUM_LIT> ) [ <NUM_LIT:0> ] <EOL> if not len ( i ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> direction = numpy . real ( V [ : , i [ <NUM_LIT:0> ] ] ) . squeeze ( ) <EOL> direction /= vector_norm ( direction ) <EOL> w , V = numpy . linalg . eig ( M33 . T ) <EOL> i = numpy . where ( abs ( numpy . real ( w ) ) < <NUM_LIT> ) [ <NUM_LIT:0> ] <EOL> if len ( i ) : <EOL> normal = numpy . real ( V [ : , i [ <NUM_LIT:0> ] ] ) . squeeze ( ) <EOL> normal /= vector_norm ( normal ) <EOL> return point , normal , direction , None , False <EOL> else : <EOL> return point , direction , None , None , False <EOL> else : <EOL> i = numpy . where ( abs ( numpy . real ( w ) ) > <NUM_LIT> ) [ <NUM_LIT:0> ] <EOL> if not len ( i ) : <EOL> raise ValueError ( <EOL> "<STR_LIT>" ) <EOL> point = numpy . real ( V [ : , i [ - <NUM_LIT:1> ] ] ) . squeeze ( ) <EOL> point /= point [ <NUM_LIT:3> ] <EOL> normal = - M [ <NUM_LIT:3> , : <NUM_LIT:3> ] <EOL> perspective = M [ : <NUM_LIT:3> , <NUM_LIT:3> ] / numpy . dot ( point [ : <NUM_LIT:3> ] , normal ) <EOL> if pseudo : <EOL> perspective -= normal <EOL> return point , normal , None , perspective , pseudo <EOL> def clip_matrix ( left , right , bottom , top , near , far , perspective = False ) : <EOL> """<STR_LIT>""" <EOL> if left >= right or bottom >= top or near >= far : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if perspective : <EOL> if near <= _EPS : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> t = <NUM_LIT> * near <EOL> M = [ [ t / ( left - right ) , <NUM_LIT:0.0> , ( right + left ) / ( right - left ) , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , t / ( bottom - top ) , ( top + bottom ) / ( top - bottom ) , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:0.0> , ( far + near ) / ( near - far ) , t * far / ( far - near ) ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:0.0> , - <NUM_LIT:1.0> , <NUM_LIT:0.0> ] ] <EOL> else : <EOL> M = [ [ <NUM_LIT> / ( right - left ) , <NUM_LIT:0.0> , <NUM_LIT:0.0> , ( right + left ) / ( left - right ) ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT> / ( top - bottom ) , <NUM_LIT:0.0> , ( top + bottom ) / ( bottom - top ) ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT> / ( far - near ) , ( far + near ) / ( near - far ) ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:1.0> ] ] <EOL> return numpy . array ( M ) <EOL> def shear_matrix ( angle , direction , point , normal ) : <EOL> """<STR_LIT>""" <EOL> normal = unit_vector ( normal [ : <NUM_LIT:3> ] ) <EOL> direction = unit_vector ( direction [ : <NUM_LIT:3> ] ) <EOL> if abs ( numpy . dot ( normal , direction ) ) > <NUM_LIT> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> angle = math . tan ( angle ) <EOL> M = numpy . identity ( <NUM_LIT:4> ) <EOL> M [ : <NUM_LIT:3> , : <NUM_LIT:3> ] += angle * numpy . outer ( direction , normal ) <EOL> M [ : <NUM_LIT:3> , <NUM_LIT:3> ] = - angle * numpy . dot ( point [ : <NUM_LIT:3> ] , normal ) * direction <EOL> return M <EOL> def shear_from_matrix ( matrix ) : <EOL> """<STR_LIT>""" <EOL> M = numpy . array ( matrix , dtype = numpy . float64 , copy = False ) <EOL> M33 = M [ : <NUM_LIT:3> , : <NUM_LIT:3> ] <EOL> w , V = numpy . linalg . eig ( M33 ) <EOL> i = numpy . where ( abs ( numpy . real ( w ) - <NUM_LIT:1.0> ) < <NUM_LIT> ) [ <NUM_LIT:0> ] <EOL> if len ( i ) < <NUM_LIT:2> : <EOL> raise ValueError ( "<STR_LIT>" % w ) <EOL> V = numpy . real ( V [ : , i ] ) . squeeze ( ) . T <EOL> lenorm = - <NUM_LIT:1.0> <EOL> for i0 , i1 in ( ( <NUM_LIT:0> , <NUM_LIT:1> ) , ( <NUM_LIT:0> , <NUM_LIT:2> ) , ( <NUM_LIT:1> , <NUM_LIT:2> ) ) : <EOL> n = numpy . cross ( V [ i0 ] , V [ i1 ] ) <EOL> w = vector_norm ( n ) <EOL> if w > lenorm : <EOL> lenorm = w <EOL> normal = n <EOL> normal /= lenorm <EOL> direction = numpy . dot ( M33 - numpy . identity ( <NUM_LIT:3> ) , normal ) <EOL> angle = vector_norm ( direction ) <EOL> direction /= angle <EOL> angle = math . atan ( angle ) <EOL> w , V = numpy . linalg . eig ( M ) <EOL> i = numpy . where ( abs ( numpy . real ( w ) - <NUM_LIT:1.0> ) < <NUM_LIT> ) [ <NUM_LIT:0> ] <EOL> if not len ( i ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> point = numpy . real ( V [ : , i [ - <NUM_LIT:1> ] ] ) . squeeze ( ) <EOL> point /= point [ <NUM_LIT:3> ] <EOL> return angle , direction , point , normal <EOL> def decompose_matrix ( matrix ) : <EOL> """<STR_LIT>""" <EOL> M = numpy . array ( matrix , dtype = numpy . float64 , copy = True ) . T <EOL> if abs ( M [ <NUM_LIT:3> , <NUM_LIT:3> ] ) < _EPS : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> M /= M [ <NUM_LIT:3> , <NUM_LIT:3> ] <EOL> P = M . copy ( ) <EOL> P [ : , <NUM_LIT:3> ] = <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:1.0> <EOL> if not numpy . linalg . det ( P ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> scale = numpy . zeros ( ( <NUM_LIT:3> , ) ) <EOL> shear = [ <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> ] <EOL> angles = [ <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> ] <EOL> if any ( abs ( M [ : <NUM_LIT:3> , <NUM_LIT:3> ] ) > _EPS ) : <EOL> perspective = numpy . dot ( M [ : , <NUM_LIT:3> ] , numpy . linalg . inv ( P . T ) ) <EOL> M [ : , <NUM_LIT:3> ] = <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:1.0> <EOL> else : <EOL> perspective = numpy . array ( [ <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:1.0> ] ) <EOL> translate = M [ <NUM_LIT:3> , : <NUM_LIT:3> ] . copy ( ) <EOL> M [ <NUM_LIT:3> , : <NUM_LIT:3> ] = <NUM_LIT:0.0> <EOL> row = M [ : <NUM_LIT:3> , : <NUM_LIT:3> ] . copy ( ) <EOL> scale [ <NUM_LIT:0> ] = vector_norm ( row [ <NUM_LIT:0> ] ) <EOL> row [ <NUM_LIT:0> ] /= scale [ <NUM_LIT:0> ] <EOL> shear [ <NUM_LIT:0> ] = numpy . dot ( row [ <NUM_LIT:0> ] , row [ <NUM_LIT:1> ] ) <EOL> row [ <NUM_LIT:1> ] -= row [ <NUM_LIT:0> ] * shear [ <NUM_LIT:0> ] <EOL> scale [ <NUM_LIT:1> ] = vector_norm ( row [ <NUM_LIT:1> ] ) <EOL> row [ <NUM_LIT:1> ] /= scale [ <NUM_LIT:1> ] <EOL> shear [ <NUM_LIT:0> ] /= scale [ <NUM_LIT:1> ] <EOL> shear [ <NUM_LIT:1> ] = numpy . dot ( row [ <NUM_LIT:0> ] , row [ <NUM_LIT:2> ] ) <EOL> row [ <NUM_LIT:2> ] -= row [ <NUM_LIT:0> ] * shear [ <NUM_LIT:1> ] <EOL> shear [ <NUM_LIT:2> ] = numpy . dot ( row [ <NUM_LIT:1> ] , row [ <NUM_LIT:2> ] ) <EOL> row [ <NUM_LIT:2> ] -= row [ <NUM_LIT:1> ] * shear [ <NUM_LIT:2> ] <EOL> scale [ <NUM_LIT:2> ] = vector_norm ( row [ <NUM_LIT:2> ] ) <EOL> row [ <NUM_LIT:2> ] /= scale [ <NUM_LIT:2> ] <EOL> shear [ <NUM_LIT:1> : ] /= scale [ <NUM_LIT:2> ] <EOL> if numpy . dot ( row [ <NUM_LIT:0> ] , numpy . cross ( row [ <NUM_LIT:1> ] , row [ <NUM_LIT:2> ] ) ) < <NUM_LIT:0> : <EOL> numpy . negative ( scale , scale ) <EOL> numpy . negative ( row , row ) <EOL> angles [ <NUM_LIT:1> ] = math . asin ( - row [ <NUM_LIT:0> , <NUM_LIT:2> ] ) <EOL> if math . cos ( angles [ <NUM_LIT:1> ] ) : <EOL> angles [ <NUM_LIT:0> ] = math . atan2 ( row [ <NUM_LIT:1> , <NUM_LIT:2> ] , row [ <NUM_LIT:2> , <NUM_LIT:2> ] ) <EOL> angles [ <NUM_LIT:2> ] = math . atan2 ( row [ <NUM_LIT:0> , <NUM_LIT:1> ] , row [ <NUM_LIT:0> , <NUM_LIT:0> ] ) <EOL> else : <EOL> angles [ <NUM_LIT:0> ] = math . atan2 ( - row [ <NUM_LIT:2> , <NUM_LIT:1> ] , row [ <NUM_LIT:1> , <NUM_LIT:1> ] ) <EOL> angles [ <NUM_LIT:2> ] = <NUM_LIT:0.0> <EOL> return scale , shear , angles , translate , perspective <EOL> def compose_matrix ( scale = None , shear = None , angles = None , translate = None , <EOL> perspective = None ) : <EOL> """<STR_LIT>""" <EOL> M = numpy . identity ( <NUM_LIT:4> ) <EOL> if perspective is not None : <EOL> P = numpy . identity ( <NUM_LIT:4> ) <EOL> P [ <NUM_LIT:3> , : ] = perspective [ : <NUM_LIT:4> ] <EOL> M = numpy . dot ( M , P ) <EOL> if translate is not None : <EOL> T = numpy . identity ( <NUM_LIT:4> ) <EOL> T [ : <NUM_LIT:3> , <NUM_LIT:3> ] = translate [ : <NUM_LIT:3> ] <EOL> M = numpy . dot ( M , T ) <EOL> if angles is not None : <EOL> R = euler_matrix ( angles [ <NUM_LIT:0> ] , angles [ <NUM_LIT:1> ] , angles [ <NUM_LIT:2> ] , '<STR_LIT>' ) <EOL> M = numpy . dot ( M , R ) <EOL> if shear is not None : <EOL> Z = numpy . identity ( <NUM_LIT:4> ) <EOL> Z [ <NUM_LIT:1> , <NUM_LIT:2> ] = shear [ <NUM_LIT:2> ] <EOL> Z [ <NUM_LIT:0> , <NUM_LIT:2> ] = shear [ <NUM_LIT:1> ] <EOL> Z [ <NUM_LIT:0> , <NUM_LIT:1> ] = shear [ <NUM_LIT:0> ] <EOL> M = numpy . dot ( M , Z ) <EOL> if scale is not None : <EOL> S = numpy . identity ( <NUM_LIT:4> ) <EOL> S [ <NUM_LIT:0> , <NUM_LIT:0> ] = scale [ <NUM_LIT:0> ] <EOL> S [ <NUM_LIT:1> , <NUM_LIT:1> ] = scale [ <NUM_LIT:1> ] <EOL> S [ <NUM_LIT:2> , <NUM_LIT:2> ] = scale [ <NUM_LIT:2> ] <EOL> M = numpy . dot ( M , S ) <EOL> M /= M [ <NUM_LIT:3> , <NUM_LIT:3> ] <EOL> return M <EOL> def orthogonalization_matrix ( lengths , angles ) : <EOL> """<STR_LIT>""" <EOL> a , b , c = lengths <EOL> angles = numpy . radians ( angles ) <EOL> sina , sinb , _ = numpy . sin ( angles ) <EOL> cosa , cosb , cosg = numpy . cos ( angles ) <EOL> co = ( cosa * cosb - cosg ) / ( sina * sinb ) <EOL> return numpy . array ( [ <EOL> [ a * sinb * math . sqrt ( <NUM_LIT:1.0> - co * co ) , <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> ] , <EOL> [ - a * sinb * co , b * sina , <NUM_LIT:0.0> , <NUM_LIT:0.0> ] , <EOL> [ a * cosb , b * cosa , c , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:1.0> ] ] ) <EOL> def affine_matrix_from_points ( v0 , v1 , shear = True , scale = True , usesvd = True ) : <EOL> """<STR_LIT>""" <EOL> v0 = numpy . array ( v0 , dtype = numpy . float64 , copy = True ) <EOL> v1 = numpy . array ( v1 , dtype = numpy . float64 , copy = True ) <EOL> ndims = v0 . shape [ <NUM_LIT:0> ] <EOL> if ndims < <NUM_LIT:2> or v0 . shape [ <NUM_LIT:1> ] < ndims or v0 . shape != v1 . shape : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> t0 = - numpy . mean ( v0 , axis = <NUM_LIT:1> ) <EOL> M0 = numpy . identity ( ndims + <NUM_LIT:1> ) <EOL> M0 [ : ndims , ndims ] = t0 <EOL> v0 += t0 . reshape ( ndims , <NUM_LIT:1> ) <EOL> t1 = - numpy . mean ( v1 , axis = <NUM_LIT:1> ) <EOL> M1 = numpy . identity ( ndims + <NUM_LIT:1> ) <EOL> M1 [ : ndims , ndims ] = t1 <EOL> v1 += t1 . reshape ( ndims , <NUM_LIT:1> ) <EOL> if shear : <EOL> A = numpy . concatenate ( ( v0 , v1 ) , axis = <NUM_LIT:0> ) <EOL> u , s , vh = numpy . linalg . svd ( A . T ) <EOL> vh = vh [ : ndims ] . T <EOL> B = vh [ : ndims ] <EOL> C = vh [ ndims : <NUM_LIT:2> * ndims ] <EOL> t = numpy . dot ( C , numpy . linalg . pinv ( B ) ) <EOL> t = numpy . concatenate ( ( t , numpy . zeros ( ( ndims , <NUM_LIT:1> ) ) ) , axis = <NUM_LIT:1> ) <EOL> M = numpy . vstack ( ( t , ( ( <NUM_LIT:0.0> , ) * ndims ) + ( <NUM_LIT:1.0> , ) ) ) <EOL> elif usesvd or ndims != <NUM_LIT:3> : <EOL> u , s , vh = numpy . linalg . svd ( numpy . dot ( v1 , v0 . T ) ) <EOL> R = numpy . dot ( u , vh ) <EOL> if numpy . linalg . det ( R ) < <NUM_LIT:0.0> : <EOL> R -= numpy . outer ( u [ : , ndims - <NUM_LIT:1> ] , vh [ ndims - <NUM_LIT:1> , : ] * <NUM_LIT> ) <EOL> s [ - <NUM_LIT:1> ] *= - <NUM_LIT:1.0> <EOL> M = numpy . identity ( ndims + <NUM_LIT:1> ) <EOL> M [ : ndims , : ndims ] = R <EOL> else : <EOL> xx , yy , zz = numpy . sum ( v0 * v1 , axis = <NUM_LIT:1> ) <EOL> xy , yz , zx = numpy . sum ( v0 * numpy . roll ( v1 , - <NUM_LIT:1> , axis = <NUM_LIT:0> ) , axis = <NUM_LIT:1> ) <EOL> xz , yx , zy = numpy . sum ( v0 * numpy . roll ( v1 , - <NUM_LIT:2> , axis = <NUM_LIT:0> ) , axis = <NUM_LIT:1> ) <EOL> N = [ [ xx + yy + zz , <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> ] , <EOL> [ yz - zy , xx - yy - zz , <NUM_LIT:0.0> , <NUM_LIT:0.0> ] , <EOL> [ zx - xz , xy + yx , yy - xx - zz , <NUM_LIT:0.0> ] , <EOL> [ xy - yx , zx + xz , yz + zy , zz - xx - yy ] ] <EOL> w , V = numpy . linalg . eigh ( N ) <EOL> q = V [ : , numpy . argmax ( w ) ] <EOL> q /= vector_norm ( q ) <EOL> M = quaternion_matrix ( q ) <EOL> if scale and not shear : <EOL> v0 *= v0 <EOL> v1 *= v1 <EOL> M [ : ndims , : ndims ] *= math . sqrt ( numpy . sum ( v1 ) / numpy . sum ( v0 ) ) <EOL> M = numpy . dot ( numpy . linalg . inv ( M1 ) , numpy . dot ( M , M0 ) ) <EOL> M /= M [ ndims , ndims ] <EOL> return M <EOL> def superimposition_matrix ( v0 , v1 , scale = False , usesvd = True ) : <EOL> """<STR_LIT>""" <EOL> v0 = numpy . array ( v0 , dtype = numpy . float64 , copy = False ) [ : <NUM_LIT:3> ] <EOL> v1 = numpy . array ( v1 , dtype = numpy . float64 , copy = False ) [ : <NUM_LIT:3> ] <EOL> return affine_matrix_from_points ( v0 , v1 , shear = False , <EOL> scale = scale , usesvd = usesvd ) <EOL> def euler_matrix ( ai , aj , ak , axes = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> firstaxis , parity , repetition , frame = _AXES2TUPLE [ axes ] <EOL> except ( AttributeError , KeyError ) : <EOL> _TUPLE2AXES [ axes ] <EOL> firstaxis , parity , repetition , frame = axes <EOL> i = firstaxis <EOL> j = _NEXT_AXIS [ i + parity ] <EOL> k = _NEXT_AXIS [ i - parity + <NUM_LIT:1> ] <EOL> if frame : <EOL> ai , ak = ak , ai <EOL> if parity : <EOL> ai , aj , ak = - ai , - aj , - ak <EOL> si , sj , sk = math . sin ( ai ) , math . sin ( aj ) , math . sin ( ak ) <EOL> ci , cj , ck = math . cos ( ai ) , math . cos ( aj ) , math . cos ( ak ) <EOL> cc , cs = ci * ck , ci * sk <EOL> sc , ss = si * ck , si * sk <EOL> M = numpy . identity ( <NUM_LIT:4> ) <EOL> if repetition : <EOL> M [ i , i ] = cj <EOL> M [ i , j ] = sj * si <EOL> M [ i , k ] = sj * ci <EOL> M [ j , i ] = sj * sk <EOL> M [ j , j ] = - cj * ss + cc <EOL> M [ j , k ] = - cj * cs - sc <EOL> M [ k , i ] = - sj * ck <EOL> M [ k , j ] = cj * sc + cs <EOL> M [ k , k ] = cj * cc - ss <EOL> else : <EOL> M [ i , i ] = cj * ck <EOL> M [ i , j ] = sj * sc - cs <EOL> M [ i , k ] = sj * cc + ss <EOL> M [ j , i ] = cj * sk <EOL> M [ j , j ] = sj * ss + cc <EOL> M [ j , k ] = sj * cs - sc <EOL> M [ k , i ] = - sj <EOL> M [ k , j ] = cj * si <EOL> M [ k , k ] = cj * ci <EOL> return M <EOL> def euler_from_matrix ( matrix , axes = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> firstaxis , parity , repetition , frame = _AXES2TUPLE [ axes . lower ( ) ] <EOL> except ( AttributeError , KeyError ) : <EOL> _TUPLE2AXES [ axes ] <EOL> firstaxis , parity , repetition , frame = axes <EOL> i = firstaxis <EOL> j = _NEXT_AXIS [ i + parity ] <EOL> k = _NEXT_AXIS [ i - parity + <NUM_LIT:1> ] <EOL> M = numpy . array ( matrix , dtype = numpy . float64 , copy = False ) [ : <NUM_LIT:3> , : <NUM_LIT:3> ] <EOL> if repetition : <EOL> sy = math . sqrt ( M [ i , j ] * M [ i , j ] + M [ i , k ] * M [ i , k ] ) <EOL> if sy > _EPS : <EOL> ax = math . atan2 ( M [ i , j ] , M [ i , k ] ) <EOL> ay = math . atan2 ( sy , M [ i , i ] ) <EOL> az = math . atan2 ( M [ j , i ] , - M [ k , i ] ) <EOL> else : <EOL> ax = math . atan2 ( - M [ j , k ] , M [ j , j ] ) <EOL> ay = math . atan2 ( sy , M [ i , i ] ) <EOL> az = <NUM_LIT:0.0> <EOL> else : <EOL> cy = math . sqrt ( M [ i , i ] * M [ i , i ] + M [ j , i ] * M [ j , i ] ) <EOL> if cy > _EPS : <EOL> ax = math . atan2 ( M [ k , j ] , M [ k , k ] ) <EOL> ay = math . atan2 ( - M [ k , i ] , cy ) <EOL> az = math . atan2 ( M [ j , i ] , M [ i , i ] ) <EOL> else : <EOL> ax = math . atan2 ( - M [ j , k ] , M [ j , j ] ) <EOL> ay = math . atan2 ( - M [ k , i ] , cy ) <EOL> az = <NUM_LIT:0.0> <EOL> if parity : <EOL> ax , ay , az = - ax , - ay , - az <EOL> if frame : <EOL> ax , az = az , ax <EOL> return ax , ay , az <EOL> def euler_from_quaternion ( quaternion , axes = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> return euler_from_matrix ( quaternion_matrix ( quaternion ) , axes ) <EOL> def quaternion_from_euler ( ai , aj , ak , axes = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> firstaxis , parity , repetition , frame = _AXES2TUPLE [ axes . lower ( ) ] <EOL> except ( AttributeError , KeyError ) : <EOL> _TUPLE2AXES [ axes ] <EOL> firstaxis , parity , repetition , frame = axes <EOL> i = firstaxis + <NUM_LIT:1> <EOL> j = _NEXT_AXIS [ i + parity - <NUM_LIT:1> ] + <NUM_LIT:1> <EOL> k = _NEXT_AXIS [ i - parity ] + <NUM_LIT:1> <EOL> if frame : <EOL> ai , ak = ak , ai <EOL> if parity : <EOL> aj = - aj <EOL> ai /= <NUM_LIT> <EOL> aj /= <NUM_LIT> <EOL> ak /= <NUM_LIT> <EOL> ci = math . cos ( ai ) <EOL> si = math . sin ( ai ) <EOL> cj = math . cos ( aj ) <EOL> sj = math . sin ( aj ) <EOL> ck = math . cos ( ak ) <EOL> sk = math . sin ( ak ) <EOL> cc = ci * ck <EOL> cs = ci * sk <EOL> sc = si * ck <EOL> ss = si * sk <EOL> q = numpy . empty ( ( <NUM_LIT:4> , ) ) <EOL> if repetition : <EOL> q [ <NUM_LIT:0> ] = cj * ( cc - ss ) <EOL> q [ i ] = cj * ( cs + sc ) <EOL> q [ j ] = sj * ( cc + ss ) <EOL> q [ k ] = sj * ( cs - sc ) <EOL> else : <EOL> q [ <NUM_LIT:0> ] = cj * cc + sj * ss <EOL> q [ i ] = cj * sc - sj * cs <EOL> q [ j ] = cj * ss + sj * cc <EOL> q [ k ] = cj * cs - sj * sc <EOL> if parity : <EOL> q [ j ] *= - <NUM_LIT:1.0> <EOL> return q <EOL> def quaternion_about_axis ( angle , axis ) : <EOL> """<STR_LIT>""" <EOL> q = numpy . array ( [ <NUM_LIT:0.0> , axis [ <NUM_LIT:0> ] , axis [ <NUM_LIT:1> ] , axis [ <NUM_LIT:2> ] ] ) <EOL> qlen = vector_norm ( q ) <EOL> if qlen > _EPS : <EOL> q *= math . sin ( angle / <NUM_LIT> ) / qlen <EOL> q [ <NUM_LIT:0> ] = math . cos ( angle / <NUM_LIT> ) <EOL> return q <EOL> def quaternion_matrix ( quaternion ) : <EOL> """<STR_LIT>""" <EOL> q = numpy . array ( quaternion , dtype = numpy . float64 , copy = True ) <EOL> n = numpy . dot ( q , q ) <EOL> if n < _EPS : <EOL> return numpy . identity ( <NUM_LIT:4> ) <EOL> q *= math . sqrt ( <NUM_LIT> / n ) <EOL> q = numpy . outer ( q , q ) <EOL> return numpy . array ( [ <EOL> [ <NUM_LIT:1.0> - q [ <NUM_LIT:2> , <NUM_LIT:2> ] - q [ <NUM_LIT:3> , <NUM_LIT:3> ] , q [ <NUM_LIT:1> , <NUM_LIT:2> ] <EOL> - q [ <NUM_LIT:3> , <NUM_LIT:0> ] , q [ <NUM_LIT:1> , <NUM_LIT:3> ] + q [ <NUM_LIT:2> , <NUM_LIT:0> ] , <NUM_LIT:0.0> ] , <EOL> [ q [ <NUM_LIT:1> , <NUM_LIT:2> ] + q [ <NUM_LIT:3> , <NUM_LIT:0> ] , <NUM_LIT:1.0> - q [ <NUM_LIT:1> , <NUM_LIT:1> ] - q [ <NUM_LIT:3> , <NUM_LIT:3> ] , <EOL> q [ <NUM_LIT:2> , <NUM_LIT:3> ] - q [ <NUM_LIT:1> , <NUM_LIT:0> ] , <NUM_LIT:0.0> ] , <EOL> [ q [ <NUM_LIT:1> , <NUM_LIT:3> ] - q [ <NUM_LIT:2> , <NUM_LIT:0> ] , q [ <NUM_LIT:2> , <NUM_LIT:3> ] + q [ <NUM_LIT:1> , <NUM_LIT:0> ] , <EOL> <NUM_LIT:1.0> - q [ <NUM_LIT:1> , <NUM_LIT:1> ] - q [ <NUM_LIT:2> , <NUM_LIT:2> ] , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:1.0> ] ] ) <EOL> def quaternion_from_matrix ( matrix , isprecise = False ) : <EOL> """<STR_LIT>""" <EOL> M = numpy . array ( matrix , dtype = numpy . float64 , copy = False ) [ : <NUM_LIT:4> , : <NUM_LIT:4> ] <EOL> if isprecise : <EOL> q = numpy . empty ( ( <NUM_LIT:4> , ) ) <EOL> t = numpy . trace ( M ) <EOL> if t > M [ <NUM_LIT:3> , <NUM_LIT:3> ] : <EOL> q [ <NUM_LIT:0> ] = t <EOL> q [ <NUM_LIT:3> ] = M [ <NUM_LIT:1> , <NUM_LIT:0> ] - M [ <NUM_LIT:0> , <NUM_LIT:1> ] <EOL> q [ <NUM_LIT:2> ] = M [ <NUM_LIT:0> , <NUM_LIT:2> ] - M [ <NUM_LIT:2> , <NUM_LIT:0> ] <EOL> q [ <NUM_LIT:1> ] = M [ <NUM_LIT:2> , <NUM_LIT:1> ] - M [ <NUM_LIT:1> , <NUM_LIT:2> ] <EOL> else : <EOL> i , j , k = <NUM_LIT:1> , <NUM_LIT:2> , <NUM_LIT:3> <EOL> if M [ <NUM_LIT:1> , <NUM_LIT:1> ] > M [ <NUM_LIT:0> , <NUM_LIT:0> ] : <EOL> i , j , k = <NUM_LIT:2> , <NUM_LIT:3> , <NUM_LIT:1> <EOL> if M [ <NUM_LIT:2> , <NUM_LIT:2> ] > M [ i , i ] : <EOL> i , j , k = <NUM_LIT:3> , <NUM_LIT:1> , <NUM_LIT:2> <EOL> t = M [ i , i ] - ( M [ j , j ] + M [ k , k ] ) + M [ <NUM_LIT:3> , <NUM_LIT:3> ] <EOL> q [ i ] = t <EOL> q [ j ] = M [ i , j ] + M [ j , i ] <EOL> q [ k ] = M [ k , i ] + M [ i , k ] <EOL> q [ <NUM_LIT:3> ] = M [ k , j ] - M [ j , k ] <EOL> q *= <NUM_LIT:0.5> / math . sqrt ( t * M [ <NUM_LIT:3> , <NUM_LIT:3> ] ) <EOL> else : <EOL> m00 = M [ <NUM_LIT:0> , <NUM_LIT:0> ] <EOL> m01 = M [ <NUM_LIT:0> , <NUM_LIT:1> ] <EOL> m02 = M [ <NUM_LIT:0> , <NUM_LIT:2> ] <EOL> m10 = M [ <NUM_LIT:1> , <NUM_LIT:0> ] <EOL> m11 = M [ <NUM_LIT:1> , <NUM_LIT:1> ] <EOL> m12 = M [ <NUM_LIT:1> , <NUM_LIT:2> ] <EOL> m20 = M [ <NUM_LIT:2> , <NUM_LIT:0> ] <EOL> m21 = M [ <NUM_LIT:2> , <NUM_LIT:1> ] <EOL> m22 = M [ <NUM_LIT:2> , <NUM_LIT:2> ] <EOL> K = numpy . array ( [ [ m00 - m11 - m22 , <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> ] , <EOL> [ m01 + m10 , m11 - m00 - m22 , <NUM_LIT:0.0> , <NUM_LIT:0.0> ] , <EOL> [ m02 + m20 , m12 + m21 , m22 - m00 - m11 , <NUM_LIT:0.0> ] , <EOL> [ m21 - m12 , m02 - m20 , m10 - m01 , m00 + m11 + m22 ] ] ) <EOL> K /= <NUM_LIT> <EOL> w , V = numpy . linalg . eigh ( K ) <EOL> q = V [ [ <NUM_LIT:3> , <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:2> ] , numpy . argmax ( w ) ] <EOL> if q [ <NUM_LIT:0> ] < <NUM_LIT:0.0> : <EOL> numpy . negative ( q , q ) <EOL> return q <EOL> def quaternion_multiply ( quaternion1 , quaternion0 ) : <EOL> """<STR_LIT>""" <EOL> w0 , x0 , y0 , z0 = quaternion0 <EOL> w1 , x1 , y1 , z1 = quaternion1 <EOL> return numpy . array ( [ - x1 * x0 - y1 * y0 - z1 * z0 + w1 * w0 , <EOL> x1 * w0 + y1 * z0 - z1 * y0 + w1 * x0 , <EOL> - x1 * z0 + y1 * w0 + z1 * x0 + w1 * y0 , <EOL> x1 * y0 - y1 * x0 + z1 * w0 + w1 * z0 ] , dtype = numpy . float64 ) <EOL> def quaternion_conjugate ( quaternion ) : <EOL> """<STR_LIT>""" <EOL> q = numpy . array ( quaternion , dtype = numpy . float64 , copy = True ) <EOL> numpy . negative ( q [ <NUM_LIT:1> : ] , q [ <NUM_LIT:1> : ] ) <EOL> return q <EOL> def quaternion_inverse ( quaternion ) : <EOL> """<STR_LIT>""" <EOL> q = numpy . array ( quaternion , dtype = numpy . float64 , copy = True ) <EOL> numpy . negative ( q [ <NUM_LIT:1> : ] , q [ <NUM_LIT:1> : ] ) <EOL> return q / numpy . dot ( q , q ) <EOL> def quaternion_real ( quaternion ) : <EOL> """<STR_LIT>""" <EOL> return float ( quaternion [ <NUM_LIT:0> ] ) <EOL> def quaternion_imag ( quaternion ) : <EOL> """<STR_LIT>""" <EOL> return numpy . array ( quaternion [ <NUM_LIT:1> : <NUM_LIT:4> ] , dtype = numpy . float64 , copy = True ) <EOL> def quaternion_slerp ( quat0 , quat1 , fraction , spin = <NUM_LIT:0> , shortestpath = True ) : <EOL> """<STR_LIT>""" <EOL> q0 = unit_vector ( quat0 [ : <NUM_LIT:4> ] ) <EOL> q1 = unit_vector ( quat1 [ : <NUM_LIT:4> ] ) <EOL> if fraction == <NUM_LIT:0.0> : <EOL> return q0 <EOL> elif fraction == <NUM_LIT:1.0> : <EOL> return q1 <EOL> d = numpy . dot ( q0 , q1 ) <EOL> if abs ( abs ( d ) - <NUM_LIT:1.0> ) < _EPS : <EOL> return q0 <EOL> if shortestpath and d < <NUM_LIT:0.0> : <EOL> d = - d <EOL> numpy . negative ( q1 , q1 ) <EOL> angle = math . acos ( d ) + spin * math . pi <EOL> if abs ( angle ) < _EPS : <EOL> return q0 <EOL> isin = <NUM_LIT:1.0> / math . sin ( angle ) <EOL> q0 *= math . sin ( ( <NUM_LIT:1.0> - fraction ) * angle ) * isin <EOL> q1 *= math . sin ( fraction * angle ) * isin <EOL> q0 += q1 <EOL> return q0 <EOL> def random_quaternion ( rand = None ) : <EOL> """<STR_LIT>""" <EOL> if rand is None : <EOL> rand = numpy . random . rand ( <NUM_LIT:3> ) <EOL> else : <EOL> assert len ( rand ) == <NUM_LIT:3> <EOL> r1 = numpy . sqrt ( <NUM_LIT:1.0> - rand [ <NUM_LIT:0> ] ) <EOL> r2 = numpy . sqrt ( rand [ <NUM_LIT:0> ] ) <EOL> pi2 = math . pi * <NUM_LIT> <EOL> t1 = pi2 * rand [ <NUM_LIT:1> ] <EOL> t2 = pi2 * rand [ <NUM_LIT:2> ] <EOL> return numpy . array ( [ numpy . cos ( t2 ) * r2 , numpy . sin ( t1 ) * r1 , <EOL> numpy . cos ( t1 ) * r1 , numpy . sin ( t2 ) * r2 ] ) <EOL> def random_rotation_matrix ( rand = None ) : <EOL> """<STR_LIT>""" <EOL> return quaternion_matrix ( random_quaternion ( rand ) ) <EOL> class Arcball ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , initial = None ) : <EOL> """<STR_LIT>""" <EOL> self . _axis = None <EOL> self . _axes = None <EOL> self . _radius = <NUM_LIT:1.0> <EOL> self . _center = [ <NUM_LIT:0.0> , <NUM_LIT:0.0> ] <EOL> self . _vdown = numpy . array ( [ <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:1.0> ] ) <EOL> self . _constrain = False <EOL> if initial is None : <EOL> self . _qdown = numpy . array ( [ <NUM_LIT:1.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> ] ) <EOL> else : <EOL> initial = numpy . array ( initial , dtype = numpy . float64 ) <EOL> if initial . shape == ( <NUM_LIT:4> , <NUM_LIT:4> ) : <EOL> self . _qdown = quaternion_from_matrix ( initial ) <EOL> elif initial . shape == ( <NUM_LIT:4> , ) : <EOL> initial /= vector_norm ( initial ) <EOL> self . _qdown = initial <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> self . _qnow = self . _qpre = self . _qdown <EOL> def place ( self , center , radius ) : <EOL> """<STR_LIT>""" <EOL> self . _radius = float ( radius ) <EOL> self . _center [ <NUM_LIT:0> ] = center [ <NUM_LIT:0> ] <EOL> self . _center [ <NUM_LIT:1> ] = center [ <NUM_LIT:1> ] <EOL> def setaxes ( self , * axes ) : <EOL> """<STR_LIT>""" <EOL> if axes is None : <EOL> self . _axes = None <EOL> else : <EOL> self . _axes = [ unit_vector ( axis ) for axis in axes ] <EOL> def setconstrain ( self , constrain ) : <EOL> """<STR_LIT>""" <EOL> self . _constrain = bool ( constrain ) <EOL> def getconstrain ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _constrain <EOL> def down ( self , point ) : <EOL> """<STR_LIT>""" <EOL> self . _vdown = arcball_map_to_sphere ( point , self . _center , self . _radius ) <EOL> self . _qdown = self . _qpre = self . _qnow <EOL> if self . _constrain and self . _axes is not None : <EOL> self . _axis = arcball_nearest_axis ( self . _vdown , self . _axes ) <EOL> self . _vdown = arcball_constrain_to_axis ( self . _vdown , self . _axis ) <EOL> else : <EOL> self . _axis = None <EOL> def drag ( self , point ) : <EOL> """<STR_LIT>""" <EOL> vnow = arcball_map_to_sphere ( point , self . _center , self . _radius ) <EOL> if self . _axis is not None : <EOL> vnow = arcball_constrain_to_axis ( vnow , self . _axis ) <EOL> self . _qpre = self . _qnow <EOL> t = numpy . cross ( self . _vdown , vnow ) <EOL> if numpy . dot ( t , t ) < _EPS : <EOL> self . _qnow = self . _qdown <EOL> else : <EOL> q = [ numpy . dot ( self . _vdown , vnow ) , t [ <NUM_LIT:0> ] , t [ <NUM_LIT:1> ] , t [ <NUM_LIT:2> ] ] <EOL> self . _qnow = quaternion_multiply ( q , self . _qdown ) <EOL> def next ( self , acceleration = <NUM_LIT:0.0> ) : <EOL> """<STR_LIT>""" <EOL> q = quaternion_slerp ( self . _qpre , self . _qnow , <NUM_LIT> + acceleration , False ) <EOL> self . _qpre , self . _qnow = self . _qnow , q <EOL> def matrix ( self ) : <EOL> """<STR_LIT>""" <EOL> return quaternion_matrix ( self . _qnow ) <EOL> def arcball_map_to_sphere ( point , center , radius ) : <EOL> """<STR_LIT>""" <EOL> v0 = ( point [ <NUM_LIT:0> ] - center [ <NUM_LIT:0> ] ) / radius <EOL> v1 = ( center [ <NUM_LIT:1> ] - point [ <NUM_LIT:1> ] ) / radius <EOL> n = v0 * v0 + v1 * v1 <EOL> if n > <NUM_LIT:1.0> : <EOL> n = math . sqrt ( n ) <EOL> return numpy . array ( [ v0 / n , v1 / n , <NUM_LIT:0.0> ] ) <EOL> else : <EOL> return numpy . array ( [ v0 , v1 , math . sqrt ( <NUM_LIT:1.0> - n ) ] ) <EOL> def arcball_constrain_to_axis ( point , axis ) : <EOL> """<STR_LIT>""" <EOL> v = numpy . array ( point , dtype = numpy . float64 , copy = True ) <EOL> a = numpy . array ( axis , dtype = numpy . float64 , copy = True ) <EOL> v -= a * numpy . dot ( a , v ) <EOL> n = vector_norm ( v ) <EOL> if n > _EPS : <EOL> if v [ <NUM_LIT:2> ] < <NUM_LIT:0.0> : <EOL> numpy . negative ( v , v ) <EOL> v /= n <EOL> return v <EOL> if a [ <NUM_LIT:2> ] == <NUM_LIT:1.0> : <EOL> return numpy . array ( [ <NUM_LIT:1.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> ] ) <EOL> return unit_vector ( [ - a [ <NUM_LIT:1> ] , a [ <NUM_LIT:0> ] , <NUM_LIT:0.0> ] ) <EOL> def arcball_nearest_axis ( point , axes ) : <EOL> """<STR_LIT>""" <EOL> point = numpy . array ( point , dtype = numpy . float64 , copy = False ) <EOL> nearest = None <EOL> mx = - <NUM_LIT:1.0> <EOL> for axis in axes : <EOL> t = numpy . dot ( arcball_constrain_to_axis ( point , axis ) , point ) <EOL> if t > mx : <EOL> nearest = axis <EOL> mx = t <EOL> return nearest <EOL> _EPS = numpy . finfo ( float ) . eps * <NUM_LIT> <EOL> _NEXT_AXIS = [ <NUM_LIT:1> , <NUM_LIT:2> , <NUM_LIT:0> , <NUM_LIT:1> ] <EOL> _AXES2TUPLE = { <EOL> '<STR_LIT>' : ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) , '<STR_LIT>' : ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:0> ) , '<STR_LIT>' : ( <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:0> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:0> ) , '<STR_LIT>' : ( <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) , '<STR_LIT>' : ( <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:0> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:0> ) , '<STR_LIT>' : ( <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:0> ) , '<STR_LIT>' : ( <NUM_LIT:2> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:2> , <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:0> ) , '<STR_LIT>' : ( <NUM_LIT:2> , <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:0> ) , '<STR_LIT>' : ( <NUM_LIT:2> , <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:0> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:1> ) , '<STR_LIT>' : ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:1> ) , '<STR_LIT>' : ( <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:1> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:1> ) , '<STR_LIT>' : ( <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:1> ) , '<STR_LIT>' : ( <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:1> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:1> ) , '<STR_LIT>' : ( <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:1> ) , '<STR_LIT>' : ( <NUM_LIT:2> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:1> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:2> , <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:1> ) , '<STR_LIT>' : ( <NUM_LIT:2> , <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:1> ) , '<STR_LIT>' : ( <NUM_LIT:2> , <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:1> ) } <EOL> _TUPLE2AXES = dict ( ( v , k ) for k , v in _AXES2TUPLE . items ( ) ) <EOL> def vector_norm ( data , axis = None , out = None ) : <EOL> """<STR_LIT>""" <EOL> data = numpy . array ( data , dtype = numpy . float64 , copy = True ) <EOL> if out is None : <EOL> if data . ndim == <NUM_LIT:1> : <EOL> return math . sqrt ( numpy . dot ( data , data ) ) <EOL> data *= data <EOL> out = numpy . atleast_1d ( numpy . sum ( data , axis = axis ) ) <EOL> numpy . sqrt ( out , out ) <EOL> return out <EOL> else : <EOL> data *= data <EOL> numpy . sum ( data , axis = axis , out = out ) <EOL> numpy . sqrt ( out , out ) <EOL> def unit_vector ( data , axis = None , out = None ) : <EOL> """<STR_LIT>""" <EOL> if out is None : <EOL> data = numpy . array ( data , dtype = numpy . float64 , copy = True ) <EOL> if data . ndim == <NUM_LIT:1> : <EOL> data /= math . sqrt ( numpy . dot ( data , data ) ) <EOL> return data <EOL> else : <EOL> if out is not data : <EOL> out [ : ] = numpy . array ( data , copy = False ) <EOL> data = out <EOL> length = numpy . atleast_1d ( numpy . sum ( data * data , axis ) ) <EOL> numpy . sqrt ( length , length ) <EOL> if axis is not None : <EOL> length = numpy . expand_dims ( length , axis ) <EOL> data /= length <EOL> if out is None : <EOL> return data <EOL> def random_vector ( size ) : <EOL> """<STR_LIT>""" <EOL> return numpy . random . random ( size ) <EOL> def vector_product ( v0 , v1 , axis = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> return numpy . cross ( v0 , v1 , axis = axis ) <EOL> def angle_between_vectors ( v0 , v1 , directed = True , axis = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> v0 = numpy . array ( v0 , dtype = numpy . float64 , copy = False ) <EOL> v1 = numpy . array ( v1 , dtype = numpy . float64 , copy = False ) <EOL> dot = numpy . sum ( v0 * v1 , axis = axis ) <EOL> dot /= vector_norm ( v0 , axis = axis ) * vector_norm ( v1 , axis = axis ) <EOL> return numpy . arccos ( dot if directed else numpy . fabs ( dot ) ) <EOL> def inverse_matrix ( matrix ) : <EOL> """<STR_LIT>""" <EOL> return numpy . linalg . inv ( matrix ) <EOL> def concatenate_matrices ( * matrices ) : <EOL> """<STR_LIT>""" <EOL> M = numpy . identity ( <NUM_LIT:4> ) <EOL> for i in matrices : <EOL> M = numpy . dot ( M , i ) <EOL> return M <EOL> def is_same_transform ( matrix0 , matrix1 ) : <EOL> """<STR_LIT>""" <EOL> matrix0 = numpy . array ( matrix0 , dtype = numpy . float64 , copy = True ) <EOL> matrix0 /= matrix0 [ <NUM_LIT:3> , <NUM_LIT:3> ] <EOL> matrix1 = numpy . array ( matrix1 , dtype = numpy . float64 , copy = True ) <EOL> matrix1 /= matrix1 [ <NUM_LIT:3> , <NUM_LIT:3> ] <EOL> return numpy . allclose ( matrix0 , matrix1 ) <EOL> def _import_module ( name , package = None , warn = True , prefix = '<STR_LIT>' , ignore = '<STR_LIT:_>' ) : <EOL> """<STR_LIT>""" <EOL> import warnings <EOL> from importlib import import_module <EOL> try : <EOL> if not package : <EOL> module = import_module ( name ) <EOL> else : <EOL> module = import_module ( '<STR_LIT:.>' + name , package = package ) <EOL> except ImportError : <EOL> if warn : <EOL> warnings . warn ( "<STR_LIT>" % name ) <EOL> else : <EOL> for attr in dir ( module ) : <EOL> if ignore and attr . startswith ( ignore ) : <EOL> continue <EOL> if prefix : <EOL> if attr in globals ( ) : <EOL> globals ( ) [ prefix + attr ] = globals ( ) [ attr ] <EOL> elif warn : <EOL> warnings . warn ( "<STR_LIT>" + attr ) <EOL> globals ( ) [ attr ] = getattr ( module , attr ) <EOL> return True <EOL> import sys <EOL> req_version = ( <NUM_LIT:2> , <NUM_LIT:7> ) <EOL> cur_version = sys . version_info <EOL> if cur_version >= req_version : <EOL> _import_module ( '<STR_LIT>' , package = "<STR_LIT>" ) <EOL> if __name__ == "<STR_LIT:__main__>" : <EOL> import doctest <EOL> import random <EOL> numpy . set_printoptions ( suppress = True , precision = <NUM_LIT:5> ) <EOL> doctest . testmod ( ) </s>
