def _build_clients_table(self, clients: List[SimpleNamespace]): text = "<table>" text += "<caption>Connected OrbitX clients</caption>" text += "<tr>" text += "<th scope='col'>Client</th>" text += "<th scope='col'>Location</th>" text += "<th scope='col'>Last Contact</th>" text += "</tr>" self._last_contact_wtexts = [] if len(clients) == 0: text += \ "<tr><td colspan='3'>No currently connected clients</td></tr>" for client in clients: self._last_contact_wtexts.append(vpython.wtext(text='')) vpython_widgets.last_div_id += 1 text += "<tr>" text += f"<td>{client.client_type}</td>" text += f"<td>{client.client_addr}</td>" text += f"<td><div id={vpython_widgets.last_div_id}>Connecting" text += "</div></td></tr>" text += "</table>" self._clients_table.text = text
def __init__(self): self._commands: List[network.Request] = [] self._last_state: PhysicsState canvas = vpython.canvas(width=1, height=1) common.include_vpython_footer_file( Path('orbitx', 'graphics', 'simple_css.css')) # Hide vpython wtexts, except for the table. canvas.append_to_caption("""<style> span { /* Hide any wtexts we generate. */ display: none; } span.nohide { /* Make sure wtexts we make are not hidden. */ display: initial; } div.flex-box { display: flex; justify-content: space-between; } input { flex: 1; margin: 5px; } </style>""") canvas.append_to_caption("<title>OrbitX Physics Server</title>") canvas.append_to_caption("<h1>OrbitX Physics Server</h1>") canvas.append_to_caption(f"<h3>Running on {socket.getfqdn()}</h3>") canvas.append_to_caption("<div class='flex-box'></div>") vpython_widgets.Input(bind=self._load_hook, placeholder='Load savefile') vpython_widgets.Input(bind=self._load_hook, placeholder='Save savefile') vpython_widgets.stuff_widgets_into_flex_box( [vpython_widgets.last_div_id - 1, vpython_widgets.last_div_id]) canvas.append_to_caption("<hr />") self._clients_table = vpython.wtext(text='') vpython_widgets.last_div_id += 1 # We hide all other vpython-made wtexts, except for this one. canvas.append_to_caption(f"""<script> document.querySelector( 'span[id="{vpython_widgets.last_div_id}"]').className = 'nohide'; </script>""") self._last_contact_wtexts: List[vpython.wtext] = [] self._previous_number_of_clients: int = 0 # This is needed to launch vpython. vpython.sphere() canvas.delete() common.remove_vpython_css()
def __init__(self, caption: str, text_gen: Callable[[Any], str], helptext: Optional[str], *, new_section: bool): global last_div_id self._wtext = vpython.wtext() last_div_id += 1 self._text_gen = text_gen helptext = f"<div class='helptext'>{helptext}</div>" \ if helptext else "" vpython.canvas.get_selected().caption += f"""
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)
def Reset(): vp.scene.width = 800 vp.scene.height = 800 vp.scene.range = 1.3 vp.scene.title = "ANTIKYTHERA\n" vp.button(text="display", bind=display, pos=vp.scene.title_anchor) vp.scene.append_to_title('\n') vp.button(text="display at", bind=showat, pos=vp.scene.title_anchor) vp.scene.append_to_title('\n') vp.button(text="credits", bind=credits, pos=vp.scene.title_anchor) vp.scene.append_to_title('\n') vp.winput(bind=seteclipse, pos=vp.scene.title_anchor, text = 'YEAR') vp.button(text="eclipes predictor", bind=prediction, pos=vp.scene.title_anchor) vp.scene.append_to_title('\n') current_date = datetime.datetime.today() guidate = vp.wtext(text=" ")
def __init__(self, server_name: str, intermediary: OrbitVIntermediary): self._orbitsse_path = intermediary.orbitsse canvas = vpython.canvas(width=1, height=1) common.include_vpython_footer_file( Path('orbitx', 'graphics', 'simple_css.css')) canvas.append_to_caption("<title>OrbitX Compat Client</title>") canvas.append_to_caption("<h1>OrbitX ↔ OrbitV Piloting Compatibility") canvas.append_to_caption( f"<h3>Connected to Physics Server at {server_name}</h3>") self._error_field = vpython.wtext(text='') vpython_widgets.last_div_id += 1 canvas.append_to_caption( f"<div id={vpython_widgets.last_div_id}></div>") canvas.append_to_caption("<h3>OrbitX → OrbitV</h3>") canvas.append_to_caption( "<div>" f"Writing to <span class='mono'>{intermediary.osbackup}</span>" "</div>") self._osbackup_write_time_field = vpython.wtext(text='') vpython_widgets.last_div_id += 1 canvas.append_to_caption( "<div>" "<span>Last update written at</span> " f"<span class='mono' id='{vpython_widgets.last_div_id}'></span>" "</div>") self._orbitv_entities = set(intermediary.orbitv_names) self._last_missing_entities_set: Set[str] = set() self._missing_entities_warning = vpython.wtext(text='') vpython_widgets.last_div_id += 1 canvas.append_to_caption( f"<div id='{vpython_widgets.last_div_id}'></div>") canvas.append_to_caption("<h3>OrbitX ← OrbitV</h3>") canvas.append_to_caption( "<div>" f"Reading from <span class='mono'>{intermediary.orbitsse}</span>" "</div>") self._orbitsse_read_time_field = vpython.wtext(text='') vpython_widgets.last_div_id += 1 canvas.append_to_caption( "<div>" "<span>Last update detected and read at</span> " f"<span class='mono' id='{vpython_widgets.last_div_id}'></span>" "</div>") canvas.append_to_caption("<table>\n") canvas.append_to_caption( "<caption>Contents of last OrbitV Engineering update</caption>") canvas.append_to_caption("<tr>") canvas.append_to_caption("<th scope='col'>Field name</th>") canvas.append_to_caption("<th scope='col'>Field value</th>") canvas.append_to_caption("</tr>") def row_text_setter( eng_update: network.Request.OrbitVEngineeringUpdate, field_name: str) -> str: return getattr(eng_update, field_name) fields_list = orbitx_pb2.Command.OrbitVEngineeringUpdate.DESCRIPTOR.fields self._eng_fields: List[vpython_widgets.TableText] = [] for descriptor in fields_list: self._eng_fields.append( vpython_widgets.TableText( descriptor.name.replace('_', ' ').title(), functools.partial(row_text_setter, field_name=descriptor.name), None, new_section=False)) canvas.append_to_caption("</table>") # This is needed to launch vpython. vpython.sphere() canvas.delete() common.remove_vpython_css()
try: if running: mod_esc.escenario3_avance(dt) if mod_esc.n==20: message[2]+=""" El scattering de Compton, hace referencia al efecto que un foton presenta al incidir a un electron en reposo. \n Al incidirlo, el electron se deflecta y el foton se dispersa con un angulo que se conoce como angulo de dispersion.\n <img src="imagenes/comptonDiagram.png" width=500 height=300>\n El foton al ser dispersado, cambia su longitud de onda, siguiendo la formula de Rutheford:\n\n"""+' <img src="imagenes/comptonEquation.png" width=200 height=60>\n >' vp.scene.caption = message[2] break except: break else: # el evento == "Elige un escenario" vp.scene.caption=mensajeInicio mensajeInicio="""\n Diferentes escenarios creados con el fin de visualizar informacion acerca de las particulas del modelo estandar, para visualizar los efectos \n de scattering de particulas alpha incidiendo un nucleo (scattering de Rutherford) y por ultimo, para visualizar el scattering de un foton incidiendo en un electron en resposo (scattering de Compton). \n\n\n\n Para el escenario de Rutherford y Compton scattering, se usaron algunas graficas tomadas de los siguientes libros: Serway, R., Moyer, C., & Moses, C. (2005). Modern physics (3rd ed., pp. 90,92). Tipler, P., & Llewellyn, R. (2020). Modern Physics (6th ed., pp. 159,162).""" vp.wtext(pos=vp.scene.title_anchor, text=" ") # Menu de eleccion de escenarios: llama a la funcion Ejecutar(m) y ejecuta el escenario con el evento m correspondiente menu=vp.menu(choices=["Elige un escenario", "Informacion", "Rutherford Scattering", "Compton Scattering"], index=0, pos=vp.scene.title_anchor, bind=Ejecutar) vp.scene.append_to_caption(' ') vp.scene.append_to_caption(mensajeInicio) vp.scene.append_to_caption('\n')
# https://www.glowscript.org/#/user/GlowScriptDemos/folder/Examples/program/Color-RGB-HSV-VPython/edit # GlowScript version of Jupyter demo program Color-RGB-HSV vp.scene.userzoom = False vp.scene.userspin = False vp.scene.width = 460 vp.scene.height = 200 vp.scene.range = 1 vp.scene.background = vp.color.red # Force creation of canvas; box is not seen because it is outside the canvas vp.box(pos=vp.vector(10, 0, 0)) cancopy = 'You can Ctrl-C or Command-C copy these RGB and HSV values:\n' vp.scene.title = cancopy vp.scene.append_to_title("RGB = <") titlergb = vp.wtext(pos=vp.scene.title_anchor, text="1.000, 0.000, 0.000") vp.scene.append_to_title(">, HSV = <") titlehsv = vp.wtext(pos=vp.scene.title_anchor, text="0.000, 0.000, 0.000") vp.scene.append_to_title(">") C = ['Red', 'Green', 'Blue', 'Hue', 'Saturation', 'Value'] sliders = [] wts = [] def set_background(sl): if sl.id < 3: wts[sl.id].text = '{:1.3f}'.format(sl.value) rgb = vp.vector(sliders[0].value, sliders[1].value, sliders[2].value) hsv = vp.color.rgb_to_hsv(rgb) # reset HSV slider positions; display 3 figures
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 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)
color=vector(1, 0, 0), pos=vector(100, 2, 0)) onY100 = text(text="100cm", align='center', color=vector(0, 1, 0), pos=vector(4, 100, 0)) onZ100 = text(text="100cm", align='center', color=vector(0, 0, 1), pos=vector(0, 2, 100)) lineToPoint = arrow(pos=vector(0, 0, 0), axis=vector(0, 0, 0), shaftwidth=1, color=vector(0, 1, 1)) hudDist = wtext(pos=window.caption_anchor, text="Distance ") hudStrength = wtext(pos=window.caption_anchor, text="Strength ") hudPan = wtext(pos=window.caption_anchor, text="Pan ") hudTilt = wtext(pos=window.caption_anchor, text="Tilt ") hudShowDist = checkbox(pos=window.caption_anchor, text="Show distance", bind=showDistance) hudShowStrength = checkbox(pos=window.caption_anchor, text="Show Strength", bind=showStrength) hudShowUnreliable = checkbox(pos=window.caption_anchor, text="Show filtered", bind=showUnreliable) hudShowDist.checked = True hudShowUnreliable.checked = True hudShowDist.disabled = True
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 ")
current_date = datetime.datetime.today() # current date of the simulation guiday = str(current_date.day) guimonth = str(current_date.month) guiyear = str(current_date.year) #setting the scene vp.scene.width = 800 vp.scene.height = 800 vp.scene.range = 1.3 vp.scene.title = "ANTIKYTHERA\n" #vp.scene.append_to_title('\n') vp.scene.append_to_title('\n') #vp.scene.append_to_title('\n') vp.button(text="credits", bind=credits, pos=vp.scene.title_anchor) #vp.scene.append_to_title('\n') #vp.scene.append_to_title('\n') vp.wtext(text = "--------------------------------------------------------------\n") vp.wtext(text = " SOLAR SYSTEM SIMULATOR \n") vp.wtext(text = "--------------------------------------------------------------\n") vp.wtext(text = "\nPress ") vp.button(text="Start", bind=start) vp.wtext(text = " to start the simulation\n") vp.wtext(text = "\nEnter a date in 'mm/dd/yyyy' ") vp.winput(bind=setdate, type="string") vp.wtext(text = " and press the 'Enter' key to simulate the system at that time") dateErrorText = vp.wtext(text = "\n") vp.wtext(text = "\nThis is the current date: \n") vp.wtext(text = "-----------------\n") guidate = vp.wtext(text=" ") guidate.text = "| " + guiday + "/" + guimonth + "/" + guiyear + " |\n" vp.wtext(text = "-----------------\n") vp.wtext(text = "\nControl the runtime using the buttons and slider below: \n")
str(shape_color), color=vpython.color.red, pos=vpython.vector(-25, 20, 0), height=3) def form_box(): """ this function handle the form box :return: None """ text_box.text = TEXT_BOX_STYLE scene.bind(KEY_RECOGNIZE_BY, key_input) vpython.button(bind=word_checker, text=lang.BUTTON_TEXT) # main part scene = vpython.canvas(title=lang.TITLE, width=config.WINDOW_WIDTH, height=config.WINDOW_HEIGHT, background=vpython.color.black) scene.append_to_caption(lang.DESCRIPTION) info = create_all_shapes() word = info[0] chosen_shape = info[1] shape_color = info[2] text_box = vpython.wtext() result = vpython.wtext() show_instruction() form_box()
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 scene.append_to_caption("Frequency [f] = ")
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))