draft implementation of arbitrary PDF
[sympy.git] / sympy / plotting / plot_controller.py
blobb7220ea729ae0cdc15129d48e58cface7c5b9089
1 from pyglet.window import key
2 from pyglet.window.mouse import LEFT, RIGHT, MIDDLE
3 from util import get_direction_vectors, get_basis_vectors
5 class PlotController(object):
7 normal_mouse_sensitivity = 4.0
8 modified_mouse_sensitivity = 1.0
10 normal_key_sensitivity = 160.0
11 modified_key_sensitivity = 40.0
13 keymap = {
14 key.LEFT:'left',
15 key.A:'left',
16 key.NUM_4:'left',
18 key.RIGHT:'right',
19 key.D:'right',
20 key.NUM_6:'right',
22 key.UP:'up',
23 key.W:'up',
24 key.NUM_8:'up',
26 key.DOWN:'down',
27 key.S:'down',
28 key.NUM_2:'down',
30 key.Z:'rotate_z_neg',
31 key.NUM_1:'rotate_z_neg',
33 key.C:'rotate_z_pos',
34 key.NUM_3:'rotate_z_pos',
36 key.Q:'spin_left',
37 key.NUM_7:'spin_left',
38 key.E:'spin_right',
39 key.NUM_9:'spin_right',
41 key.X:'reset_camera',
42 key.NUM_5:'reset_camera',
44 key.NUM_ADD:'zoom_in',
45 key.PAGEUP:'zoom_in',
46 key.R:'zoom_in',
48 key.NUM_SUBTRACT:'zoom_out',
49 key.PAGEDOWN:'zoom_out',
50 key.F:'zoom_out',
52 key.RSHIFT:'modify_sensitivity',
53 key.LSHIFT:'modify_sensitivity',
55 key.F1:'rot_preset_xy',
56 key.F2:'rot_preset_xz',
57 key.F3:'rot_preset_yz',
58 key.F4:'rot_preset_perspective',
60 key.F5:'toggle_axes',
61 key.F6:'toggle_axe_colors',
63 key.F8:'save_image'
66 def __init__(self, window, **kwargs):
67 self.invert_mouse_zoom = kwargs.pop('invert_mouse_zoom', False)
68 self.window = window
69 self.camera = window.camera
70 self.action = {
71 # Rotation around the view Y (up) vector
72 'left':False,
73 'right':False,
74 # Rotation around the view X vector
75 'up':False,
76 'down':False,
77 # Rotation around the view Z vector
78 'spin_left':False,
79 'spin_right':False,
80 # Rotation around the model Z vector
81 'rotate_z_neg':False,
82 'rotate_z_pos':False,
83 # Reset to the default rotation
84 'reset_camera':False,
85 # Performs camera z-translation
86 'zoom_in':False,
87 'zoom_out':False,
88 # Use alternative sensitivity (speed)
89 'modify_sensitivity':False,
90 # Rotation presets
91 'rot_preset_xy':False,
92 'rot_preset_xz':False,
93 'rot_preset_yz':False,
94 'rot_preset_perspective':False,
95 # axes
96 'toggle_axes':False,
97 'toggle_axe_colors':False,
98 # screenshot
99 'save_image':False
102 def update(self, dt):
103 z = 0
104 if self.action['zoom_out']: z -= 1
105 if self.action['zoom_in']: z += 1
106 if z != 0:
107 self.camera.zoom_relative(z/10.0, self.get_key_sensitivity()/10.0)
109 dx, dy, dz = 0, 0, 0
110 if self.action['left']: dx -= 1
111 if self.action['right']: dx += 1
112 if self.action['up']: dy -= 1
113 if self.action['down']: dy += 1
114 if self.action['spin_left']: dz += 1
115 if self.action['spin_right']: dz -= 1
117 if not self.is_2D():
118 if dx != 0:
119 self.camera.euler_rotate(dx*dt*self.get_key_sensitivity(), *(get_direction_vectors()[1]))
120 if dy != 0:
121 self.camera.euler_rotate(dy*dt*self.get_key_sensitivity(), *(get_direction_vectors()[0]))
122 if dz != 0:
123 self.camera.euler_rotate(dz*dt*self.get_key_sensitivity(), *(get_direction_vectors()[2]))
124 else:
125 self.camera.mouse_translate(0, 0, dx*dt*self.get_key_sensitivity(), -dy*dt*self.get_key_sensitivity())
127 rz = 0
128 if self.action['rotate_z_neg'] and not self.is_2D(): rz -= 1
129 if self.action['rotate_z_pos'] and not self.is_2D(): rz += 1
131 if rz != 0:
132 self.camera.euler_rotate(rz*dt*self.get_key_sensitivity(), *(get_basis_vectors()[2]))
134 if self.action['reset_camera']:
135 self.camera.reset()
137 if self.action['rot_preset_xy']:
138 self.camera.set_rot_preset('xy')
139 if self.action['rot_preset_xz']:
140 self.camera.set_rot_preset('xz')
141 if self.action['rot_preset_yz']:
142 self.camera.set_rot_preset('yz')
143 if self.action['rot_preset_perspective']:
144 self.camera.set_rot_preset('perspective')
146 if self.action['toggle_axes']:
147 self.action['toggle_axes'] = False
148 self.camera.axes.toggle_visible()
150 if self.action['toggle_axe_colors']:
151 self.action['toggle_axe_colors'] = False
152 self.camera.axes.toggle_colors()
154 if self.action['save_image']:
155 self.action['save_image'] = False
156 self.window.plot.saveimage()
158 return True
160 def get_mouse_sensitivity(self):
161 if self.action['modify_sensitivity']:
162 return self.modified_mouse_sensitivity
163 else:
164 return self.normal_mouse_sensitivity
166 def get_key_sensitivity(self):
167 if self.action['modify_sensitivity']:
168 return self.modified_key_sensitivity
169 else:
170 return self.normal_key_sensitivity
172 def on_key_press(self, symbol, modifiers):
173 if symbol in self.keymap:
174 self.action[self.keymap[symbol]] = True
176 def on_key_release(self, symbol, modifiers):
177 if symbol in self.keymap:
178 self.action[self.keymap[symbol]] = False
180 def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
181 if buttons & LEFT:
182 if self.is_2D():
183 self.camera.mouse_translate(x, y, dx, dy)
184 else:
185 self.camera.spherical_rotate((x-dx,y-dy),(x,y), self.get_mouse_sensitivity())
186 if buttons & MIDDLE:
187 self.camera.zoom_relative([1,-1][self.invert_mouse_zoom]*dy, self.get_mouse_sensitivity()/20.0)
188 if buttons & RIGHT:
189 self.camera.mouse_translate(x, y, dx, dy)
191 def on_mouse_scroll(self, x, y, dx, dy):
192 self.camera.zoom_relative([1,-1][self.invert_mouse_zoom]*dy, self.get_mouse_sensitivity())
194 def is_2D(self):
195 functions = self.window.plot._functions
196 for i in functions:
197 if len(functions[i].i_vars)>1 or len(functions[i].d_vars)>2:
198 return False
199 return True