def __init__(self, graphics_canvas, name, robot=None):
        self.joints = []
        self.num_joints = 0
        self.rob_shown = True
        self.ref_shown = True
        self.opacity = 1
        self.name = name
        self.__scene = graphics_canvas

        self.angles = []
        self.robot = robot

        # If Robot given, create the robot
        if self.robot is not None:
            # Update name
            self.name = self.robot.name
            # Get initial poses
            zero_angles = self.robot.qz
            all_poses = self.robot.fkine_all(zero_angles)
            # Create the base
            if robot.basemesh is not None:
                self.append_link("s", robot.base, robot.basemesh, [0, 0], 0)
            # else: assume no base joint
            # Create the joints
            i = 0
            for link in self.robot.links:
                # Get info
                if link.isprismatic():
                    j_type = 'p'
                elif link.isrevolute():
                    j_type = 'r'
                else:
                    j_type = 's'
                pose = all_poses[i]   # Pose
                if link.mesh is None:
                    if i == 0:
                        x1, x2 = SE3().t[0], all_poses[i].t[0]
                        y1, y2 = SE3().t[1], all_poses[i].t[1]
                        z1, z2 = SE3().t[2], all_poses[i].t[2]
                        length = sqrt(
                            (x2 - x1) * (x2 - x1) + (y2 - y1)
                            * (y2 - y1) + (z2 - z1) * (z2 - z1))  # Length
                    else:
                        x1, x2 = all_poses[i - 1].t[0], all_poses[i].t[0]
                        y1, y2 = all_poses[i - 1].t[1], all_poses[i].t[1]
                        z1, z2 = all_poses[i - 1].t[2], all_poses[i].t[2]
                        length = sqrt(
                            (x2 - x1) * (x2 - x1) + (y2 - y1)
                            * (y2 - y1) + (z2 - z1) * (z2 - z1))  # Length
                else:
                    length = link.mesh
                angle_lims = link.qlim  # Angle limits
                theta = link.theta  # Current angle
                i += 1
                self.append_link(j_type, pose, length, angle_lims, theta)

        # Add the robot to the canvas UI
        graphics_canvas.add_robot(self)
Пример #2
0
def _coulomb(n1, n2, k, r):
    """Calculates Coulomb forces and updates node data."""
    # Get relevant positional data
    delta = [x2 - x1 for x1, x2 in zip(n1['velocity'], n2['velocity'])]
    distance = sqrt(sum([d * d for d in delta]))

    # If the deltas are too small, use random values to keep things moving
    if distance < 0.1:
        delta = [uniform(0.1, 0.2) for i in range(3)]
        distance = sqrt(sum([d**2 for d in delta]))

    # If the distance isn't huge (ie. Coulomb is negligible), calculate
    if distance < r:
        force = (k / distance)**2
        n1['force'] = [f - force * d for f, d in zip(n1['force'], delta)]
        n2['force'] = [f + force * d for f, d in zip(n2['force'], delta)]
Пример #3
0
def _hooke(n1, n2, k, r):  #k and r are undefined!!!!
    """Calculates Hooke spring forces and updates node data."""
    # Get relevant positional data
    delta = [x2 - x1 for x1, x2 in zip(n1['velocity'], n2['velocity'])]
    distance = sqrt(sum([d**2 for d in delta]))

    # If the deltas are too small, use random values to keep things moving
    if distance < 0.1:
        delta = [uniform(0.1, 0.2) for i in range(3)]
        distance = sqrt(sum([d**2 for d in delta]))

    # Truncate distance so as to not have crazy springiness
    distance = min(distance, r)

    # Calculate Hooke force and update nodes
    force = (distance**2 - k**2) / (distance * k)

    n1['force'] = [f + force * d for f, d in zip(n1['force'], delta)]
    n2['force'] = [f - force * d for f, d in zip(n2['force'], delta)]
Пример #4
0
def create_binary_system(bounds: tuple) -> list:
    """Creates a binary system and returns the two stars in a list."""
    x_bound, y_bound, z_bound = bounds
    star_A = create_star(pos=(1 * AU, 0, 0),
                         mass=4 * 1.99E30,
                         vel=(0, 0, 0),
                         radius=4E10)
    star_B = create_star(pos=(-4 * AU, 0, 0),
                         mass=1.99E30,
                         vel=(0, 0, 0),
                         radius=2E10,
                         color=(1, 0, 0))
    star_A.vel = vp.vec(
        0, 0.1 * vp.sqrt((G * (star_A.mass + star_B.mass)) / (2 * AU)), 0)
    star_B.vel = -star_A.mass / star_B.mass * star_A.vel
    return [star_A, star_B]
Пример #5
0
    def __init__(self, graphics_canvas, name, seriallink=None):
        self.joints = []
        self.num_joints = 0
        self.rob_shown = True
        self.ref_shown = True
        self.opacity = 1
        self.name = name
        self.__scene = graphics_canvas

        self.angles = []
        self.seriallink = seriallink

        # If seriallink given, create the robot
        if self.seriallink is not None:
            # Update name
            self.name = self.seriallink.name
            # Get initial poses
            zero_angles = [0] * len(self.seriallink.links)
            all_poses = self.seriallink.fkine(zero_angles, alltout=True)
            # Create the base
            if seriallink.basemesh is not None:
                self.append_link("s", all_poses[0], str(seriallink.basemesh),
                                 [0, 0], 0)
            # else: assume no base joint
            # Create the joints
            i = 0
            for link in self.seriallink.links:
                # Get info
                j_type = link.jointtype  # Type of
                pose = all_poses[i + 1]  # Pose
                if link.mesh is None:
                    x1, x2 = all_poses[i].t[0], all_poses[i + 1].t[0]
                    y1, y2 = all_poses[i].t[1], all_poses[i + 1].t[1]
                    z1, z2 = all_poses[i].t[2], all_poses[i + 1].t[2]
                    length = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) *
                                  (y2 - y1) + (z2 - z1) * (z2 - z1))  # Length
                else:
                    length = str(link.mesh)
                angle_lims = link.qlim  # Angle limits
                theta = link.theta  # Current angle
                i += 1
                self.append_link(j_type, pose, length, angle_lims, theta)

        # Add the robot to the canvas UI
        graphics_canvas.add_robot(self)
Пример #6
0
def reset():
    global theta, thetadot, psi, psidot, phi, phidot
    theta = 0.3*vp.pi  # initial polar angle of shaft (from vertical)
    thetadot = 0  # initial rate of change of polar angle
    psi = 0  # initial spin angle
    psidot = 30  # initial rate of change of spin angle (spin ang. velocity)
    phi = -vp.pi/2  # initial azimuthal angle
    phidot = 0  # initial rate of change of azimuthal angle
    if pureprecession:  # Set to True if you want pure precession, without nutation
        a = (1-I3/I1)*vp.sin(theta)*vp.cos(theta)
        b = -(I3/I1)*psidot*vp.sin(theta)
        c = M*g*r*vp.sin(theta)/I1
        phidot = (-b+vp.sqrt(b**2-4*a*c))/(2*a)
    gyro.axis = gyro.length * \
        vp.vector(vp.sin(theta)*vp.sin(phi),
                  vp.cos(theta), vp.sin(theta)*vp.cos(phi))
    A = vp.norm(gyro.axis)
    gyro.pos = 0.5*Lshaft*A
    tip.pos = Lshaft*A
    tip.clear_trail()
def tetrahedron(radius=1, center=vpy.vec(0, 0, 0)):
    """
    Create a regular tetrahedron which corners are on a sphere of given radius
        and with the given centerpoint.
    A regular tetrahedron can be generated using four non-adjacent corners of a cube.
        That's how this tetrahedron is created.
    The tetrahedron edges are parallel to the angle bisectors of the x, y and z axes.
    """
    corners = [
        vpy.vec(1, 1, 1),
        vpy.vec(0, 0, 1),
        vpy.vec(1, 0, 0),
        vpy.vec(0, 1, 0)
    ]
    corners = [
        (corner - vpy.vec(.5, .5, .5)) * radius * 2 / vpy.sqrt(3) + center
        for corner in corners
    ]
    faces = [[0, 1, 2], [1, 0, 3], [0, 2, 3], [1, 3, 2]]
    return corners, faces
Пример #8
0
    def set_force(self, force, scale=1e-1, f_min = 0.1, f_max = 10.):
        """

        :param force: 3*2 states force
        :param scale: scaling in velocity
        :param f_min: minimal magnitude of force
        :param f_max: maximal magnitude of force
        """
        global game_objects
        orig = [force[:,0],force[:,1],force[:,2]]
        ff = [force[:,3]*scale,force[:,4]*scale,force[:,5]*scale]
        for ii in range(len(ff[0])):
            magn = vis.sqrt(ff[0][ii]*ff[0][ii]+ff[1][ii]*ff[1][ii]+ff[2][ii]*ff[2][ii])+1e-3
            if magn > f_max:
                ff[0][ii] = ff[0][ii] * f_max/magn
                ff[1][ii] = ff[1][ii] * f_max/magn
                ff[2][ii] = ff[2][ii] * f_max/magn
            if magn < f_min:
                ff[0][ii] = ff[0][ii] * f_min/magn
                ff[1][ii] = ff[1][ii] * f_min/magn
                ff[2][ii] = ff[2][ii] * f_min/magn

        v = Vector_dyn(orig, ff, 'F', self.p, pos=vis.vector(0,0,0), axis=vis.vector(5,0,0), shaftwidth=0.5, color=vis.color.red)
        game_objects.append( v )
Пример #9
0
def circle_point_upper(x, r):
    return sqrt(2 * r * x - x**2) + r
Пример #10
0
def circle_point_lower(x, r):
    return r - sqrt(2 * r * x - x**2)
Пример #11
0
def distance(a: vp.sphere, b: vp.sphere) -> float:
    """Returns the distance between two VPython spheres."""
    return vp.sqrt((a.pos.x - b.pos.x)**2 + (a.pos.y - b.pos.y)**2 +
                   (a.pos.z - b.pos.z)**2)
Пример #12
0
from vpython import sphere, box, cylinder, cone, color, curve, rate
from vpython import sqrt, atan, cos, sin, pi
from vpython import vector as vec

dirt = vec(1, 0.6, 0.4)

ground = box(color=dirt)
ground.axis = vec(1, 0, 1)
ground.size = vec(0.305 * 120 / sqrt(2), 0.305 * 1, 0.305 * 120 / sqrt(2))
ground.pos = 0.305 * vec(0, -0.5, 0)

mound = cone(color=dirt)
mound.axis = 0.305 * vec(0, 10 / 12, 0)
mound.radius = 0.305 * 9

pitcher = cylinder(color=color.red)
pitcher.pos = 0.305 * vec(0, 10 / 12, 0)
pitcher.axis = 0.305 * vec(0, 6, 0)

plate = box(color=color.yellow)
plate.size = vec(1, 0.1, 1)
plate.pos = 0.305 * vec(60.5, 0, 0)

strikezone = box(color=color.red)
strikezone.size = vec(0.305 / 12, 0.305 * 2, 0.305 * 2)
strikezone.pos = 0.305 * vec(60.5, 2.5, 0)


def in_boundary(x, bound, pos):
    return x - bound / 2 < pos < x + bound / 2
Пример #13
0

if __name__ == '__main__':

    osc0 = Coupled_Oscillator(k=1,
                              m=1,
                              radius=0.15,
                              length=1,
                              origin=vp.vector(0, 0, 0))
    osc1 = Coupled_Oscillator(k=1,
                              m=1,
                              radius=0.15,
                              length=1,
                              origin=vp.vector(osc0.body.pos))

    osc1.set_initial_conditions(osc1.body.pos, vp.vector(0.5, 0, 0))

    dt = 0.01 * 2 * vp.pi * vp.sqrt(osc0.m / osc0.k)

    while True:
        vp.rate(100)
        osc0.calculate_acceleration(osc1)
        osc1.calculate_acceleration()

        osc0.set_velocity(dt)
        osc1.set_velocity(dt)

        osc0.set_position(dt)
        osc1.update_origin(osc0.body.pos)
        osc1.set_position(dt)
Пример #14
0
import vpython as vp
N = 4  # N by N by N array of atoms
# Surrounding the N**3 atoms is another layer of invisible fixed-position atoms
# that provide stability to the lattice.
k = 1
m = 1
spacing = 1
atom_radius = 0.3*spacing
L0 = spacing-1.8*atom_radius
V0 = vp.pi*(0.5*atom_radius)**2*L0  # initial volume of spring
vp.scene.center = 0.5*(N-1)*vp.vector(1, 1, 1)
dt = 0.04*(2*vp.pi*vp.sqrt(m/k))
axes = [vp.vector(1, 0, 0), vp.vector(0, 1, 0), vp.vector(0, 0, 1)]

vp.scene.caption = """A model of a solid represented as atoms connected by interatomic bonds.

To rotate "camera", drag with right button or Ctrl-drag.
To zoom, drag with middle button or Alt/Option depressed, or use scroll wheel.
  On a two-button mouse, middle is left + right.
To pan left/right and up/down, Shift-drag.
Touch screen: pinch/extend to zoom, swipe or two-finger rotate."""


class crystal:

    def __init__(self,  N, atom_radius, spacing, momentumRange):
        self.atoms = []
        self.springs = []

        # Create (N+2)^3 atoms in a grid; the outermost atoms are fixed and invisible
        for z in range(-1, N+1, 1):
Пример #15
0
    def __init__(self, graphics_canvas, name, robot=None):
        self.joints = []
        self.num_joints = 0
        self.rob_shown = True
        self.ref_shown = True
        self.opacity = 1
        self.name = name
        self.__scene = graphics_canvas

        self.angles = []
        self.robot = robot

        # If Robot given, create the robot
        if self.robot is not None:
            # Update name
            self.name = self.robot.name
            # Get initial poses
            zero_angles = np.zeros((self.robot.n,))
            all_poses = self.robot.fkine_all(zero_angles, old=False)
            # Create the base
            try:
                if robot.basemesh is not None:
                    self.append_link("s", all_poses[0], robot.basemesh, [0, 0], 0)
            except:
                pass
            # else: assume no base joint
            robot_colours = robot.linkcolormap()
            # Create the joints
            for i, link in enumerate(self.robot.links):
                # Get info
                if link.isprismatic:
                    j_type = 'p'
                elif link.isrevolute:
                    j_type = 'r'
                else:
                    j_type = 's'
                pose = all_poses[i+1]   # link frame pose
                if link.mesh is None:
                    if i == 0:
                        x1, x2 = SE3().t[0], all_poses[i].t[0]
                        y1, y2 = SE3().t[1], all_poses[i].t[1]
                        z1, z2 = SE3().t[2], all_poses[i].t[2]
                        length = sqrt(
                            (x2 - x1) * (x2 - x1) + (y2 - y1)
                            * (y2 - y1) + (z2 - z1) * (z2 - z1))  # Length
                    else:
                        x1, x2 = all_poses[i - 1].t[0], all_poses[i].t[0]
                        y1, y2 = all_poses[i - 1].t[1], all_poses[i].t[1]
                        z1, z2 = all_poses[i - 1].t[2], all_poses[i].t[2]
                        length = sqrt(
                            (x2 - x1) * (x2 - x1) + (y2 - y1)
                            * (y2 - y1) + (z2 - z1) * (z2 - z1))  # Length
                else:
                    length = link.mesh
                angle_lims = link.qlim  # Angle limits
                theta = link.theta  # Current angle
                self.append_link(j_type, pose, length, angle_lims, theta)

            # Apply colours
            for i, joint in enumerate(self.joints):
                link_colour = list(robot_colours(i))[:3]
                joint.set_texture(colour=link_colour)

        # Add the robot to the canvas UI
        graphics_canvas.add_robot(self)
Пример #16
0
    def __handle_keyboard_inputs(self):
        """
        Pans amount dependent on distance between camera and focus point.
        Closer = smaller pan amount

        A = move left (pan)
        D = move right (pan)
        W = move up (pan)
        S = move down (pan)

        <- = rotate left along camera axes (rotate)
        -> = rotate right along camera axes (rotate)
        ^ = rotate up along camera axes (rotate)
        V = rotate down along camera axes (rotate)

        Q = roll left (rotate)
        E = roll right (rotate)

        ctrl + LMB = rotate (Default Vpython)
        """
        # If camera lock, just skip the function
        if self.__camera_lock:
            return

        # Constants
        pan_amount = 0.02  # units
        rot_amount = 1.0  # deg

        # Current settings
        cam_distance = self.scene.camera.axis.mag
        cam_pos = vector(self.scene.camera.pos)
        cam_focus = vector(self.scene.center)

        # Weird manipulation to get correct vector directions. (scene.camera.up always defaults to world up)
        cam_axis = (vector(self.scene.camera.axis))  # X
        cam_side_axis = self.scene.camera.up.cross(cam_axis)  # Y
        cam_up = cam_axis.cross(cam_side_axis)  # Z

        cam_up.mag = cam_axis.mag

        # Get a list of keys
        keys = keysdown()

        # Userpan uses ctrl, so skip this check to avoid changing camera pose while shift is held
        if 'shift' in keys:
            return

        ################################################################################################################
        # PANNING
        # Check if the keys are pressed, update vectors as required
        # Changing camera position updates the scene center to follow same changes
        if 'w' in keys:
            cam_pos = cam_pos + cam_up * pan_amount
        if 's' in keys:
            cam_pos = cam_pos - cam_up * pan_amount
        if 'a' in keys:
            cam_pos = cam_pos + cam_side_axis * pan_amount
        if 'd' in keys:
            cam_pos = cam_pos - cam_side_axis * pan_amount

        # Update camera position before rotation (to keep pan and rotate separate)
        self.scene.camera.pos = cam_pos

        ################################################################################################################
        # Camera Roll
        # If only one rotation key is pressed
        if 'q' in keys and 'e' not in keys:
            # Rotate camera up
            cam_up = cam_up.rotate(angle=-radians(rot_amount), axis=cam_axis)
            # Set magnitude as it went to inf
            cam_up.mag = cam_axis.mag
            # Set
            self.scene.up = cam_up

        # If only one rotation key is pressed
        if 'e' in keys and 'q' not in keys:
            # Rotate camera up
            cam_up = cam_up.rotate(angle=radians(rot_amount), axis=cam_axis)
            # Set magnitude as it went to inf
            cam_up.mag = cam_axis.mag
            # Set
            self.scene.up = cam_up

        ################################################################################################################
        # CAMERA ROTATION
        d = cam_distance
        move_dist = sqrt(d ** 2 + d ** 2 - 2 * d * d * cos(radians(rot_amount)))  # SAS Cosine

        # If only left not right key
        if 'left' in keys and 'right' not in keys:
            # Calculate distance to translate
            cam_pos = cam_pos + norm(cam_side_axis) * move_dist
            # Calculate new camera axis
            cam_axis = -(cam_pos - cam_focus)
        if 'right' in keys and 'left' not in keys:
            cam_pos = cam_pos - norm(cam_side_axis) * move_dist
            cam_axis = -(cam_pos - cam_focus)
        if 'up' in keys and 'down' not in keys:
            cam_pos = cam_pos + norm(cam_up) * move_dist
            cam_axis = -(cam_pos - cam_focus)
        if 'down' in keys and 'up' not in keys:
            cam_pos = cam_pos - norm(cam_up) * move_dist
            cam_axis = -(cam_pos - cam_focus)

        # Update camera position and axis
        self.scene.camera.pos = cam_pos
        self.scene.camera.axis = cam_axis
Пример #17
0
Created on Thu Feb 11 13:58:34 2021

@author: Andrea Bassi
"""
import vpython as vp

from simple_oscillator_with_class import Oscillator


class Dumped_Oscillator(Oscillator):
    def __init__(self, k, m, beta, radius, length):
        super().__init__(k, m, radius, length)
        self.beta = beta

    def dump(self):
        self.acceleration += -self.beta * self.body.velocity / self.m


osc = Dumped_Oscillator(k=1, m=1, beta=0.1, radius=0.15, length=1)

osc.set_initial_conditions(vp.vector(1.5, 0, 0), vp.vector(0, 0, 0))

dt = 0.01 * 2 * vp.pi * vp.sqrt(osc.m / osc.k)

while True:
    vp.rate(100)
    osc.calculate_acceleration()
    osc.dump()
    osc.set_velocity(dt)
    osc.set_position(dt)
    def set_clip_poly(self, shape_str="cuboid", size=None, show_edges=True):
        """
        define a polyhedron to set the shape of the puzzle.
        saves the polyhedron as self.clip_poly
            and displays it with low opacity

        inputs:
        -------
            shape_str - (str) - the shape of the polyhedron
                current options:
                    - 'cuboid' = 'c' (default)
                    - 'cube'
                    - 'octahedron' = 'oct'
                    - 'tetrahedron' = 'tet'
            size - (float) or (vpy.vector) - if shape is a cuboid,
                this has to be a vpython vector, otherwise it needs to be a float

        raises:
        -------
            - ValueError if the shape is not valid
            - TypeError if the shape is not given as a string
        """
        if not isinstance(shape_str, str):
            raise TypeError(f"'shape_str' should be of type 'str' \
but was of type '{type(shape_str)}'")
        if hasattr(self, "clip_poly"):
            self.clip_poly.obj.visible = False
            # if isinstance(self.clip_poly, Polyhedron):
            #     self.clip_poly.toggle_visible(False)
            # else:
        if shape_str in ("cuboid", "c"):
            if size == None:
                xsize = max([obj.pos.x for obj in self.vpy_objects]) \
                      + abs(min([obj.pos.x for obj in self.vpy_objects]))
                ysize = max([obj.pos.y for obj in self.vpy_objects]) \
                      + abs(min([obj.pos.y for obj in self.vpy_objects]))
                zsize = max([obj.pos.z for obj in self.vpy_objects]) \
                      + abs(min([obj.pos.z for obj in self.vpy_objects]))
                size = vpy.vec(xsize, ysize, zsize)
            elif isinstance(size, (float, int)):
                size = vpy.vec(size, size, size)
            corners, faces = shapes["cuboid"](size=size)

        elif shape_str in ("tetrahedron", "tet"):
            if size == None:
                size = 2 * max([obj.pos.mag for obj in self.vpy_objects])
            corners, faces = shapes["tetrahedron"](radius=size)

        elif shape_str in ("cube"):
            if size == None:
                size = 2*max(
                    [max([abs(obj.pos.x), abs(obj.pos.y), abs(obj.pos.z)]) \
                    for obj in self.vpy_objects])
            corners, faces = shapes["cube"](sidelength=size)

        elif shape_str in ("octahedron", "oct"):
            if size == None:
                size = 2 * max([obj.pos.mag for obj in self.vpy_objects])
            corners, faces = shapes["octahedron"](radius=size)
        elif shape_str in ("cylinder", "cyl"):
            if size == None:
                size = max([
                    vpy.sqrt(obj.pos.x**2 + obj.pos.y**2)
                    for obj in self.vpy_objects
                ])
            height = max([obj.pos.z for obj in self.vpy_objects]) \
                   + abs(min([obj.pos.z for obj in self.vpy_objects]))
            corners, faces = shapes["cylinder"](radius=size, height=height)
        else:
            raise ValueError(
                f"Invalid shape. Got {shape_str} but expected one of ['c', 'cuboid', 'tetrahedron', 'cube', 'oct', 'octahedron']."
            )
        self.clip_poly = Polyhedron(corners,
                                    faces,
                                    opacity=.2,
                                    color=vpy.vec(0.4, 0, 0.6),
                                    show_edges=show_edges,
                                    show_corners=show_edges)
Пример #19
0
    vp.vector(d, d, -d),
    vp.vector(-d, d, -d)
])
vert1 = vp.curve(color=gray, radius=r)
vert2 = vp.curve(color=gray, radius=r)
vert3 = vp.curve(color=gray, radius=r)
vert4 = vp.curve(color=gray, radius=r)
vert1.append([vp.vector(-d, -d, -d), vp.vector(-d, d, -d)])
vert2.append([vp.vector(-d, -d, d), vp.vector(-d, d, d)])
vert3.append([vp.vector(d, -d, d), vp.vector(d, d, d)])
vert4.append([vp.vector(d, -d, -d), vp.vector(d, d, -d)])

Atoms = []
p = []
apos = []
pavg = vp.sqrt(2 * mass * 1.5 * k *
               T)  # average kinetic energy p**2/(2mass) = (3/2)kT

for i in range(Natoms):
    x = L * vp.random() - L / 2
    y = L * vp.random() - L / 2
    z = L * vp.random() - L / 2
    if i == 0:
        Atoms.append(
            vp.sphere(pos=vp.vector(x, y, z),
                      radius=Ratom,
                      color=vp.color.cyan,
                      make_trail=True,
                      retain=100,
                      trail_radius=0.3 * Ratom))
    else:
        Atoms.append(