def display(): vp.scene.append_to_title('\n') vp.button(text="credits", bind=showat, pos=vp.scene.title_anchor) vp.scene.append_to_caption('\n') vp.button(text="Pause", bind=Pause) vp.scene.append_to_caption('\n') t = vp.slider(min=-20000, max=20000, value=1, length=675, bind=setyear) vp.scene.append_to_caption('\n') print("B") celestpos = Jacob(t.value) # makes the sun shine vp.sphere(color=vp.color.yellow, emissive=True) vp.local_light(pos=vp.vector(0, 0, 0), color=vp.color.yellow) # creates the visual representation of the planets earth = vp.sphere(texture=vp.textures.earth, pos=vp.vector(celestpos[0] / 10000000, celestpos[1] / 10000000, celestpos[2] / 10000000), make_trail=True, trail_type="points", interval=10, retain=25) mars = vp.sphere(color=vp.vector(1, 0, 0), pos=vp.vector(celestpos[3] / 10000000, celestpos[4] / 10000000, celestpos[5] / 10000000), make_trail=True, trail_type="points", interval=10, retain=25) # venus = vp.sphere(color = vp.vector(1,1,.8), pos = vp.vector(celestpos[0] / 10000000,celestpos[0] / 10000000,celestpos[0] / 10000000), make_trail=True, trail_type="points", interval=10, retain=10) # mercury = vp.sphere(color = vp.vector(.3,.3,.3), pos = vp.vector(celestpos[0] / 10000000,celestpos[0] / 10000000,celestpos[0] / 10000000), make_trail=True, trail_type="points", interval=10, retain=5) # moon = vp.sphere(color = vp.vector(.3,.3,.3), pos = vp.vector(Moon.xPos / 10000000, Moon.yPos / 10000000,0)) vp.scene.append_to_caption('\n') sl = vp.slider(min=-20, max=20, value=1, length=675, bind=setspeed) while True: while pause == False: celestpos = Jacob(sl.value) # simulates motion # Moon.simulate_orbit(i, 0) # Earth.simulate_orbit(t, 0) # Venus.simulate_orbit(t, 0) # Mercury.simulate_orbit(t, 0) earth.pos = vp.vector(celestpos[0] / 10000000, celestpos[1] / 10000000, celestpos[2] / 10000000) mars.pos = vp.vector(celestpos[3] / 10000000, celestpos[4] / 10000000, celestpos[5] / 10000000) # venus.pos = vp.vector(Venus.xPos / 10000000,Venus.yPos / 10000000,0) # mercury.pos = vp.vector(Mercury.xPos / 10000000, Mercury.yPos / 10000000,0) # moon.pos = vp.vector(Moon.xPos / 10000000, Moon.yPos / 10000000,0) if (sl.value > 0): t.value += 1 time.sleep(0.01) else: t.value -= 1 time.sleep(.01)
def add_widgets(scene, solar_system): """ Adds menus and sliders to the window to allow you to control the camera and simulation parameters. It's not important to understand this function. """ def follow_body(menu): scene.camera.follow(solar_system.bodies[menu.index].visual) def change_dt(slider): global dt dt = 10 ** slider.value dt_text.text = "dt={:.2e}s:".format(dt) def toggle_infobox(checkbox): for body in solar_system.bodies: body.info.visible = checkbox.checked def toggle_controls(checkbox): solar_system.controls_label.visible = checkbox.checked vis.wtext(pos = scene.title_anchor, text = " ") vis.wtext(pos = scene.title_anchor, text = "Focus: ") vis.menu(pos = scene.title_anchor, choices = list(map(lambda body: body.name, solar_system.bodies)), bind = follow_body) vis.wtext(pos = scene.title_anchor, text = " ") dt_text = vis.wtext(pos = scene.title_anchor, text = "dt={:.2e}s:".format(dt)) vis.slider(pos = scene.title_anchor, min = 0, max = 6, value = np.log10(dt), bind = change_dt) vis.wtext(pos = scene.title_anchor, text = " ") vis.checkbox(pos = scene.title_anchor, text = "Enable infoboxes", checked = True, bind = toggle_infobox) vis.wtext(pos = scene.title_anchor, text = " ") vis.checkbox(pos = scene.title_anchor, text = "Show controls", checked = False, bind = toggle_controls)
def __setup_joint_sliders(self): """ Display the Teachpanel mode of the UI """ i = 1 for joint in self.__teachpanel[self.__selected_robot]: # Add a title self.scene.append_to_caption('Joint {0}:\t'.format(i)) i += 1 # Add the slider, with the correct joint variables s = slider( bind=self.__joint_slider, min=joint[self.__idx_qlim_min], max=joint[self.__idx_qlim_max], value=joint[self.__idx_theta] ) self.__teachpanel_sliders.append(s) self.scene.append_to_caption('\n\n')
def add_widgets(scene, cyclotron): """ Adds menus and sliders to the window to allow you to control the camera and simulation parameters. It's not important to understand this function. """ def follow_body(menu): scene.camera.follow(cyclotron.bodies[menu.index].visual) def change_dt(slider): global dt dt = 10 ** slider.value dt_text.text = "dt={:.2e}s:".format(dt) def change_E(slider): global E_mag E_mag = 10 ** slider.value E_text.text = "|E|={:.2e}s:".format(E_mag) def change_B(slider): global B_mag B_mag = 10 ** slider.value cyclotron.b_field = vec(0, 0, -B_mag) B_text.text = "|B|={:.2e}s:".format(B_mag) def toggle_infobox(checkbox): for body in cyclotron.bodies: body.info.visible = checkbox.checked def toggle_controls(checkbox): cyclotron.controls_label.visible = checkbox.checked vis.wtext(pos = scene.title_anchor, text = " ") vis.wtext(pos = scene.title_anchor, text = "Focus: ") vis.menu(pos = scene.title_anchor, choices = list(map(lambda body: body.name, cyclotron.bodies)), bind = follow_body) vis.wtext(pos = scene.title_anchor, text = " ") dt_text = vis.wtext(pos = scene.title_anchor, text = "dt={:.2e}s:".format(dt)) vis.slider(pos = scene.title_anchor, min = -15, max = -9, value = np.log10(dt), bind = change_dt, length = 200) E_text = vis.wtext(pos = scene.title_anchor, text = "|E|={:.2e}N/m:".format(E_mag)) vis.slider(pos = scene.title_anchor, min = 0, max = 12, value = np.log10(E_mag), bind = change_E, length = 200) B_text = vis.wtext(pos = scene.title_anchor, text = "|B|={:.2e}N/m:".format(B_mag)) vis.slider(pos = scene.title_anchor, min = -4, max = 0, value = np.log10(B_mag), bind = change_B, length = 200)
wts[sl.id].text = '{:1.3f}'.format(sl.value) hsv = vp.vector(sliders[3].value, sliders[4].value, sliders[5].value) rgb = vp.color.hsv_to_rgb(hsv) # reset RGB slider positions; display 3 figures sliders[0].value = int(1000 * rgb.x) / 1000 sliders[1].value = int(1000 * rgb.y) / 1000 sliders[2].value = int(1000 * rgb.z) / 1000 wts[0].text = '{:1.3f}'.format(rgb.x) wts[1].text = '{:1.3f}'.format(rgb.y) wts[2].text = '{:1.3f}'.format(rgb.z) vp.scene.background = rgb # For readability, limit precision of display of quantities to 3 figures titlergb.text = "{:1.3f}, {:1.3f}, {:1.3f}".format(rgb.x, rgb.y, rgb.z) titlehsv.text = "{:1.3f}, {:1.3f}, {:1.3f}".format(hsv.x, hsv.y, hsv.z) vp.scene.caption = '\n' for i in range(6): # Create the 3 RGB and 3 HSV sliders sliders.append( vp.slider(length=300, left=10, min=0, max=1, bind=set_background, id=i)) vp.scene.append_to_caption(' ' + C[i] + ' ') # Display slider name wts.append(vp.wtext(text='0.000')) vp.scene.append_to_caption('\n\n') if i == 2: vp.scene.append_to_caption("\n\n") # Separate the RGB and HSV sliders sliders[0].value = 1 # make the background red sliders[4].value = sliders[5].value = 1 wts[0].text = '1.000' wts[4].text = wts[5].text = '1.000'
def makeColorbar(self, doOrnaments=True, colorscale='jet', bg='default'): title = None if doOrnaments: title = MooView.consolidatedTitle + "\n" barWidth = SCALE_SCENE * 1.5 self.colorbar = vp.canvas(title=title, width=barWidth, height=self.swy * SCALE_SCENE, background=bgLookup(bg), align='left', range=1, autoscale=False) #self.colorbar = vp.canvas( title = title, width = barWidth, height = self.swy * SCALE_SCENE, background = vp.color.cyan, align = 'left', range = 1, autoscale = False ) self.colorbar.userzoom = False self.colorbar.userspin = False self.colorbar.userpan = False height = 0.10 width = 5 axOrigin = vp.vector(0, -5.5, 0) for idx, rgb in enumerate(self.rgb): cbox = vp.box(canvas=self.colorbar, pos=vp.vector(0, height * (idx - 26), 0), width=width, height=height, color=rgb) barName = self.title.replace(' ', '\n') self.barName = vp.label(canvas=self.colorbar, align='left', pixel_pos=True, pos=vp.vector(2, (self.swy - 0.32) * SCALE_SCENE, 0), text=barName, height=15, color=vp.color.black, box=False, opacity=0) self.barMin = vp.label(canvas=self.colorbar, align='center', pixel_pos=True, pos=vp.vector(barWidth / 2, self.swy * SCALE_SCENE * 0.22, 0), text="{:.3f}".format(self.valMin), height=12, color=vp.color.black, box=False, opacity=0) self.barMax = vp.label(canvas=self.colorbar, align='center', pixel_pos=True, pos=vp.vector(barWidth / 2, (self.swy - 1.2) * SCALE_SCENE, 0), text="{:.3f}".format(self.valMax), height=12, color=vp.color.black, box=False, opacity=0) self.xAx = vp.cylinder(canvas=self.colorbar, pos=axOrigin, axis=vp.vector(0.8, 0, 0), radius=0.04, color=vp.color.red) self.yAx = vp.cylinder(canvas=self.colorbar, pos=axOrigin, axis=vp.vector(0, 0.8, 0), radius=0.04, color=vp.color.green) self.zAx = vp.cylinder(canvas=self.colorbar, pos=axOrigin, axis=vp.vector(0, 0, 0), radius=0.04, color=vp.color.blue) self.axisLength = vp.label(pos=axOrigin + vp.vector(0, 1, 0), text="1.00 <i>u</i>m", color=vp.color.black, box=False) if doOrnaments: self.timeLabel = vp.wtext(text="Time = 0.000 sec", pos=self.colorbar.title_anchor) self.sleepLabel = vp.wtext(text=" Frame dt = 0.005 sec", pos=self.colorbar.title_anchor) self.sleepSlider = vp.slider(pos=self.colorbar.title_anchor, length=200, bind=self.setSleepTime, min=0.0, max=0.2, value=self.sleep) self.replayButton = vp.button(text="Start Replay", pos=self.colorbar.title_anchor, bind=self.toggleReplay, disabled=True) self.colorbar.append_to_title("\n")
def create_widgets(): Game.scene1.append_to_caption("\n\n") # ------- roughness of terrain ---------------- Game.scene1.append_to_caption("change terrain roughness to") Game.slider_roughness = v.slider(bind=func_roughness, min=0, max=1.0, step=0.01, value=Game.roughness, length=500) Game.label_roughness = v.wtext( text=f" ={Game.roughness:.2f} (0 = very smooth, 1= very rough)") Game.scene1.append_to_caption(Game.label_roughness) Game.scene1.append_to_caption( v.button(text="generate new landscape", bind=func_recalc)) Game.scene1.append_to_caption("\n\n") # ---- winputs fields: fields that accept an text entry that will be converted into a number --- Game.scene1.append_to_caption("type in values and press ENTER:\n\n ") # --------sea level--------------- Game.scene1.append_to_caption("change sea level to") #Game.input_sea_level = v.slider(bind=func_sea_level, min=0.0, max=Game.snow_level, step=0.01, value=Game.sea_level) Game.input_sea_level = v.winput(bind=func_sea_level, type="numeric", text=Game.sea_level) Game.label_sea_level = v.wtext(text=f" ={Game.sea_level:.2f} ") Game.scene1.append_to_caption(Game.label_sea_level) Game.scene1.append_to_caption(" (must be lesser than snow level)\n\n") # ------- snow level -------------- Game.scene1.append_to_caption("change snow level to") #Game.input_snow_level = v.slider(bind=func_snow_level, min=Game.sea_level, max=1.0, step=0.01, value=Game.snow_level) #Game.label_snow_level = v.wtext(text=f"{Game.snow_level*100:.0f} % of (max. height- min. height) = {Game.min_y + Game.snow_level*(Game.max_y-Game.min_y):.2f}") Game.input_snow_level = v.winput(bind=func_snow_level, type="numeric", text=Game.snow_level) Game.label_snow_level = v.wtext(text=f" ={Game.snow_level:.2f} ") Game.scene1.append_to_caption(Game.label_snow_level) Game.scene1.append_to_caption(" (must be greater than sea level)\n\n") # --------world size --------------- Game.scene1.append_to_caption("change world size to: ") #Game.input_world_size = v.slider(bind=func_world_size, min=1, max=100, step=1, # value=Game.world_size) Game.input_world_size = v.winput(bind=func_world_size, type="numeric", text=Game.world_size) Game.label_world_size = v.wtext( text=f" = {Game.world_size} x {Game.world_size} tiles") Game.scene1.append_to_caption(Game.label_world_size) Game.scene1.append_to_caption("\n\n") # -------- min height, max height -------------- Game.scene1.append_to_caption("change minimum height to:") Game.input_min_y = v.winput(bind=func_min_y, type="numeric", text=Game.min_y) Game.label_min_y = v.wtext(text=f" ={Game.min_y:.2f}") Game.scene1.append_to_caption(Game.label_min_y) Game.scene1.append_to_caption(" change maximum height to:") Game.input_max_y = v.winput(bind=func_max_y, type="numeric", text=Game.max_y) Game.label_max_y = v.wtext(text=f" ={Game.max_y:.2f}") Game.scene1.append_to_caption(Game.label_max_y) Game.scene1.append_to_caption("\n\n") # -------- Game.scene1.append_to_caption("change color of ")
def __setup_ui_controls(self, list_of_names): """ The initial configuration of the user interface :param list_of_names: A list of names of the robots in the screen :type list_of_names: `list` """ # Button to reset camera btn_reset = button(bind=self.__reset_camera, text="Reset Camera") self.scene.append_to_caption('\t') chkbox_cam = checkbox(bind=self.__camera_lock_checkbox, text="Camera Lock", checked=self.__camera_lock) self.scene.append_to_caption('\t') chkbox_rel = checkbox(bind=self.__grid_relative_checkbox, text="Grid Relative", checked=self.__grid_relative) self.scene.append_to_caption('\n\n') # Drop down for robots / joints in frame menu_robots = menu(bind=self.__menu_item_chosen, choices=list_of_names) if not len(list_of_names) == 0: menu_robots.index = self.__selected_robot self.scene.append_to_caption('\t') # Button to delete the selected robot btn_del = button(bind=self.__del_robot, text="Delete Robot") self.scene.append_to_caption('\t') # Button to clear the robots in screen btn_clr = button(bind=self.clear_scene, text="Clear Scene") self.scene.append_to_caption('\n\n') # Checkbox for grid visibility chkbox_grid = checkbox(bind=self.__grid_visibility_checkbox, text="Grid Visibility", checked=self.__grid_visibility) self.scene.append_to_caption('\t') # Checkbox for reference frame visibilities if len(self.__robots) == 0: chkbox_ref = checkbox(bind=self.__reference_frame_checkbox, text="Show Reference Frames", checked=True) else: chk = self.__robots[self.__selected_robot].ref_shown chkbox_ref = checkbox(bind=self.__reference_frame_checkbox, text="Show Reference Frames", checked=chk) self.scene.append_to_caption('\t') # Checkbox for robot visibility if len(self.__robots) == 0: chkbox_rob = checkbox(bind=self.__robot_visibility_checkbox, text="Show Robot", checked=True) else: chk = self.__robots[self.__selected_robot].rob_shown chkbox_rob = checkbox(bind=self.__robot_visibility_checkbox, text="Show Robot", checked=chk) self.scene.append_to_caption('\n\n') # Slider for robot opacity self.scene.append_to_caption('Opacity:') if len(self.__robots) == 0: sld_opc = slider(bind=self.__opacity_slider, value=1) else: opc = self.__robots[self.__selected_robot].opacity sld_opc = slider(bind=self.__opacity_slider, value=opc) # self.scene.append_to_caption('\n\n') # Prevent the space bar from toggling the active checkbox/button/etc (default browser behaviour) self.scene.append_to_caption(''' <script type="text/javascript"> $(document).keyup(function(event) { if(event.which === 32) { event.preventDefault(); } }); </script>''') # https://stackoverflow.com/questions/22280139/prevent-space-button-from-triggering-any-other-button-click-in-jquery # Control manual controls_str = '<br><b>Controls</b><br>' \ '<b>PAN</b><br>' \ 'W , S | <i>forward / backward</i><br>' \ 'A , D | <i>left / right</i><br>' \ 'SPACE , SHIFT | <i>up / down</i><br>' \ '<b>ROTATE</b><br>' \ 'CTRL + LMB | <i>free spin</i><br>' \ 'ARROWS KEYS | <i>rotate direction</i><br>' \ 'Q , E | <i>roll left / right</i><br>' \ '<b>ZOOM</b></br>' \ 'MOUSEWHEEL | <i>zoom in / out</i><br>' \ '<script type="text/javascript">var arrow_keys_handler = function(e) {switch(e.keyCode){ case 37: case 39: case 38: case 40: case 32: e.preventDefault(); break; default: break;}};window.addEventListener("keydown", arrow_keys_handler, false);</script>' # Disable the arrow keys from scrolling in the browser # https://stackoverflow.com/questions/8916620/disable-arrow-key-scrolling-in-users-browser self.scene.append_to_caption(controls_str) return [btn_reset, menu_robots, chkbox_ref, chkbox_rob, chkbox_grid, chkbox_cam, chkbox_rel, sld_opc, btn_del, btn_clr]
planet.simulate_orbit(0) list_of_planet_models.append(vp.sphere(textures=vp.textures.earth, pos=vp.vector(planet.xPos / 10000000, planet.yPos / 10000000, planet.zPos / 10000000), make_trail=True, trail_type="curve", interval=10, retain=50, radius = 0.1)) list_of_planet_names.append(vp.label(text = planet.name, pos = list_of_planet_models[list_of_planets.index(planet)].pos, height = 15, yoffset = 50, space = 30, border = 4, font = 'sans')) for satellite in list_of_satellites: for planet in list_of_planets: if satellite.host == planet.name: satellite.simulate_orbit(0, planet) list_of_satellite_models.append(vp.sphere(textures=vp.textures.earth, pos=vp.vector(satellite.xPos / 10000000, satellite.yPos / 10000000, satellite.zPos / 10000000), make_trail=False, radius = 0.03)) list_of_satellite_names.append(vp.label(text = satellite.name, pos = list_of_satellite_models[list_of_satellites.index(satellite)].pos, height = 15, yoffset = 50, space = 30, border = 4, font = 'sans')) break ############################################################################ sl = vp.slider(min=-3, max=3, value=0.5, length=675, bind=setspeed) ################################################################################ vp.scene.camera.pos = vp.vector(0, 0, 20) vp.scene.append_to_caption('\n') vp.scene.append_to_caption('\n') vp.wtext(text = "--------------------------------------------------------------\n") vp.wtext(text = " ECLIPSE PREDICTOR \n") vp.wtext(text = "--------------------------------------------------------------\n") vp.wtext(text = "\nEnter a year to predict eclipses in: ") vp.winput(bind=prediction) vp.wtext(text = " and press the 'Enter' key ") vp.wtext(text="\n ") for i in range(7):
title="Ideal Pendulum Simulation by haiq70", autoscale=False, center=vp.vector(0, -3, 0)) bob = vp.sphere(pos=vp.vector(0, -length, 0), radius=0.5) string = vp.cylinder(pos=vp.vector(0, 0, 0), axis=vp.vector(0, -length, 0), radius=0.02) # BUTTONS vp.button(bind=start_button_clicked, text='Start') vp.button(bind=pause_button_clicked, text='Pause') scene.append_to_caption('\n\n') # SLIDER (SPATIAL DEVIATION) scene.append_to_caption("Spatial deviation: ") slider_sd = vp.slider(min=0.1, max=90, bind=get_theta, step=0.1, value=5) theta_output = vp.wtext(text=slider_sd.value) scene.append_to_caption(" \u00b0 \n") # SLIDER (LENGTH OF THE STRING) scene.append_to_caption("Length of the string: ") slider_l = vp.slider(min=0.1, max=10, bind=get_length, step=0.1, value=3) length_output = vp.wtext(text=slider_l.value) scene.append_to_caption(" m\n\n") # TEXT OUTPUT # period scene.append_to_caption("Period [T] = ") period_output = vp.wtext(text=period) scene.append_to_caption(" s\n") # frequency
def start(self): """open the vpython window and start the simulation""" # set up important boolean values from options testing = self.options.testing central_centered = self.options.central_centered show_pointers = self.options.pointers # set up canvas, bodies and pointers scene = vp.canvas(title="Simulation zum Zweikörperproblem", height=self.options.canvas.height, width=self.options.canvas.width) central = Body(sim=self, name="central", mass=self.values.central.mass, velocity=vp.vector(self.values.central.velocity.x, self.values.central.velocity.y, self.values.central.velocity.z), radius=self.values.central.radius, make_trail=True, color=vp.vector(self.options.colors.bodies.x / 255, self.options.colors.bodies.y / 255, self.options.colors.bodies.z / 255)) sat = Body(sim=self, name="sat", mass=self.values.sat.mass, velocity=vp.vector(self.values.sat.velocity.x, self.values.sat.velocity.y, self.values.sat.velocity.z), pos=vp.vector( self.values.distance + self.values.central.radius + self.values.sat.radius, 0, 0), radius=self.values.sat.radius, make_trail=True, color=vp.vector(self.options.colors.bodies.x / 255, self.options.colors.bodies.y / 255, self.options.colors.bodies.z / 255)) central_ptr = vp.arrow() sat_ptr = vp.arrow() if show_pointers: central_ptr = vp.arrow(axis=vp.vector( 0, -((self.values.distance + central.radius + sat.radius) / 2), 0), color=vp.vector( self.options.colors.pointers.x, self.options.colors.pointers.y, self.options.colors.pointers.z)) central_ptr.pos = (central.pos - central_ptr.axis) + vp.vector( 0, self.values.central.radius, 0) sat_ptr = vp.arrow(axis=vp.vector( 0, -((self.values.distance + central.radius + sat.radius) / 2), 0), color=vp.vector(self.options.colors.pointers.x, self.options.colors.pointers.y, self.options.colors.pointers.z)) sat_ptr.pos = sat.pos - sat_ptr.axis + vp.vector( 0, self.values.sat.radius, 0) # set up buttons pause_sim = vp.button(text="Pause", bind=self.pause) vp.button(text="Stop", bind=lambda: os.kill(os.getpid(), signal.SIGINT)) vp.button(text="Restart", bind=self.restart) scene.append_to_caption("\n") # set up sliders for changing the radius of the two bodies central_slider = vp.slider( max=((self.values.distance + self.values.central.radius) / self.values.central.radius), min=1, value=1, top=12, bottom=12, bind=lambda: self.adjust_radius(slider=central_slider, sphere=central)) vp.button(text="Reset", bind=lambda: self.reset_slider(central_slider)) scene.append_to_caption("\n") sat_slider = vp.slider( max=((self.values.distance + self.values.sat.radius) / self.values.sat.radius), min=1, value=1, top=12, bottom=12, bind=lambda: self.adjust_radius(slider=sat_slider, sphere=sat)) vp.button(text="Reset", bind=lambda: self.reset_slider(sat_slider)) # set up time variables t = 0 t_max = self.options.rate * self.options.sim_time # main simulation loop if central_centered: scene.camera.follow(central) while t <= t_max: # weird behaviour of those two vp.rate(self.options.rate) # vp.sleep(1/self.options["update_rate"]) if pause_sim.text == "Pause": # physical calculations r = sat.pos - central.pos fv = (6.67430e-11 * central.mass * sat.mass) / (vp.mag(r)**2) central.force = fv * vp.norm(r) sat.force = fv * vp.norm(-r) central.calculate(self.options.delta_t) sat.calculate(self.options.delta_t) if show_pointers: # move pointers central_ptr.pos = central.pos - central_ptr.axis + \ vp.vector(0, central.radius, 0) sat_ptr.pos = sat.pos - sat_ptr.axis + vp.vector( 0, sat.radius, 0) if self.options.sim_time > 0: t += 1 if bool(self.options.restart): self.restart()
def visualize(cluster, animation=False, transparent=False, scale=None, origin='auto'): """ Create a 3D visualization of a particle cluster using VPython Arguments: cluster sphere or particle cluster animation (bool) an animation visualization transparent (bool) transparent particles scale (str) if set, display a scale bar origin origin of camera view ('auto' for centroid, 'cluster' for cluster origin, or np.array) """ import vpython vec = vpython.vec # scene = vpython.canvas(width=750, height=600, background=vec(1,1,1)) if origin == 'auto': origin = vec(*np.average(cluster.position, axis=0))/nm elif origin == 'cluster': origin = vec(*cluster.origin)/nm else: origin = vec(*origin)/nm scene = vpython.canvas(width=500, height=325, background=vec(1,1,1), center=origin) if type(cluster) == miepy.sphere_cluster: for i in range(cluster.Nparticles): position = cluster.position[i]/nm radius = cluster.radius[i]/nm paint = get_paint(cluster.material[i]) sphere = vpython.sphere(pos=vec(*position), radius=radius, texture=paint.texture, color=paint.color, shininess=paint.shininess) elif type(cluster) == miepy.cluster: for i in range(cluster.Nparticles): particle = cluster.particles[i] paint = get_paint(particle.material) obj = draw_particle(particle, paint) if transparent: for obj in scene.objects: obj.opacity = .5 if cluster.interface is not None: scene.autoscale = False length = height = 1e-3/nm width = 1e-3/nm z = cluster.interface.z box = vpython.box(pos=vec(0,0,-z-width/2), width=width, height=height, length=length, color=vec(0.6,0.6,0.6), shininess=0) if animation: T = 300 # cluster = vpython.compound(scene.objects) # cluster.rotate(angle=2*np.pi/T, origin=vec(0,0,0), axis=vec(0,1,0)) scene.append_to_caption('\n') def setspeed(s): nonlocal T wt.text = 'f = {:1.2f} Hz'.format(s.value) T = 30/s.value sl = vpython.slider(min=0.01, max=.3, value=.1, length=180, bind=setspeed, right=15, top=7) wt = vpython.wtext(text='f = {:1.2f} Hz'.format(sl.value)) def transparency(b): if b.checked: for obj in scene.objects: obj.opacity = .5 else: for obj in scene.objects: obj.opacity = 1 scene.append_to_caption(' ') vpython.checkbox(bind=transparency, text='Transparent') running = True def Run(b): nonlocal running running = not running if running: b.text = " ▌▌" b.color = vec(1,0,0) else: b.text = " ► " b.color = vec(0,.6,0) scene.append_to_caption(' ') vpython.button(text=" ▌▌", bind=Run, color=vec(1,0,0)) for t in count(): vpython.rate(30) # phi = 2*np.pi*t/T # scene.forward = vec(-np.sin(phi), 0, -np.cos(phi)) if running: for obj in scene.objects: obj.rotate(angle=2*np.pi/T, origin=origin, axis=vec(0,1,0))