Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
 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)
Ejemplo n.º 5
0
        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'
Ejemplo n.º 6
0
 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")
Ejemplo n.º 7
0
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 ")
Ejemplo n.º 8
0
    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]
Ejemplo n.º 9
0
    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):
Ejemplo n.º 10
0
                  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()
Ejemplo n.º 12
0
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))