def camera_from_quat(pos_nm, orient_quat, camera_distance=10000, ngl_correct=True): """define a vtk camera with a particular orientation Parameters ---------- pos_nm: np.array, list, tuple an iterator of length 3 containing the focus point of the camera orient_quat: np.array, list, tuple a len(4) quatenerion (x,y,z,w) describing the rotation of the camera such as returned by neuroglancer x,y,z,w all in [0,1] range camera_distance: float the desired distance from pos_nm to the camera (default = 10000 nm) Returns ------- vtk.vtkCamera a vtk camera setup according to these rules """ camera = vtk.vtkCamera() # define the quaternion in vtk, note the swapped order # w,x,y,z instead of x,y,z,w quat_vtk = vtk.vtkQuaterniond(orient_quat[3], orient_quat[0], orient_quat[1], orient_quat[2]) # use this to define a rotation matrix in x,y,z # right handed units M = np.zeros((3, 3), dtype=np.float32) quat_vtk.ToMatrix3x3(M) # the default camera orientation is y up up = [0, 1, 0] # calculate default camera position is backed off in positive z pos = [0, 0, camera_distance] # set the camera rototation by applying the rotation matrix camera.SetViewUp(*np.dot(M, up)) # set the camera position by applying the rotation matrix camera.SetPosition(*np.dot(M, pos)) if ngl_correct: # neuroglancer has positive y going down # so apply these azimuth and roll corrections # to fix orientatins camera.Azimuth(-180) camera.Roll(180) # shift the camera posiiton and focal position # to be centered on the desired location p = camera.GetPosition() p_new = np.array(p) + pos_nm camera.SetPosition(*p_new) camera.SetFocalPoint(*pos_nm) return camera
def MyFunc(obj, ev): global lastNormal global lastAxis1 global axes saxis = np.array(obj.GetPoint1()) - np.array(obj.GetOrigin()) axis = np.array(obj.GetNormal()) vec = vtk.vtkVector3d() # Axis of rotation vtk.vtkMath.Cross(lastNormal, axis, vec) costheta = vtk.vtkMath.Dot(axis, lastNormal) sintheta = vtk.vtkMath.Norm(vec) theta = np.arctan2(sintheta, costheta) if sintheta != 0.0: vec[0] = vec[0] / sintheta vec[1] = vec[1] / sintheta vec[2] = vec[2] / sintheta # Convert to Quaternion costheta = np.cos(0.5 * theta) sintheta = np.sin(0.5 * theta) quat0 = vtk.vtkQuaterniond(costheta, vec[0] * sintheta, vec[1] * sintheta, vec[2] * sintheta) rot0 = np.ones((3, 3), dtype=np.float) vtk.vtkMath.QuaternionToMatrix3x3(quat0, rot0) if 1: newAxis1 = vtk.vtkVector3d() vtk.vtkMath.Multiply3x3(rot0, lastAxis1, newAxis1) # Rotate newAxis1 into saxis vec = vtk.vtkVector3d() # Axis of rotation vtk.vtkMath.Cross(newAxis1, saxis, vec) costheta = vtk.vtkMath.Dot(saxis, newAxis1) sintheta = vtk.vtkMath.Norm(vec) theta = np.arctan2(sintheta, costheta) if sintheta != 0.0: vec[0] = vec[0] / sintheta vec[1] = vec[1] / sintheta vec[2] = vec[2] / sintheta # Convert to Quaternion costheta = np.cos(0.5 * theta) sintheta = np.sin(0.5 * theta) quat1 = vtk.vtkQuaterniond(costheta, vec[0] * sintheta, vec[1] * sintheta, vec[2] * sintheta) rot1 = np.ones((3, 3), dtype=np.float) vtk.vtkMath.QuaternionToMatrix3x3(quat1, rot1) # Concatenate rotations rot = np.dot(rot1, rot0) # Rotate rot1 * rot0 (0, ix, jy, kz) rot0^-1 rot1^-1 = rot1*rot0 (0,x,y,z) (rot1*rot0)^-1 #rot2 = np.ones((3,3),dtype=np.float) #quat2 = vtk.vtkQuaterniond() #vtk.vtkMath.MultiplyQuaternion(quat1, quat0, quat2) #vtk.vtkMath.QuaternionToMatrix3x3(quat2, rot2) mat = np.zeros((4, 4), dtype=np.float) mat[:3, :3] = rot mat[3, 3] = 1.0 tmp = vtk.vtkVector3d() vtk.vtkMath.Multiply3x3(rot, axes.GetOrigin(), tmp) mat[:3, 3] = np.array(obj.GetCenter()) - np.array(tmp) # Construct 4x4 matrix trans = vtk.vtkMatrix4x4() trans.DeepCopy(mat.flatten().tolist()) if axes.GetUserTransform() is not None: axes.GetUserTransform().Concatenate(trans) else: transform = vtk.vtkTransform() transform.SetMatrix(trans) transform.PostMultiply() axes.SetUserTransform(transform) # Only for book keeping axes.SetOrigin(obj.GetCenter()) # Not modified by SetUserTransform axes.Modified() # Update last axes lastAxis1[0] = saxis[0] lastAxis1[1] = saxis[1] lastAxis1[2] = saxis[2] lastNormal = (axis[0], axis[1], axis[2])
def AxesToTransform(normal0, first0, origin0, normal1, first1, origin1): """ Generate homegenous transform transforming origin and positive orientation defined by (normal0, first0, origin0) into (normal1, first1, origin1) """ vec = vtk.vtkVector3d() # Axis of rotation vtk.vtkMath.Cross(normal0, normal1, vec) costheta = vtk.vtkMath.Dot(normal1, normal0) sintheta = vtk.vtkMath.Norm(vec) theta = np.arctan2(sintheta, costheta) if sintheta != 0.0: vec[0] = vec[0] / sintheta vec[1] = vec[1] / sintheta vec[2] = vec[2] / sintheta # Convert to Quaternion costheta = np.cos(0.5 * theta) sintheta = np.sin(0.5 * theta) quat0 = vtk.vtkQuaterniond(costheta, vec[0] * sintheta, vec[1] * sintheta, vec[2] * sintheta) newFirst = vtk.vtkVector3d() rot0 = np.ones((3, 3), dtype=np.float) vtk.vtkMath.QuaternionToMatrix3x3(quat0, rot0) if 1: # Can be performed using quaternions vtk.vtkMath.Multiply3x3(rot0, first0, newFirst) else: # Quaternion equivalent of the above line quatAxis0 = vtk.vtkQuaterniond(0.0, first0[0], first0[1], first0[2]) quatAxisTmp = vtk.vtkQuaterniond() quatAxis1 = vtk.vtkQuaterniond() vtk.vtkMath.MultiplyQuaternion(quat0, quatAxis0, quatAxisTmp) vtk.vtkMath.MultiplyQuaternion(quatAxisTmp, quat0.Inverse(), quatAxis1) newFirst[0] = quatAxis1[1] newFirst[1] = quatAxis1[2] newFirst[2] = quatAxis1[3] # Rotate newFirst into first1 vec = vtk.vtkVector3d() # Axis of rotation vtk.vtkMath.Cross(newFirst, first1, vec) costheta = vtk.vtkMath.Dot(first1, newFirst) sintheta = vtk.vtkMath.Norm(vec) theta = np.arctan2(sintheta, costheta) if sintheta != 0.0: vec[0] = vec[0] / sintheta vec[1] = vec[1] / sintheta vec[2] = vec[2] / sintheta # Convert to Quaternion costheta = np.cos(0.5 * theta) sintheta = np.sin(0.5 * theta) quat1 = vtk.vtkQuaterniond(costheta, vec[0] * sintheta, vec[1] * sintheta, vec[2] * sintheta) if 0: rot1 = np.ones((3, 3), dtype=np.float) vtk.vtkMath.QuaternionToMatrix3x3(quat1, rot1) rot = np.dot(rot1, rot0) else: # Quaternion equivalent of the above rot = np.ones((3, 3), dtype=np.float) quat2 = vtk.vtkQuaterniond() vtk.vtkMath.MultiplyQuaternion(quat1, quat0, quat2) vtk.vtkMath.QuaternionToMatrix3x3(quat2, rot) # Rotation mat = np.zeros((4, 4), dtype=np.float) mat[:3, :3] = rot mat[3, 3] = 1.0 # Translation tmp = vtk.vtkVector3d() vtk.vtkMath.Multiply3x3(rot, origin0, tmp) mat[:3, 3] = np.array(origin1) - np.array(tmp) # Construct 4x4 matrix trans = vtk.vtkMatrix4x4() trans.DeepCopy(mat.flatten().tolist()) return trans
ren.SetActiveCamera(camera) self.renWin.Render() self.iniOk = True def __init__(self): self.iniOk = False def __del__(self): self.renWin.Finalize() if __name__ == "__main__": # create quaternion # rotation origin theta = math.pi * -0.5 # x y z coodinates of the rotation vector rot_ax = math.sin(theta / 2) * np.array([1.0, 1.0, .0]) qtr_arr = np.insert(rot_ax, 0, math.cos(theta / 2), axis=0) # qtr_arr = [1.0, 0.0, 0.0, 0.0] # unity quat # print qtr_arr qtr = vtk.vtkQuaterniond(qtr_arr) #print qtr.Normalized() scene = vtpDrawScene() scene.initScene() scene.SetQuatOrientation(qtr) raw_input("Press Enter to exit") del scene