@@ -15,6 +15,14 @@ def __init__(self, physical_state_to_draw, texture_path=None):
1515 # Note that this might actually start an HTTP server!
1616 import vpython
1717 self ._vpython = vpython
18+ assert len (physical_state_to_draw .entities ) >= 1
19+ try :
20+ self ._origin = [entity
21+ for entity in physical_state_to_draw .entities
22+ if entity .name == 'Habitat' ][0 ]
23+ except IndexError :
24+ # Couldn't find the Habitat, default to the first entity
25+ self ._origin = physical_state_to_draw .entities [0 ]
1826 self ._scene = vpython .canvas (
1927 title = '<b>OrbitX\n </b>' ,
2028 align = 'right' ,
@@ -24,7 +32,7 @@ def __init__(self, physical_state_to_draw, texture_path=None):
2432 autoscale = True
2533 )
2634
27- self .show_label = True
35+ self ._show_label = True
2836 self .pause = False
2937 self .pause_label = vpython .label (
3038 text = "Simulation Paused." , visible = False )
@@ -40,24 +48,28 @@ def __init__(self, physical_state_to_draw, texture_path=None):
4048 if texture_path is None :
4149 # If we're in src/ look for src/../textures/
4250 self ._texture_path = Path ('data' , 'textures' )
43- #stars = str(self._texture_path / 'Stars.jpg')
44- #vpython.sphere(radius=9999999999999, texture=stars)
51+ # stars = str(self._texture_path / 'Stars.jpg')
52+ # vpython.sphere(radius=9999999999999, texture=stars)
4553
4654 for planet in physical_state_to_draw .entities :
4755 self ._spheres [planet .name ] = self ._draw_sphere (planet )
4856 self ._labels [planet .name ] = self ._draw_labels (planet )
49- if planet .name == 'Sun' : # The sun is special!
57+ if planet .name == 'Habitat' :
58+ self ._habitat_arrow = self ._draw_habitat_arrow (planet )
5059 self ._scene .camera .follow (
51- self ._spheres [planet .name ]) # thanks Copernicus
52- self ._spheres [planet .name ].emissive = True # The sun glows!
53- self ._scene .lights = []
54- self ._lights = [self ._vpython .local_light (
55- pos = self ._vpython .vector (planet .x , planet .y , 0 )
56- )]
60+ self ._spheres [planet .name ])
5761 self ._scene .autoscale = False
5862
63+ self .recentre_camera ("Habitat" )
64+
65+ def _posn (self , entity ):
66+ return self ._vpython .vector (
67+ entity .x - self ._origin .x ,
68+ entity .y - self ._origin .y ,
69+ 0 )
70+
5971 def _show_hide_label (self ):
60- if self .show_label :
72+ if self ._show_label :
6173 for key , label in self ._labels .items ():
6274 label .visible = True
6375 else :
@@ -66,10 +78,10 @@ def _show_hide_label(self):
6678
6779 def _handle_keydown (self , evt ):
6880 """Input key handler"""
69- #global show_label , pause
81+ # global _show_label , pause
7082 k = evt .key
7183 if (k == 'l' ):
72- self .show_label = not self .show_label
84+ self ._show_label = not self ._show_label
7385 self ._show_hide_label ()
7486 elif (k == 'p' ):
7587 self .pause = not self .pause
@@ -88,7 +100,7 @@ def _handle_click(self, evt):
88100 # global obj, clicked
89101 try :
90102 obj = self ._scene .mouse .pick
91- if obj != None :
103+ if obj is not None :
92104 self .update_caption (obj )
93105
94106 except AttributeError :
@@ -103,12 +115,6 @@ def _get_objname(self, obj):
103115 obj_name = k
104116 return obj_name
105117
106- def _update_center (self , m ):
107- """Change camera to focus on different object"""
108- value = m .selected
109- print (value )
110- self ._scene .center = self ._spheres [value ].pos
111-
112118 # TODO: 1)Update with correct physics values
113119 def _set_caption (self ):
114120 """Set and update the captions"""
@@ -131,74 +137,121 @@ def _set_menus(self):
131137
132138 self ._scene .append_to_caption (
133139 "<b>Center: </b>" )
134- center = self ._vpython .menu (choices = ['Sun' , 'Mercury' , 'Venus' , 'Earth' , 'Mars' , 'Jupiter' , 'Saturn' , 'Uranus' , 'Neptune' , 'Pluto' ],
140+ center = self ._vpython .menu (choices = ['Sun' , 'Mercury' , 'Venus' , 'Earth' , 'Mars' , 'Jupiter' , 'Saturn' , 'Uranus' , 'Neptune' , 'Pluto' , 'Habitat' , 'Moon' ],
135141 pos = self ._scene .caption_anchor , bind = self ._recentre_dropdown_hook , selected = 'Sun' )
136142 self ._scene .append_to_caption ("\n " )
137143 self ._scene .append_to_caption (
138144 "<b>Target: </b>" )
139145 target = self ._vpython .menu (
140146 choices = ['Sun' , 'Mercury' , 'Venus' , 'Earth' , 'Mars' , 'Jupiter' , 'Saturn' , 'Uranus' ,
141147 'Neptune' , 'Pluto' , 'AYSE' ],
142- pos = self ._scene .caption_anchor , bind = self ._update_center , selected = 'AYSE' )
148+ pos = self ._scene .caption_anchor , bind = self ._recentre_dropdown_hook , selected = 'AYSE' )
143149 self ._scene .append_to_caption ("\n " )
144150 self ._scene .append_to_caption (
145151 "<b>Ref: </b>" )
146152 ref = self ._vpython .menu (
147153 choices = ['Sun' , 'Mercury' , 'Venus' , 'Earth' , 'Mars' , 'Jupiter' , 'Saturn' , 'Uranus' ,
148154 'Neptune' , 'Pluto' , 'AYSE' ],
149- pos = self ._scene .caption_anchor , bind = self ._update_center , selected = 'AYSE' )
155+ pos = self ._scene .caption_anchor , bind = self ._recentre_dropdown_hook , selected = 'AYSE' )
150156 self ._scene .append_to_caption ("\n " )
151157 self ._scene .append_to_caption (
152158 "<b>Nav: </b>" )
153159 NAVmode = self ._vpython .menu (
154160 choices = ['Sun' , 'Mercury' , 'Venus' , 'Earth' , 'Mars' , 'Jupiter' , 'Saturn' , 'Uranus' ,
155161 'Neptune' , 'Pluto' , 'deprt ref' ],
156- pos = self ._scene .caption_anchor , bind = self ._update_center , selected = 'deprt ref' )
162+ pos = self ._scene .caption_anchor , bind = self ._recentre_dropdown_hook , selected = 'deprt ref' )
157163 self ._scene .append_to_caption ("\n " )
158164
159165 def draw (self , physical_state_to_draw ):
160166 if self .pause :
161167 self ._scene .pause ("Simulation is paused. \n Press 'p' to continue" )
162168 for planet in physical_state_to_draw .entities :
163169 self ._update_sphere (planet )
164- if self .show_label :
170+ if self ._show_label :
165171 self ._update_label (planet )
172+ if planet .name == "Habitat" :
173+ self ._update_habitat_arrow (planet )
174+
175+ def _draw_habitat_arrow (self , planet ):
176+ """Create an arrow that restore the habitat direction information"""
177+ return self ._vpython .arrow (
178+ pos = (
179+ self ._posn (planet ) +
180+ self ._vpython .vector (0 , 0 , - 2 * planet .r )
181+ ),
182+ axis = self ._vpython .vector (planet .vx , planet .vy , 0 ).norm (),
183+ length = 100 )
184+
185+ def _update_habitat_arrow (self , planet ):
186+ """Update the position of the arrow """
187+
188+ self ._habitat_arrow .pos = (
189+ self ._posn (planet ) +
190+ self ._vpython .vector (0 , 0 , - 2 * planet .r )
191+ )
192+ self ._habitat_arrow .axis = self ._vpython .vector (
193+ planet .vx , planet .vy , 0 ).norm ()
166194
167195 def _draw_labels (self , planet ):
168- return self ._vpython .label (visible = True , pos = self ._vpython .vector (planet .x , planet .y , 0 ), text = planet .name , xoffset = 0 , yoffset = 10 , height = 16 ,
169- border = 4 , font = 'sans' )
196+ label = self ._vpython .label (
197+ visible = True , pos = self ._posn (planet ),
198+ text = planet .name , xoffset = 0 , yoffset = 10 , height = 16 ,
199+ border = 4 , font = 'sans' )
200+
201+ if planet .name == 'Habitat' :
202+ label .text += f'\n Fuel: { planet .fuel } '
203+
204+ return label
170205
171206 def _draw_sphere (self , planet ):
172207 texture = self ._texture_path / (planet .name + '.jpg' )
173- if texture .is_file ():
174- return self ._vpython .sphere (
175- pos = self ._vpython .vector (planet .x , planet .y , 0 ),
208+
209+ if planet .name == "Habitat" :
210+ # Todo: habitat object should be seperately defined from planets
211+ obj = self ._vpython .cone (
212+ pos = self ._posn (planet ),
213+ axis = self ._vpython .vector (
214+ planet .vx , planet .vy , 0 ),
176215 radius = planet .r ,
216+ length = 2 * planet .r ,
177217 make_trail = True ,
178- shininess = 0.1 ,
179- texture = str (texture )
218+ shininess = 0.1
180219 )
181220 else :
182- log .debug (f'Could not find texture { texture } ' )
183- return self ._vpython .sphere (
184- pos = self ._vpython .vector (planet .x , planet .y , 0 ),
221+ obj = self ._vpython .sphere (
222+ pos = self ._posn (planet ),
185223 radius = planet .r ,
186- shininess = 0.1 ,
187- make_trail = True
224+ make_trail = True ,
225+ shininess = 0.1
188226 )
189227
228+ if planet .name == 'Sun' : # The sun is special!
229+ obj .emissive = True # The sun glows!
230+ self ._scene .lights = []
231+ self ._lights = [self ._vpython .local_light (pos = obj .pos )]
232+
233+ if texture .is_file ():
234+ obj .texture = str (texture )
235+ else :
236+ log .debug (f'Could not find texture { texture } ' )
237+
238+ return obj
239+
190240 def _update_sphere (self , planet ):
191- self ._spheres [planet .name ].pos = self ._vpython .vector (
192- planet .x , planet .y , 0 )
241+ self ._spheres [planet .name ].pos = self ._posn (planet )
193242
194243 def _update_label (self , planet ):
195- self ._labels [planet .name ].pos = self ._vpython .vector (
196- planet .x , planet .y , 0 )
244+ if planet .name == "Habitat" :
245+ self ._labels ["Habitat" ].text = "Habitat\n " + \
246+ "Fuel: " + str (planet .fuel )
247+ self ._labels [planet .name ].pos = self ._posn (planet )
197248
198249 def _recentre_dropdown_hook (self , selection ):
199250 self .recentre_camera (selection .selected )
200251
201252 def recentre_camera (self , planet_name ):
253+ """Change camera to focus on different object"""
254+
202255 try :
203256 if planet_name == "Sun" :
204257 self ._scene .range = self ._spheres ["Sun" ].radius * 15000
0 commit comments