|
| 1 | +importnumpyasnp |
| 2 | +importmatplotlib.transformsasmtransforms |
| 3 | + |
| 4 | + |
| 5 | +classNonAffine3D(mtransforms.Transform): |
| 6 | +input_dims=output_dims=3 |
| 7 | +is_affine=False |
| 8 | + |
| 9 | +def__init__(self,*args,matrix=None,**kwargs): |
| 10 | +super().__init__(*args,**kwargs) |
| 11 | +ifmatrixisNone: |
| 12 | +matrix=np.identity(4) |
| 13 | +self._mtx=matrix.copy() |
| 14 | +self._invalid=0 |
| 15 | + |
| 16 | +deftransform_non_affine(self,values): |
| 17 | +mtx=self.get_matrix() |
| 18 | + |
| 19 | +ifisinstance(values,np.ma.MaskedArray): |
| 20 | +tpoints=mtransforms.matrix_transform(values.data,mtx) |
| 21 | +returnnp.ma.MaskedArray(tpoints,mask=np.ma.getmask(values)) |
| 22 | +returnmtransforms.matrix_transform(values,mtx) |
| 23 | + |
| 24 | +definverted(self): |
| 25 | +returnNonAffine3D(matrix=np.linalg.inv(self._mtx)) |
| 26 | + |
| 27 | + |
| 28 | +classWorldTransform(mtransforms.Affine3D): |
| 29 | +def__init__(self,xmin,xmax,ymin,ymax,zmin,zmax,pb_aspect=None): |
| 30 | +dx=xmax-xmin |
| 31 | +dy=ymax-ymin |
| 32 | +dz=zmax-zmin |
| 33 | +ifpb_aspectisnotNone: |
| 34 | +ax,ay,az=pb_aspect |
| 35 | +dx/=ax |
| 36 | +dy/=ay |
| 37 | +dz/=az |
| 38 | +mtx=np.array([ |
| 39 | + [1/dx,0,0,-xmin/dx], |
| 40 | + [0,1/dy,0,-ymin/dy], |
| 41 | + [0,0,1/dz,-zmin/dz], |
| 42 | + [0,0,0,1] |
| 43 | + ]) |
| 44 | +super().__init__(matrix=mtx) |
| 45 | + |
| 46 | + |
| 47 | +classPerspectiveTransform(NonAffine3D): |
| 48 | +def__init__(self,zfront,zback,focal_length): |
| 49 | +e=focal_length |
| 50 | +a=1 |
| 51 | +b= (zfront+zback)/ (zfront-zback) |
| 52 | +c=-2* (zfront*zback)/ (zfront-zback) |
| 53 | +mtx=np.array([[e,0,0,0], |
| 54 | + [0,e/a,0,0], |
| 55 | + [0,0,b,c], |
| 56 | + [0,0,-1,0]]) |
| 57 | +super().__init__(matrix=mtx) |
| 58 | + |
| 59 | + |
| 60 | +classOrthographicTransform(NonAffine3D): |
| 61 | +def__init__(self,zfront,zback): |
| 62 | +a=-(zfront+zback) |
| 63 | +b=-(zfront-zback) |
| 64 | +mtx=np.array([[2,0,0,0], |
| 65 | + [0,2,0,0], |
| 66 | + [0,0,-2,0], |
| 67 | + [0,0,a,b]]) |
| 68 | +super().__init__(matrix=mtx) |
| 69 | + |
| 70 | + |
| 71 | +classViewTransform(mtransforms.Affine3D): |
| 72 | +def__init__(self,u,v,w,E): |
| 73 | +""" |
| 74 | + Return the view transformation matrix. |
| 75 | +
|
| 76 | + Parameters |
| 77 | + ---------- |
| 78 | + u : 3-element numpy array |
| 79 | + Unit vector pointing towards the right of the screen. |
| 80 | + v : 3-element numpy array |
| 81 | + Unit vector pointing towards the top of the screen. |
| 82 | + w : 3-element numpy array |
| 83 | + Unit vector pointing out of the screen. |
| 84 | + E : 3-element numpy array |
| 85 | + The coordinates of the eye/camera. |
| 86 | + """ |
| 87 | +self._u=u |
| 88 | +self._v=v |
| 89 | +self._w=w |
| 90 | + |
| 91 | +Mr=np.eye(4) |
| 92 | +Mt=np.eye(4) |
| 93 | +Mr[:3, :3]= [u,v,w] |
| 94 | +Mt[:3,-1]=-E |
| 95 | +mtx=np.dot(Mr,Mt) |
| 96 | +super().__init__(matrix=mtx) |