Exemplo n.º 1
0
def animate_traj(traj):
    mesh = trimesh.load_mesh('../models/ionsat.stl')
    bounds = np.array(mesh.bounds)
    mesh.apply_translation(-(bounds[0] + bounds[1]) / 2)
    mesh.apply_scale(2)
    satellite = vp.compound([
        vp.triangle(vs=[
            vp.vertex(pos=vp.vector(*vertex),
                      normal=vp.vector(*mesh.face_normals[itri]))
            for vertex in triangle
        ]) for itri, triangle in enumerate(mesh.triangles)
    ])
    satellite = vp.compound([
        satellite, *[
            vp.arrow(
                pos=vp.vector(0, 0, 0), axis=axis, shaftwidth=0.01, color=axis)
            for axis in (vp.vector(1, 0, 0), vp.vector(0, 1, 0),
                         vp.vector(0, 0, 1))
        ]
    ])  # add frame to the satellite
    wind = vp.arrow(pos=vp.vector(0, 0, -3),
                    axis=vp.vector(0, 0, 1),
                    shaftwidth=0.01,
                    color=vp.vector(1, 1, 1))
    prevQ = None
    for Q in traj:
        if prevQ is not None:
            satellite.rotate(angle=-prevQ.angle(),
                             axis=vp.vector(*prevQ.axis()),
                             origin=vp.vector(0, 0, 0))
        satellite.rotate(angle=Q.angle(),
                         axis=vp.vector(*Q.axis()),
                         origin=vp.vector(0, 0, 0))
        prevQ = Q
        vp.rate(25)
Exemplo n.º 2
0
def draw_mesh(mesh_list, opacity=0.5):
    """
    Draw meshes to the scene.

    Args:
        mesh_list(list): A list of Mesh objects that should be drawn on the scene.
        opacity(float): Optional. Opacity of the mesh objects.
    Returns:
        A list of vpython.compound objects that represent the meshes.
    """
    compounds = {}
    for mesh in mesh_list:
        surfaces = []
        for surface in mesh.surfaces:
            vertices = []
            for vertex in surface.vertices:
                v_pos = vertex.pos
                v = vpython.vertex(
                    pos=vpython.vec(v_pos[0], v_pos[1], v_pos[2]))
                v.opacity = opacity
                if surface.collision:
                    v.color = vpython.vec(1.0 - mesh.color[0],
                                          1.0 - mesh.color[1],
                                          1.0 - mesh.color[2])
                else:
                    v.color = vpython.vec(mesh.color[0], mesh.color[1],
                                          mesh.color[2])
                vertices.append(v)
            surfaces.append(
                vpython.triangle(vs=[vertices[0], vertices[1], vertices[2]]))
        compounds[mesh.name] = vpython.compound(surfaces)
        # compounds[mesh.name].pickable = False
        compounds[mesh.name].name = mesh.name
    return compounds
Exemplo n.º 3
0
def set_stl_origin(stl_obj, current_obj_origin, required_obj_origin, scene):
    """
    Move the object so the required origin is at (0, 0, 0). Then set the origin for the generated stl object.
    Origin can't be changed, so creating a compound of itself allows setting an origin location

    :param stl_obj: The generated stl object.
    :type stl_obj: class:`vpython.compound`
    :param current_obj_origin: Current coordinates of the origin of the model
    :type current_obj_origin: class:`vpython.vector`
    :param required_obj_origin: Required coordinates to place the origin at (0, 0, 0)
    :type required_obj_origin: class:`vpython.vector`
    :param scene: The scene in which to draw the object
    :type scene: class:`vpython.canvas`
    :return: Compound object of itself, with origin set respective to the joint
    :rtype: class:`vpython.compound`
    """
    # Move the object to put the origin at 0, 0, 0
    movement = required_obj_origin - current_obj_origin
    stl_obj.pos += movement

    # Set invisible to return an overwritten copy
    stl_obj.visible = False

    # Return a compound of itself with the origin at (0, 0, 0)
    return compound([stl_obj],
                    origin=vector(0, 0, 0),
                    vector=x_axis_vector,
                    canvas=scene)
Exemplo n.º 4
0
    def __set_graphic(self, structure):
        """
        Set the graphic object depending on if one was given. If no object was given, create a box and return it

        :param structure: `float` or `str` representing the joint length or STL path to load from
        :type structure: `float`, `str`
        :raises ValueError: Joint length must be greater than 0
        :return: Graphical object for the joint
        :rtype: class:`vpython.compound`
        """
        if isinstance(structure, float):
            length = structure
            if length <= 0.0:
                raise ValueError("Joint length must be greater than 0")

            box_midpoint = vector(length / 2, 0, 0)

            # Create a box along the +x axis, with the origin (point of rotation) at (0, 0, 0)
            graphic_obj = box(canvas=self.__scene,
                              pos=vector(box_midpoint.x, box_midpoint.y,
                                         box_midpoint.z),
                              axis=x_axis_vector,
                              size=vector(length, 0.1, 0.1),
                              up=y_axis_vector)

            # Set the boxes new origin
            graphic_obj = compound([graphic_obj],
                                   origin=vector(0, 0, 0),
                                   axis=x_axis_vector,
                                   up=y_axis_vector)

            return graphic_obj
        else:
            return import_object_from_numpy_stl(structure, self.__scene)
Exemplo n.º 5
0
def make_robot():
    chassis_width = 155  # left side to right
    chassis_thickness = 3  # plastic thickness
    chassis_length = 200  # front to back
    wheel_thickness = 26
    wheel_diameter = 70
    axle_x = 30  # wheel axle from
    axle_z = -20
    rear_castor_position = vp.vector(-80, -6, -30)
    rear_castor_radius = 14
    rear_caster_thickness = 12

    base = vp.box(length=chassis_length,
                  height=chassis_thickness,
                  width=chassis_width)
    # rotate to match body - so Z is height and Y is width
    base.rotate(angle=vp.radians(90), axis=vp.vector(1, 0, 0))
    wheel_dist = chassis_width / 2
    wheel_l = vp.cylinder(radius=wheel_diameter / 2,
                          length=wheel_thickness,
                          pos=vp.vector(axle_x, -wheel_dist, axle_z),
                          axis=vp.vector(0, -1, 0))
    wheel_r = vp.cylinder(radius=wheel_diameter / 2,
                          length=wheel_thickness,
                          pos=vp.vector(axle_x, wheel_dist, axle_z),
                          axis=vp.vector(0, 1, 0))
    rear_castor = vp.cylinder(radius=rear_castor_radius,
                              length=rear_caster_thickness,
                              pos=rear_castor_position,
                              axis=vp.vector(0, 1, 0))
    return vp.compound([base, wheel_l, wheel_r, rear_castor])
Exemplo n.º 6
0
 def __init__(self,
              x,
              y,
              shape='_',
              colour=color.white,
              player='first',
              opacity=1):
     self.x_pos = x
     self.y_pos = y
     self.shape = shape
     self.color = colour
     self.blocks = []
     radius = 0.23 if player == 'first' else 0.22
     for _ in range(3):
         block = compound([
             box(pos=vector(x, y, 0),
                 height=.8,
                 width=.8,
                 length=.8,
                 opacity=opacity),
             sphere(pos=vector(x, y, 0.5), radius=radius, opacity=opacity),
             sphere(pos=vector(x, y, -0.5), radius=radius, opacity=opacity)
         ])
         self.blocks.append(block)
     self.shape_dictionary = {
         '_': (0, 0, 1, 0, 2, 0),
         'I': (0, 0, 0, 1, 0, 2),
         'b': (0, 0, 1, 0, 0, 1),
         'd': (0, 0, 1, 0, 1, 1),
         'p': (0, 0, 0, 1, 1, 1),
         'q': (0, 1, 1, 0, 1, 1),
     }
     self.updater(self.x_pos, self.y_pos)
Exemplo n.º 7
0
    def draw_robot(self):  # retornar el centro de masa
        if self.robot_type == 0:
            caja = box(pos=self.initialPosition,
                       size=self.size,
                       color=self.color)
            rueda_trasera = cylinder(
                pos=caja.pos -
                vector(caja.size.x / 4, caja.size.y, caja.size.z / 4),
                axis=vector(0, 4, 0),
                radius=0.5,
                color=self.color)
            rueda_delantera = cylinder(
                pos=caja.pos +
                vector(caja.size.x / 4, -caja.size.y, -caja.size.z / 4),
                axis=vector(0, 4, 0),
                radius=0.5,
                color=self.color)

            robot = compound([caja, rueda_trasera, rueda_delantera])
        elif self.robot_type == 1:
            cuerpo = cylinder(pos=self.initialPosition,
                              radius=3,
                              color=color.blue,
                              axis=vector(0, 0, 1),
                              opacity=1)
            rueda_1 = cylinder(pos=cuerpo.pos +
                               vector(0, cuerpo.radius / 2, 0),
                               radius=cuerpo.radius / 4,
                               color=color.red,
                               axis=vector(0, 1, 0),
                               opacity=1)
            rueda_2 = cylinder(
                pos=cuerpo.pos -
                vector(0, cuerpo.radius / 2 + cuerpo.radius / 3, 0),
                radius=cuerpo.radius / 4,
                color=color.cyan,
                axis=vector(0, 1, 0),
                opacity=1)
            estabilizador = sphere(
                pos=cuerpo.pos +
                vector(cuerpo.radius / 2 + cuerpo.radius / 9, 0, 0),
                radius=cuerpo.radius / 4,
                color=color.green,
                axis=vector(0, 1, 0),
                opacity=1)
            robot = compound([cuerpo, rueda_1, rueda_2, estabilizador])
        return robot
Exemplo n.º 8
0
def import_object_from_stl(filename):
    """
    Import an stl object and convert it into a usable vpython object.
    Function not directly part of the vpython package, but can by found as part of vpython git repo.
    Code was based on it.
    https://github.com/vpython/vpython-jupyter/blob/master/convert_stl.zip

    :param filename: Name of the stl file to import (Exclude path and extension).
    :type filename: `str`
    :return: Compound object of a collection of triangles formed from an stl file.
    :rtype: class:`vpython.compound`

    .. deprecated::
        A new function using numpy import is available. It accepts both ASCII and BINARY formats.
    """
    raise DeprecationWarning("This function is outdated. Use import_object_from_numpy_stl")

    # Open the file
    filepath = './graphics/models/' + filename + '.stl'
    stl_file = open(filepath, mode='rb')
    stl_file.seek(0)
    stl_text = stl_file.readlines()

    # Initial Conditions
    triangles = []
    vertices = []
    normal = None

    # For every line in the file
    for line in stl_text:
        file_line = line.split()
        # If blank line (skip)
        if not file_line:
            pass
        # If a face
        elif file_line[0] == b'facet':
            normal = vec(
                float(file_line[2]),
                float(file_line[3]),
                float(file_line[4])
            )
        # If a vertex
        elif file_line[0] == b'vertex':
            vertices.append(
                vertex(
                    pos=vec(
                        float(file_line[1]),
                        float(file_line[2]),
                        float(file_line[3])
                    ),
                    normal=normal,
                    color=color.white
                )
            )
            if len(vertices) == 3:
                triangles.append(triangle(vs=vertices))
                vertices = []

    return compound(triangles)
Exemplo n.º 9
0
def import_object_from_numpy_stl(filename, scene):
    """
    Import either an ASCII or BINARY file format of an STL file.
    The triangles will be combined into a single compound entity.

    :param filename: Path of the stl file to import.
    :type filename: `str`
    :param scene: The scene in which to draw the object
    :type scene: class:`vpython.canvas`
    :return: Compound object of a collection of triangles formed from an stl file.
    :rtype: class:`vpython.compound`
    """
    # Load the mesh using NumPy-STL
    the_mesh = mesh.Mesh.from_file(filename)

    num_faces = len(the_mesh.vectors)
    triangles = []

    # For every face in the model
    for face in range(0, num_faces):
        # Get the (3) 3D points
        point0 = the_mesh.vectors[face][0]
        point1 = the_mesh.vectors[face][1]
        point2 = the_mesh.vectors[face][2]

        # Get the normal direction for the face
        normal0 = the_mesh.normals[face][0]
        normal1 = the_mesh.normals[face][1]
        normal2 = the_mesh.normals[face][2]
        normal = vec(normal0, normal1, normal2)

        # Create the VPython 3D points
        vertex0 = vertex(
            pos=vec(point0[0], point0[1], point0[2]),
            normal=normal,
            color=color.white
        )
        vertex1 = vertex(
            pos=vec(point1[0], point1[1], point1[2]),
            normal=normal,
            color=color.white
        )
        vertex2 = vertex(
            pos=vec(point2[0], point2[1], point2[2]),
            normal=normal,
            color=color.white
        )

        # Combine them in a list
        vertices = [vertex0, vertex1, vertex2]

        # Create a triangle using the points, and add it to the list
        triangles.append(triangle(canvas=scene, vs=vertices))

    # Return a compound of the triangles
    visual_mesh = compound(triangles, origin=vector(0, 0, 0), canvas=scene)
    return visual_mesh
Exemplo n.º 10
0
def draw_compound(xys):
    return compound([
        quad(vs=[
            vertex(pos=points[_idx[(x + dx, y + dy)]],
                   normal=points_n[_idx[x + dx, y + dy]],
                   color=colors[_idx[(x + dx, y + dy)]])
            for dx, dy in [(0, 0), (D, 0), (D, D), (0, D)]
        ]) for x, y in xys
    ])
Exemplo n.º 11
0
 def __init__(self,
              x,
              y,
              shape='O',
              colour=color.white,
              player='first',
              opacity=1):
     self.x_pos = x
     self.y_pos = y
     self.shape = shape
     self.color = colour
     self.orientation = '0'
     self.blocks = []
     radius = 0.23 if player == 'first' else 0.22
     for _ in range(4):
         block = compound([
             box(pos=vector(x, y, 0),
                 height=.8,
                 width=.8,
                 length=.8,
                 opacity=opacity),
             sphere(pos=vector(x, y, 0.5), radius=radius, opacity=opacity),
             sphere(pos=vector(x, y, -0.5), radius=radius, opacity=opacity)
         ])
         self.blocks.append(block)
     self.shape_dictionary = {
         ('I', '0'): (-1, 0, 0, 0, 1, 0, 2, 0),
         ('I', '1'): (0, -1, 0, 0, 0, 1, 0, 2),
         ('I', '2'): (-1, 0, 0, 0, 1, 0, 2, 0),
         ('I', '3'): (0, -1, 0, 0, 0, 1, 0, 2),
         ('J', '0'): (-1, 0, 0, 0, 1, 0, -1, 1),
         ('J', '1'): (0, -1, 0, 0, 0, 1, -1, -1),
         ('J', '2'): (-1, 0, 0, 0, 1, 0, 1, -1),
         ('J', '3'): (0, -1, 0, 0, 0, 1, 1, 1),
         ('T', '0'): (-1, 0, 0, 0, 1, 0, 0, 1),
         ('T', '1'): (0, 0, 0, -1, 0, 1, -1, 0),
         ('T', '2'): (-1, 0, 0, 0, 1, 0, 0, -1),
         ('T', '3'): (0, 0, 0, -1, 0, 1, 1, 0),
         ('S', '0'): (1, 0, 0, 0, 1, 1, 2, 1),
         ('S', '1'): (1, 1, 1, 0, 0, 1, 0, 2),
         ('S', '2'): (1, 0, 0, 0, 1, 1, 2, 1),
         ('S', '3'): (1, 1, 1, 0, 0, 1, 0, 2),
         ('Z', '0'): (1, 1, 0, 1, 1, 0, 2, 0),
         ('Z', '1'): (0, 1, 0, 0, 1, 1, 1, 2),
         ('Z', '2'): (1, 1, 0, 1, 1, 0, 2, 0),
         ('Z', '3'): (0, 1, 0, 0, 1, 1, 1, 2),
         ('O', '0'): (1, 0, 0, 0, 0, 1, 1, 1),
         ('O', '1'): (1, 0, 0, 0, 0, 1, 1, 1),
         ('O', '2'): (1, 0, 0, 0, 0, 1, 1, 1),
         ('O', '3'): (1, 0, 0, 0, 0, 1, 1, 1),
         ('L', '0'): (-1, 0, 0, 0, 1, 0, 1, 1),
         ('L', '1'): (0, -1, 0, 0, 0, 1, -1, 1),
         ('L', '2'): (-1, 0, 0, 0, 1, 0, -1, -1),
         ('L', '3'): (0, -1, 0, 0, 0, 1, 1, -1),
     }
     self.updater(self.x_pos, self.y_pos, orientation=self.orientation)
Exemplo n.º 12
0
def make_capsule(R, L):
    parts = []
    sph1 = sphere(pos=vec(R, 0, 0), radius=R, color=color.cyan, opacity=0.3)
    cyl = cylinder(pos=vec(R, 0, 0), axis=vec(L - 2 * R, 0, 0), radius=R, color=color.cyan, opacity=0.3)
    sph2 = sphere(pos=sph1.pos+cyl.axis, radius=R, color=color.cyan, opacity=0.3)
    parts.append(sph1)
    parts.append(cyl)
    parts.append(sph2)
    obj = compound(parts)
    return obj
Exemplo n.º 13
0
def show(mesh, Qs=None):
    """
    if Qs is None, will display the original situation of the satellite
    if Qs is a single Quaternion, will display the satellite in this situation
    if Qs is a list, wil display step by step every situations
    """
    if Qs is None:
        Qs = [loas.Quat(1, 0, 0, 0)]
    elif type(Qs) != list:
        Qs = [Qs]
    bounds = np.array(mesh.bounds)
    mesh.apply_scale(1 / np.linalg.norm(mesh.extents))  # auto resize
    satellite = vp.compound([
        vp.triangle(vs=[
            vp.vertex(pos=vp.vector(*vertex),
                      normal=vp.vector(*mesh.face_normals[itri]))
            for vertex in triangle
        ]) for itri, triangle in enumerate(mesh.triangles)
    ])
    satellite = vp.compound([
        satellite, *[
            vp.arrow(
                pos=vp.vector(0, 0, 0), axis=axis, shaftwidth=0.01, color=axis)
            for axis in (vp.vector(1, 0, 0), vp.vector(0, 1, 0),
                         vp.vector(0, 0, 1))
        ]
    ])  # add frame to the satellite
    wind = vp.arrow(pos=vp.vector(0, 0, 3),
                    axis=vp.vector(0, 0, -1),
                    shaftwidth=0.01,
                    color=vp.vector(1, 1, 1))
    prevQ = None
    for Q in Qs:
        if prevQ is not None:
            satellite.rotate(angle=-prevQ.angle(),
                             axis=vp.vector(*prevQ.axis()),
                             origin=vp.vector(0, 0, 0))
        satellite.rotate(angle=Q.angle(),
                         axis=vp.vector(*Q.axis()),
                         origin=vp.vector(0, 0, 0))
        prevQ = Q
        vp.rate(2)
def draw_reference_frame_axes(se3_pose, scene):
    """
    Draw x, y, z axes from the given point.
    Each axis is represented in the objects reference frame.


    :param se3_pose: SE3 pose representation of the reference frame
    :type se3_pose: class:`spatialmath.pose3d.SE3`
    :param scene: Which scene to put the graphics in
    :type scene: class:`vpython.canvas`
    :return: Compound object of the 3 axis arrows.
    :rtype: class:`vpython.compound`
    """

    origin = get_pose_pos(se3_pose)
    x_axis = get_pose_x_vec(se3_pose)
    y_axis = get_pose_y_vec(se3_pose)

    # Create Basic Frame
    # Draw X Axis
    x_arrow = arrow(canvas=scene,
                    pos=origin,
                    axis=x_axis_vector,
                    length=0.25,
                    color=color.red)

    # Draw Y Axis
    y_arrow = arrow(canvas=scene,
                    pos=origin,
                    axis=y_axis_vector,
                    length=0.25,
                    color=color.green)

    # Draw Z Axis
    z_arrow = arrow(canvas=scene,
                    pos=origin,
                    axis=z_axis_vector,
                    length=0.25,
                    color=color.blue)

    # Combine all to manipulate together
    # Set origin to where axis converge (instead of the middle of the resulting object bounding box)
    frame_ref = compound([x_arrow, y_arrow, z_arrow],
                         origin=origin,
                         canvas=scene)

    # Set frame axes
    frame_ref.axis = x_axis
    frame_ref.up = y_axis

    return frame_ref
    def __init__(self,
                 corners,
                 faces,
                 color=vpy.vec(.3, .3, .8),
                 opacity=1,
                 show_faces=True,
                 show_edges=True,
                 sort_faces=True,
                 debug=False):
        """
        inputs:
        -------
            corners - (list) of vpython.vectors- list of 3d coordinates of the corners of the polyhedron
            faces - (list) of lists - lists of corner indices. one sub-list per face of the polyhedron

        examples:
        ---------
            # create a small pyramid
            >>> corners = [(0,0,0), (1,0,0), (0,1,0), (0,0,1)]
            >>> corners = [vpy.vec(*corner) for corner in corners]
            >>> faces = [[0,1,2], [1,2,3], [0,1,3], [0,2,3]]
            >>> poly = polyhedron(corners, faces)
        """
        self.debug = debug
        self.color = color
        self._objects = []
        self.vertices = [
            vpy.vertex(pos=corner, color=self.color, opacity=opacity)
            for corner in corners
        ]
        # self.vertices = [vpy.vertex(pos=corner, color=corner, opacity=opacity) for corner in corners]
        self.pos = get_com(self.vertices)

        self.faces = faces
        self.face_centers = self._get_face_centers()
        if sort_faces:  # sort the faces so that the polygons are displayed without holes
            self._sort_faces()
        if show_edges:
            self.draw_all_edges()
        if show_faces:
            self.draw_faces()
        # if self.debug:
        #     self.show_faces()
        self.obj = vpy.compound(self._objects)
        for obj in self._objects:
            obj.visible = 0
Exemplo n.º 16
0
def create_landscape_from_points():
    # --- create quads
    quadlist = []
    for y, line in enumerate(Game.points):
        for x, point in enumerate(line):
            #a = point
            try:
                a = Game.points[y][x]
                b = Game.points[y][x + 1]
                c = Game.points[y + 1][x + 1]
                d = Game.points[y + 1][x]
            except IndexError:
                continue
            quadlist.append(v.quad(vs=[a, b, c, d]))

    Game.landscape = v.compound(quadlist,
                                origin=v.vector(0, 0, 0),
                                pos=v.vector(0, 0, 0))
Exemplo n.º 17
0
def make_ramp(alpha, H):
    parts = []
    B = H * sin(0.5 * pi - alpha) / sin(alpha)
    front = triangle(
        v0=vertex(pos=vec(-0.5 * B, 0, 0.25 * H)),
        v1=vertex(pos=vec(-0.5 * B, H, 0.25 * H)),
        v2=vertex(pos=vec(0.5 * B, 0, 0.25 * H))
    )
    back = triangle(
        v0=vertex(pos=vec(-0.5 * B, 0, - 0.25 * H)),
        v1=vertex(pos=vec(-0.5 * B, H, - 0.25 * H)),
        v2=vertex(pos=vec(0.5 * B, 0, - 0.25 * H))
    )
    top = quad(
        v0=front.v1,
        v1=back.v1,
        v2=back.v2,
        v3=front.v2,
    )
    bottom = quad(
        v0=front.v0,
        v1=back.v0,
        v2=back.v2,
        v3=front.v2
    )
    side = quad(
        v0=front.v0,
        v1=back.v0,
        v2=back.v1,
        v3=front.v1
    )
    parts.append(front)
    parts.append(back)
    parts.append(top)
    parts.append(bottom)
    parts.append(side)
    obj = compound(parts)
    obj.height = H
    obj.base = B
    obj.angle = alpha
    # obj.color = color.cyan
    # obj.opacity = 0.1

    return obj
    def __set_graphic(self, structure, axis_through):
        """
        Set the graphic object depending on if one was given. If no object was
        given, create a box and return it

        :param structure: `float` or `str` representing the joint length or
            STL path to load from
        :type structure: `float`, `str`
        :param axis_through: The axis that the longest side goes through
        :type axis_through: class:`numpy.ndarray`
        :raises ValueError: Joint length must be greater than 0
        :return: Graphical object for the joint
        :rtype: class:`vpython.compound`
        """
        if isinstance(structure, float):
            length = structure
            if length <= 0.0:
                raise ValueError("Joint length must be greater than 0")
            axis = vector(axis_through[0], axis_through[1], axis_through[2])
            axis.mag = length

            box_midpoint = axis / 2
            box_tooltip = axis

            # Create a box along the +x axis, with the origin
            # (point of rotation) at (0, 0, 0)
            graphic_obj = box(
                canvas=self.__scene,
                pos=vector(box_midpoint.x, box_midpoint.y, box_midpoint.z),
                axis=axis,
                size=vector(length, 0.1, 0.1),  # L, W, H
                # up=y_axis_vector
            )

            # Set the boxes new origin
            graphic_obj = compound([graphic_obj],
                                   origin=box_tooltip,
                                   axis=axis)

            return graphic_obj
        else:
            # self.stl_offset = structure[2]
            return import_object_from_numpy_stl(structure, self.__scene)
Exemplo n.º 19
0
    def _create_obj(self, entity: Entity, origin: Entity,
                    texture: Optional[str]) -> vpython.sphere:
        main_body = vpython.box()
        side_panels = vpython.box(height=2, width=0.5, length=0.6)
        obj = vpython.compound([main_body, side_panels],
                               make_trail=True,
                               texture=texture,
                               bumpmap=vpython.textures.gravel)
        obj.pos = entity.screen_pos(origin)
        obj.axis = calc.angle_to_vpy(entity.heading)
        obj.length = entity.r * 2
        obj.height = entity.r * 2
        obj.width = entity.r * 2

        # A compound object doesn't actually have a radius, but we need to
        # monkey-patch this for when we recentre the camera, to determine the
        # relevant_range of the space station
        obj.radius = entity.r
        return obj
Exemplo n.º 20
0
 def graphic(size: float):
     # Iterate over a list of Point 3-tuples, each representing the
     # vertices of a triangle in the sphere segment.
     vpython_tris = []
     for tri in calc._build_sphere_segment_vertices(entity.r, size):
         # TODO: we pick an ocean blue colour for Earth, but really we
         # should find a better way to make the landing graphic not a
         # hardcoded value after the demo.
         vpython_verts = [
             vpython.vertex(pos=vpython.vector(*coord),
                            color=(vpython.vector(0, 0.6, 0.8)
                                   if entity.name == common.EARTH else
                                   vpython.vector(0.5, 0.5, 0.5)))
             for coord in tri
         ]
         vpython_tris.append(vpython.triangle(vs=vpython_verts))
     return vpython.compound(vpython_tris,
                             opacity=0,
                             pos=self._obj.pos,
                             up=common.DEFAULT_UP)
Exemplo n.º 21
0
    def _create_obj(self, entity: Entity, origin: Entity,
                    texture_path: Optional[str]) -> vpython.sphere:
        ship = vpython.cone(pos=vpython.vector(5, 0, 0),
                            axis=vpython.vector(5, 0, 0),
                            radius=3)
        entrance = vpython.extrusion(
            path=[vpython.vec(0, 0, 0),
                  vpython.vec(4, 0, 0)],
            shape=[
                vpython.shapes.circle(radius=3),
                vpython.shapes.rectangle(pos=[0, 0], width=0.5, height=0.5)
            ],
            pos=vpython.vec(3, 0, 0))

        docking_arm = vpython.extrusion(
            path=[
                vpython.vec(0, 0, 0),
                vpython.vec(1.5, 0, 0),
                vpython.vec(1.5, 0.5, 0)
            ],
            shape=[vpython.shapes.circle(radius=0.03)])

        obj = vpython.compound([ship, entrance, docking_arm],
                               make_trail=True,
                               texture=vpython.textures.metal,
                               bumpmap=vpython.bumpmaps.gravel)
        obj.pos = entity.screen_pos(origin)
        obj.axis = calc.angle_to_vpy(entity.heading)
        obj.length = entity.r * 2
        obj.height = entity.r * 2
        obj.width = entity.r * 2

        # A compound object doesn't actually have a radius, but we need to
        # monkey-patch this for when we recentre the camera, to determine the
        # relevant_range of the space station
        obj.radius = entity.r

        return obj
Exemplo n.º 22
0
def show(modelPath, posX, posY, angle, size):
    global models
    global s

    if (len(s.objects) >= 65535):
        return 0
    f = []

    model = open(modelPath, "r")

    lines = model.read().split("\n")

    v = []
    n = []
    f = []

    minV = [0, 0, 0]
    maxV = [0, 0, 0]

    vertexCount = 0

    # Parse the OBJ file

    for line in lines:
        e = line.split(" ")
        if (e[0] == "v"):
            v.append(vec(float(e[1]), -float(e[3]), -float(e[2])))
            minV, maxV = minmaxVertices(
                minV, maxV, [float(e[1]), -float(e[3]), -float(e[2])])
        elif (e[0] == "vn"):
            n.append(vec(float(e[1]), -float(e[3]), -float(e[2])))
        elif (e[0] == "f"):
            if vertexCount < 65533:
                t0 = e[1].split("/")
                t1 = e[2].split("/")
                t2 = e[3].split("/")
                vert0 = vertex(pos=v[int(t0[0]) - 1], normal=n[int(t0[2]) - 1])
                vert1 = vertex(pos=v[int(t1[0]) - 1], normal=n[int(t1[2]) - 1])
                vert2 = vertex(pos=v[int(t2[0]) - 1], normal=n[int(t2[2]) - 1])
                f.append(triangle(vs=[vert0, vert1, vert2]))
                vertexCount += 3

    modelSize = max(maxV[0] - minV[0], maxV[1] - minV[1], maxV[2] - minV[2])

    models.append(compound(f))

    origin = numpy.array([0, 0, 7.79423])
    fov = numpy.pi / 2.0
    direction = numpy.array([
        posX * numpy.tan(fov / 2.0), posY * numpy.tan(fov / 2.0) * (2.0 / 3.0),
        -1
    ])
    direction = direction / numpy.linalg.norm(direction)

    point = numpy.array([0, 0, 0])
    normal = numpy.array([0, 0, 0])

    # Determine the portion of the screen the object is on.

    if (abs(posX) < 0.475 and abs(posY) < 0.475):
        point = numpy.array([0, 0, -roomHeight / 2])
        normal = numpy.array([0, 0, 1])
    else:
        if posY > posX:
            if posY > -posX:
                point = numpy.array([0, roomHeight / 2, 0])
                normal = numpy.array([0, -1, 0])
            else:
                point = numpy.array([-roomWidth / 2, 0, 0])
                normal = numpy.array([1, 0, 0])
        else:
            if posY < -posX:
                point = numpy.array([0, -roomHeight / 2, 0])
                normal = numpy.array([0, 1, 0])
            else:
                point = numpy.array([roomWidth / 2, 0, 0])
                normal = numpy.array([-1, 0, 0])

    # Linear interpolation to find the line to plain intersection

    d = numpy.dot(point - origin, normal) / numpy.dot(direction, normal)

    final = origin + d * direction

    dZ = abs(origin[2] - final[2])

    worldSize = (size * dZ * numpy.tan(fov / 2))

    final += (worldSize / 2) * normal

    models[-1].pos = vec(final[0], final[1], final[2])
    models[-1].rotate(angle=angle, axis=vec(0, 1, 0))
    models[-1].size = vec(worldSize / modelSize, worldSize / modelSize,
                          worldSize / modelSize)

    return 0
Exemplo n.º 23
0
    def _create_hab(self, entity: Entity, texture: str) -> \
            vpython.compound:
        def vertex(x: float, y: float, z: float) -> vpython.vertex:
            return vpython.vertex(pos=vpython.vector(x, y, z))

        # See the docstring of ThreeDeeObj._create_obj for why the dimensions
        # that define the shape of the habitat will not actually directly
        # translate to world-space.

        body = vpython.cylinder(pos=vpython.vec(0, 0, 0),
                                axis=vpython.vec(-5, 0, 0),
                                radius=10)
        head = vpython.cone(pos=vpython.vec(0, 0, 0),
                            axis=vpython.vec(2, 0, 0),
                            radius=10)
        wing = vpython.triangle(v0=vertex(0, 0, 0),
                                v1=vertex(-5, 30, 0),
                                v2=vertex(-5, -30, 0))
        wing2 = vpython.triangle(v0=vertex(0, 0, 0),
                                 v1=vertex(-5, 0, 30),
                                 v2=vertex(-5, 0, -30))

        hab = vpython.compound([body, head, wing, wing2],
                               make_trail=True,
                               texture=texture)
        hab.axis = calc.angle_to_vpy(entity.heading)
        hab.radius = entity.r / 2
        hab.shininess = 0.1
        hab.length = entity.r * 2

        boosters: List[vpython.cylinder] = []
        body_radius = entity.r / 8
        for quadrant in range(0, 4):
            # Generate four SRB bodies.
            normal = vpython.rotate(vpython.vector(0, 1, 1).hat,
                                    angle=quadrant * vpython.radians(90),
                                    axis=vpython.vector(1, 0, 0))
            boosters.append(
                vpython.cylinder(radius=self.BOOSTER_RADIUS,
                                 pos=(self.BOOSTER_RADIUS + body_radius) *
                                 normal))
            boosters.append(
                vpython.cone(
                    radius=self.BOOSTER_RADIUS,
                    length=0.2,
                    pos=((self.BOOSTER_RADIUS + body_radius) * normal +
                         vpython.vec(1, 0, 0))))

        # Append an invisible point to shift the boosters down the fuselage.
        # For an explanation of why that matters, read the
        # ThreeDeeObj._create_obj docstring (and if that doesn't make sense,
        # get in touch with Patrick M please hello hi I'm always free!)
        boosters.append(vpython.sphere(opacity=0, pos=vpython.vec(1.2, 0, 0)))
        booster_texture = texture.replace(f'{entity.name}.jpg', 'SRB.jpg')
        hab.boosters = vpython.compound(boosters, texture=booster_texture)
        hab.boosters.length = entity.r * 2
        hab.boosters.axis = hab.axis

        parachute: List[vpython.standardAttributes] = []
        string_length = entity.r * 0.5
        parachute_texture = texture.replace(f'{entity.name}.jpg',
                                            'Parachute.jpg')
        # Build the parachute fabric.
        parachute.append(
            vpython.extrusion(
                path=vpython.paths.circle(radius=0.5, up=vpython.vec(-1, 0,
                                                                     0)),
                shape=vpython.shapes.arc(angle1=vpython.radians(5),
                                         angle2=vpython.radians(95),
                                         radius=1),
                pos=vpython.vec(string_length + self.PARACHUTE_RADIUS / 2, 0,
                                0)))
        parachute[0].height = self.PARACHUTE_RADIUS * 2
        parachute[0].width = self.PARACHUTE_RADIUS * 2
        parachute[0].length = self.PARACHUTE_RADIUS
        for quadrant in range(0, 4):
            # Generate parachute attachment lines.
            string = vpython.cylinder(axis=vpython.vec(string_length,
                                                       self.PARACHUTE_RADIUS,
                                                       0),
                                      radius=0.2)
            string.rotate(angle=(quadrant * vpython.radians(90) -
                                 vpython.radians(45)),
                          axis=vpython.vector(1, 0, 0))
            parachute.append(string)
        parachute.append(
            vpython.sphere(opacity=0,
                           pos=vpython.vec(
                               -(string_length + self.PARACHUTE_RADIUS), 0,
                               0)))
        hab.parachute = vpython.compound(parachute, texture=parachute_texture)
        hab.parachute.visible = False

        return hab
    def __create_grid_objects(self):
        """
        Draw a grid along each 3D plane, that is closest to the camera.

        :return: List of the three drawn axes.
        :rtype: `list`
        """

        # Initial conditions
        xz_lines = []
        xy_lines = []
        yz_lines = []
        camera_axes = self.camera_axes
        # Locate centre of axes
        if self.__relative_cam:
            x_origin, y_origin, z_origin = round(self.__scene.center.x, 2), \
                                           round(self.__scene.center.y, 2), \
                                           round(self.__scene.center.z, 2)
            self.__focal_point = [x_origin, y_origin, z_origin]
            # Convert focal point for 2D rendering. Puts focus point in centre of the view
            if not self.__is_3d:
                self.__focal_point = [
                    val - int(self.__num_squares / 2)
                    for val in self.__focal_point
                ]
                x_origin = self.__focal_point[0]
                y_origin = self.__focal_point[1]
                z_origin = 0
                self.__focal_point[2] = z_origin
        else:
            x_origin, y_origin, z_origin = self.__focal_point[0], \
                                           self.__focal_point[1], \
                                           self.__focal_point[2]

        #   CAMERA AXES |  DISPLAYED GRID | XZ PLANE | XY PLANE | YZ PLANE
        #      x,y,z    |      x,y,z      |   x,z    |    x,y   |    y,z
        #  -------------+-----------------+----------+----------+----------
        #      -,-,-    |      +,+,+      |   +,+    |    +,+   |    +,+
        #      -,-,+    |      +,+,-      |   +,-    |    +,+   |    +,-
        #      -,+,-    |      +,-,+      |   +,+    |    +,-   |    -,+
        #      -,+,+    |      +,-,-      |   +,-    |    +,-   |    -,-
        #      +,-,-    |      -,+,+      |   -,+    |    -,+   |    +,+
        #      +,-,+    |      -,+,-      |   -,-    |    -,+   |    +,-
        #      +,+,-    |      -,-,+      |   -,+    |    -,-   |    -,+
        #      +,+,+    |      -,-,-      |   -,-    |    -,-   |    -,-
        # min = -num_squares or 0, around the default position
        # max = +num_squares or 0, around the default position
        # e.g. at the origin, for negative axes: -10 -> 0, positive axes: 0 -> 10
        min_x_coord = round(
            x_origin +
            (-(self.__num_squares / 2) + (sign(camera_axes.x) * -1) *
             (self.__num_squares / 2)) * self.__scale, 2)
        max_x_coord = round(
            x_origin + ((self.__num_squares / 2) + (sign(camera_axes.x) * -1) *
                        (self.__num_squares / 2)) * self.__scale, 2)

        min_y_coord = round(
            y_origin +
            (-(self.__num_squares / 2) + (sign(camera_axes.y) * -1) *
             (self.__num_squares / 2)) * self.__scale, 2)
        max_y_coord = round(
            y_origin + ((self.__num_squares / 2) + (sign(camera_axes.y) * -1) *
                        (self.__num_squares / 2)) * self.__scale, 2)

        min_z_coord = round(
            z_origin +
            (-(self.__num_squares / 2) + (sign(camera_axes.z) * -1) *
             (self.__num_squares / 2)) * self.__scale, 2)
        max_z_coord = round(
            z_origin + ((self.__num_squares / 2) + (sign(camera_axes.z) * -1) *
                        (self.__num_squares / 2)) * self.__scale, 2)

        x_coords = arange(min_x_coord, max_x_coord + self.__scale,
                          self.__scale)
        y_coords = arange(min_y_coord, max_y_coord + self.__scale,
                          self.__scale)
        z_coords = arange(min_z_coord, max_z_coord + self.__scale,
                          self.__scale)

        # Compound origins are in the middle of the bounding boxes. Thus new pos will be between max and min.
        x_middle = (max_x_coord + min_x_coord) / 2
        y_middle = (max_y_coord + min_y_coord) / 2
        z_middle = (max_z_coord + min_z_coord) / 2

        line_thickness = min(max(self.__scale / 25, 0.01), 5)  # 0.01 -> 5

        # XZ plane
        for x_point in x_coords:
            # Draw a line across for each x coord, along the same y-axis, from min to max z coord
            xz_lines.append(
                create_line(vector(x_point, y_origin, min_z_coord),
                            vector(x_point, y_origin, max_z_coord),
                            self.__scene,
                            thickness=line_thickness))
        for z_point in z_coords:
            # Draw a line across each z coord, along the same y-axis, from min to max z coord
            xz_lines.append(
                create_line(vector(min_x_coord, y_origin, z_point),
                            vector(max_x_coord, y_origin, z_point),
                            self.__scene,
                            thickness=line_thickness))

        # XY plane
        for x_point in x_coords:
            # Draw a line across each x coord, along the same z-axis, from min to max y coord
            xy_lines.append(
                create_line(vector(x_point, min_y_coord, z_origin),
                            vector(x_point, max_y_coord, z_origin),
                            self.__scene,
                            thickness=line_thickness))
        for y_point in y_coords:
            # Draw a line across each y coord, along the same z-axis, from min to max x coord
            xy_lines.append(
                create_line(vector(min_x_coord, y_point, z_origin),
                            vector(max_x_coord, y_point, z_origin),
                            self.__scene,
                            thickness=line_thickness))

        # YZ plane
        for y_point in y_coords:
            # Draw a line across each y coord, along the same x-axis, from min to max z coord
            yz_lines.append(
                create_line(vector(x_origin, y_point, min_z_coord),
                            vector(x_origin, y_point, max_z_coord),
                            self.__scene,
                            thickness=line_thickness))
        for z_point in z_coords:
            # Draw a line across each z coord, along the same x-axis, from min to max y coord
            yz_lines.append(
                create_line(vector(x_origin, min_y_coord, z_point),
                            vector(x_origin, max_y_coord, z_point),
                            self.__scene,
                            thickness=line_thickness))

        # Compound the lines together into respective objects
        # XY Plane
        if camera_axes.z < 0:
            xy_plane = compound(xy_lines,
                                origin=vector(x_middle, y_middle, min_z_coord))
        else:
            xy_plane = compound(xy_lines,
                                origin=vector(x_middle, y_middle, max_z_coord))

        # XZ Plane
        if camera_axes.y < 0:
            xz_plane = compound(xz_lines,
                                origin=vector(x_middle, min_y_coord, z_middle))
        else:
            xz_plane = compound(xz_lines,
                                origin=vector(x_middle, max_y_coord, z_middle))

        # YZ Plane
        if camera_axes.x < 0:
            yz_plane = compound(yz_lines,
                                origin=vector(min_x_coord, y_middle, z_middle))
        else:
            yz_plane = compound(yz_lines,
                                origin=vector(max_x_coord, y_middle, z_middle))

        # Combine all into one list
        grid = [None, None, None]
        grid[self.__xy_plane_idx] = xy_plane
        grid[self.__xz_plane_idx] = xz_plane
        grid[self.__yz_plane_idx] = yz_plane

        return grid
Exemplo n.º 25
0
def create_grid():
    Game.grid = []  # for curves
    basecolor = v.vector(0.5, 0.5, 0.5)
    #xbaselines = []
    # return values
    # create xz ground
    floor = v.box(pos=v.vector(
        Game.world_size / 2,
        0,
        Game.world_size / 2,
    ),
                  size=v.vector(Game.world_size, 0.1, Game.world_size),
                  color=v.vector(0.1, 0.1, 0.1),
                  opacity=0.25)
    for z in range(0, Game.world_size + 1, Game.grid_size):
        Game.grid.append(
            v.curve(v.vector(0, 0, z),
                    v.vector(Game.world_size, 0, z),
                    color=basecolor))
    for x in range(0, Game.world_size + 1, Game.grid_size):
        Game.grid.append(
            v.curve(v.vector(x, 0, 0),
                    v.vector(x, 0, Game.world_size),
                    color=basecolor))
    # xy wall
    starty = 0 if Game.min_y >= 0 else int(Game.min_y) - 1
    endy = int(Game.max_y) + 1 if Game.max_y > 0 else 0
    wall1 = v.box(pos=v.vector(Game.world_size / 2,
                               starty + (endy - starty) / 2, 0),
                  size=v.vector(Game.world_size, (endy - starty), 0.1),
                  color=v.vector(0.1, 0.1, 0.1),
                  opacity=0.25)
    for y in range(starty, endy, Game.grid_size):
        Game.grid.append(
            v.curve(v.vector(0, y, 0),
                    v.vector(Game.world_size, y, 0),
                    color=basecolor))
    for x in range(0, Game.world_size + 1, Game.grid_size):
        Game.grid.append(
            v.curve(v.vector(x, starty, 0),
                    v.vector(x, endy, 0),
                    color=basecolor))
    # zy wall
    wall2 = v.box(pos=v.vector(0, starty + (endy - starty) / 2,
                               Game.world_size / 2),
                  size=v.vector(0.1, (endy - starty), Game.world_size),
                  color=v.vector(0.1, 0.1, 0.1),
                  opacity=0.25)
    for y in range(starty, endy, Game.grid_size):
        Game.grid.append(
            v.curve(v.vector(0, y, 0),
                    v.vector(0, y, Game.world_size),
                    color=basecolor))
    for z in range(0, Game.world_size + 1, Game.grid_size):
        Game.grid.append(
            v.curve(v.vector(0, starty, z),
                    v.vector(0, endy, z),
                    color=basecolor))
    #curves CANNOT be part of compound
    max_y_box = v.box(pos=v.vector(0, Game.max_y, 0),
                      color=v.vector(1, 1, 0),
                      size=v.vector(1, 0.1, 1))
    min_y_box = v.box(pos=v.vector(0, Game.min_y, 0),
                      color=v.vector(0, 1, 1),
                      size=v.vector(1, 0.1, 1))
    Game.worldbox = v.compound([floor, wall1, wall2, max_y_box, min_y_box],
                               origin=v.vector(0, 0, 0))
Exemplo n.º 26
0
def create_segmented_line(pos1,
                          pos2,
                          scene,
                          segment_len,
                          colour=None,
                          thickness=0.01):
    """
    Create a dashed line from position 1 to position 2.

    :param scene: The scene in which to draw the object
    :type scene: class:`vpython.canvas`
    :param pos1: 3D position of one end of the line.
    :type pos1: class:`vpython.vector`
    :param pos2: 3D position of the other end of the line.
    :type pos2: class:`vpython.vector`
    :param colour: RGB list to colour the line to
    :type colour: `list`
    :param thickness: Thickness of the line
    :type thickness: `float`
    :param segment_len: The length of the segment, and gap between segments
    :type segment_len: `float`
    :raises ValueError: RGB colour must be normalised between 0->1
    :raises ValueError: Thickness must be greater than 0
    :return: A box resembling a line
    :rtype: class:`vpython.box`
    """
    # Set default colour
    # Stops a warning about mutable parameter
    if colour is None:
        colour = [0, 0, 0]

    if colour[0] > 1.0 or colour[1] > 1.0 or colour[2] > 1.0 or \
       colour[0] < 0.0 or colour[1] < 0.0 or colour[2] < 0.0:
        raise ValueError("RGB values must be normalised between 0 and 1")

    if thickness < 0.0:
        raise ValueError("Thickness must be greater than 0")

    # Length of the line using the magnitude
    line_len = mag(pos2 - pos1)

    # Axis direction of the line (to align the box (line) to intersect the two points)
    axis_dir = pos2 - pos1
    axis_dir.mag = 1.0

    # Return a compound of boxes of thin width and height to resemble a dashed line
    dash_positions = []
    boxes = []
    pos1 = pos1 + (
        axis_dir * segment_len / 2
    )  # Translate centre pos to centre of where dashes will originate from

    # Range = number of dashes (vis and invis)
    for idx in range(0, int(ceil(line_len / (segment_len / axis_dir.mag)))):
        # Add every even point (zeroth, second...) to skip gaps between boxes
        if idx % 2 == 0:
            dash_positions.append(pos1)
        pos1 = (pos1 + axis_dir * segment_len)
        # If the axis between points changes, then the line has surpassed the end point. The line is done
        check_dir = pos2 - pos1
        check_dir.mag = 1.0
        if not vectors_approx_equal(axis_dir, check_dir):
            break

    for xyz in dash_positions:
        length = segment_len
        # If the box will surpass the end point
        len_to_end = (pos2 - xyz).mag
        if len_to_end < segment_len / 2:
            # Length is equal to dist to the end * 2 (as pos is middle of box)
            length = len_to_end * 2

        boxes.append(
            box(canvas=scene,
                pos=xyz,
                axis=axis_dir,
                length=length,
                width=thickness,
                height=thickness,
                color=vector(colour[0], colour[1], colour[2])))

    return compound(boxes)
Exemplo n.º 27
0
    def __create_grid_objects(self):
        """
        Draw a grid along each 3D plane, that is closest to the camera.

        :return: List of the three drawn axes.
        :rtype: `list`
        """

        # Initial conditions
        xz_lines = []
        xy_lines = []
        yz_lines = []
        camera_axes = self.camera_axes
        # Locate centre of axes
        if self.__relative_cam:
            x_origin, y_origin, z_origin = round(self.__scene.center.x),\
                                           round(self.__scene.center.y),\
                                           round(self.__scene.center.z)
            self.__focal_point = [x_origin, y_origin, z_origin]
        else:
            x_origin, y_origin, z_origin = self.__focal_point[0], \
                                           self.__focal_point[1], \
                                           self.__focal_point[2]

        #   CAMERA AXES |  DISPLAYED GRID | XZ PLANE | XY PLANE | YZ PLANE
        #      x,y,z    |      x,y,z      |   x,z    |    x,y   |    y,z
        #  -------------+-----------------+----------+----------+----------
        #      -,-,-    |      +,+,+      |   +,+    |    +,+   |    +,+
        #      -,-,+    |      +,+,-      |   +,-    |    +,+   |    +,-
        #      -,+,-    |      +,-,+      |   +,+    |    +,-   |    -,+
        #      -,+,+    |      +,-,-      |   +,-    |    +,-   |    -,-
        #      +,-,-    |      -,+,+      |   -,+    |    -,+   |    +,+
        #      +,-,+    |      -,+,-      |   -,-    |    -,+   |    +,-
        #      +,+,-    |      -,-,+      |   -,+    |    -,-   |    -,+
        #      +,+,+    |      -,-,-      |   -,-    |    -,-   |    -,-
        # min = -num_squares or 0, around the default position
        # max = +num_squares or 0, around the default position
        # e.g. at the origin, for negative axes: -10 -> 0, positive axes: 0 -> 10
        min_x_coord = x_origin + int(-(self.__num_squares / 2) +
                                     (sign(camera_axes.x) * -1) *
                                     (self.__num_squares / 2))
        max_x_coord = x_origin + int((self.__num_squares / 2) +
                                     (sign(camera_axes.x) * -1) *
                                     (self.__num_squares / 2))

        min_y_coord = y_origin + int(-(self.__num_squares / 2) +
                                     (sign(camera_axes.y) * -1) *
                                     (self.__num_squares / 2))
        max_y_coord = y_origin + int((self.__num_squares / 2) +
                                     (sign(camera_axes.y) * -1) *
                                     (self.__num_squares / 2))

        min_z_coord = z_origin + int(-(self.__num_squares / 2) +
                                     (sign(camera_axes.z) * -1) *
                                     (self.__num_squares / 2))
        max_z_coord = z_origin + int((self.__num_squares / 2) +
                                     (sign(camera_axes.z) * -1) *
                                     (self.__num_squares / 2))

        # XZ plane
        for x_point in range(min_x_coord, max_x_coord + 1):
            # Draw a line across for each x coord, along the same y-axis, from min to max z coord
            xz_lines.append(
                create_line(vector(x_point, y_origin, min_z_coord),
                            vector(x_point, y_origin, max_z_coord),
                            self.__scene))
        for z_point in range(min_z_coord, max_z_coord + 1):
            # Draw a line across each z coord, along the same y-axis, from min to max z coord
            xz_lines.append(
                create_line(vector(min_x_coord, y_origin, z_point),
                            vector(max_x_coord, y_origin, z_point),
                            self.__scene))

        # XY plane
        for x_point in range(min_x_coord, max_x_coord + 1):
            # Draw a line across each x coord, along the same z-axis, from min to max y coord
            xy_lines.append(
                create_line(vector(x_point, min_y_coord, z_origin),
                            vector(x_point, max_y_coord, z_origin),
                            self.__scene))
        for y_point in range(min_y_coord, max_y_coord + 1):
            # Draw a line across each y coord, along the same z-axis, from min to max x coord
            xy_lines.append(
                create_line(vector(min_x_coord, y_point, z_origin),
                            vector(max_x_coord, y_point, z_origin),
                            self.__scene))

        # YZ plane
        for y_point in range(min_y_coord, max_y_coord + 1):
            # Draw a line across each y coord, along the same x-axis, from min to max z coord
            yz_lines.append(
                create_line(vector(x_origin, y_point, min_z_coord),
                            vector(x_origin, y_point, max_z_coord),
                            self.__scene))
        for z_point in range(min_z_coord, max_z_coord + 1):
            # Draw a line across each z coord, along the same x-axis, from min to max y coord
            yz_lines.append(
                create_line(vector(x_origin, min_y_coord, z_point),
                            vector(x_origin, max_y_coord, z_point),
                            self.__scene))

        # Compound the lines together into respective objects
        xz_plane = compound(xz_lines)
        xy_plane = compound(xy_lines)
        yz_plane = compound(yz_lines)

        # Combine all into one list
        grid = [None, None, None]
        grid[self.__xy_plane_idx] = xy_plane
        grid[self.__xz_plane_idx] = xz_plane
        grid[self.__yz_plane_idx] = yz_plane

        return grid
Exemplo n.º 28
0
    def __init__(self,
                 corners,
                 faces,
                 color=vpy.vec(.3, .3, .8),
                 opacity=1,
                 show_faces=True,
                 show_edges=True,
                 show_corners=True,
                 sort_faces=True,
                 edge_color=vpy.vec(0, 0, 0),
                 corner_color=None,
                 edge_radius=0.025,
                 corner_radius=None,
                 pos="auto",
                 debug=False):
        """
        inputs:
        -------
            corners - (list) of vpython.vectors- list of 3d coordinates of the corners of the polyhedron
            faces - (list) of lists - lists of corner indices. one sub-list per face of the polyhedron
            color - (vpython.vector) - color vector for all faces of the polyhedron
            opacity - (float) in [0,1] - opacity of all faces. 0 is invisible, 1 is opaque
            show_faces - (bool) - whether or not to draw the faces
            show_edges - (bool) - whether or not to draw the edges
            show_corners - (bool) - whether or not to draw the corners
            sort_faces - (bool) - whether or not to sort the face vertices
                before drawing the faces and edges.
                This should only be set to False if the faces are already sorted
                to save computation time. Otherwise not sorting can lead to
                major bugs when using the polyhedra later.
            edge_color - (vpython.vector) - color of all edges
            corner_color - (vpython.vector) or None - color of all corners
                defaults to edge_color

        examples:
        ---------
            # create a small pyramid
            >>> corners = [(0,0,0), (1,0,0), (0,1,0), (0,0,1)]
            >>> corners = [vpy.vec(*corner) for corner in corners]
            >>> faces = [[0,1,2], [1,2,3], [0,1,3], [0,2,3]]
            >>> poly = polyhedron(corners, faces)

            # intersection of two polyhedra P and Q:
            >>> R = P & Q
        """
        self.debug = debug
        self.eps = 1e-10  # rounding accuracy to counteract floating point errors
        self.visible = False
        self.color = color
        self.edge_color = edge_color
        self.corner_color = corner_color if corner_color != None else edge_color
        self.edge_radius = edge_radius
        self.corner_radius = corner_radius if corner_radius != None else edge_radius

        self.vertices = [
            vpy.vertex(pos=corner, color=self.color, opacity=opacity)
            for corner in corners
        ]
        self._objects = self.vertices[:]
        # self.vertices = [vpy.vertex(pos=corner, color=corner, opacity=opacity) for corner in corners]
        if isinstance(pos, vpy.vector):
            self.pos = pos
        else:
            self.pos = get_com(self.vertices)

        self.faces = faces
        self.face_centers = self._get_face_centers()
        if sort_faces:  # sort the faces so that the polygons are displayed without holes
            self._sort_faces()
        if show_corners:
            self.draw_corners()
            self.visible = True
        if show_edges:
            self.draw_all_edges()
            self.visible = True
        if show_faces:
            self.draw_faces()
            self.visible = True
        # if self.debug:
        #     self.show_faces()
        if len(self._objects) > 0 and show_faces:
            # if debug:
            #     print(f"number of vertices:", sum(isinstance(obj, vpy.vertex)for obj in self._objects))
            #     print(f"number of corners:", sum(isinstance(obj, vpy.sphere)for obj in self._objects))
            #     print(f"number of edges:", sum(isinstance(obj, vpy.cylinder)for obj in self._objects))
            #     print(f"number of triangles:", sum(isinstance(obj, vpy.triangle)for obj in self._objects))
            self.obj = vpy.compound(
                self._objects[len(self.vertices):],
                origin=self.pos,
                color=self.color)  #, pos=self.pos, color=self.color
            while self._objects != []:
                # if not isinstance(self._objects[0], vpy.vertex):
                self._objects[0].visible = False
                del (self._objects[0])
Exemplo n.º 29
0
    def initRender(self):
        self.canvas = canvas(width=1200, height=900, title='Car-3D')
        # self.canvas = canvas(width=1660, height=1010, title='Car-3D')
        ground_y = 0.17
        thk = 0.1
        ground_width = 10.0
        wallB = box(canvas=self.canvas,
                    pos=vector(0, -ground_y, 0),
                    size=vector(ground_width, thk, ground_width),
                    color=color.blue)

        # vector:(front/rear,z,l/r)

        car_w, car_l, car_h = 0.132, 0.26 / 0.6, 0.2
        wheel_r, wheel_h = 0.095, 0.035
        chassis = box(canvas=self.canvas,
                      pos=vector(0, wheel_r + 0.05, 0),
                      size=vector(car_l, car_h, car_w),
                      color=color.green)

        wheel_r / 2 + thk
        wheel1 = cylinder(pos=vector(0.6 * car_l / 2.0, wheel_r, car_w / 2.0),
                          axis=vector(0, 0, wheel_h),
                          radius=wheel_r,
                          color=color.blue)
        wheel2 = cylinder(pos=vector(0.6 * car_l / 2.0, wheel_r,
                                     -car_w / 2.0 - wheel_h),
                          axis=vector(0, 0, wheel_h),
                          radius=wheel_r,
                          color=color.blue)
        wheel3 = cylinder(pos=vector(-0.6 * car_l / 2.0, wheel_r, car_w / 2.0),
                          axis=vector(0, 0, wheel_h),
                          radius=wheel_r,
                          color=color.blue)
        wheel4 = cylinder(pos=vector(-0.6 * car_l / 2.0, wheel_r,
                                     -car_w / 2.0 - wheel_h),
                          axis=vector(0, 0, wheel_h),
                          radius=wheel_r,
                          color=color.blue)

        self.car = compound([chassis, wheel3, wheel4],
                            pos=vector(self.x_pos, self.y_pos, self.z_pos),
                            make_trail=True,
                            retain=300)
        self.frontwheel = compound([wheel1, wheel2],
                                   pos=vector(self.x_pos, self.y_pos,
                                              self.z_pos))
        self.car.axis = vector(1, 0, 0)
        self.car.up = vector(0, 1, 0)
        self.car.mass = self.car_mass

        self.pointer = arrow(pos=self.car.pos,
                             axis=self.car.axis,
                             shaftwidth=0.01)
        origin = sphere(pos=vector(0, 0, 0), radius=0.02)

        self.x_axis = arrow(pos=vector(0, 0, 0),
                            axis=vector(0, 0, 3),
                            shaftwidth=0.3,
                            color=color.red)
        self.y_axis = arrow(pos=vector(0, 0, 0),
                            axis=vector(3, 0, 0),
                            shaftwidth=0.3,
                            color=color.blue)
        self.z_axis = arrow(pos=vector(0, 0, 0),
                            axis=vector(0, 3, 0),
                            shaftwidth=0.3,
                            color=color.green)
        rate(FPS)
Exemplo n.º 30
0
                   axis=10 * ux,
                   shaftwidth=0.1,
                   color=vp.vector(1, 0, 0))
axe_y_s = vp.arrow(pos=vp.vector(10, 10, 10),
                   axis=10 * uy,
                   shaftwidth=0.1,
                   color=vp.vector(0, 1, 0))
axe_z_s = vp.arrow(pos=vp.vector(10, 10, 10),
                   axis=10 * uz,
                   shaftwidth=0.1,
                   color=vp.vector(0, 0, 1))
sugarbox = vp.box(pos=vp.vector(10, 10, 10),
                  size=vp.vector(lx, ly, lz),
                  axis=vp.vector(0, 0, 0),
                  up=uy)
satellite = vp.compound([axe_x_s, axe_y_s, axe_z_s, sugarbox])
# vecteur champ B
b_vector = vp.arrow(pos=vp.vector(-5, -5, -5),
                    axis=10 * vp.vector(B[0][0], B[1][0], B[2][0]),
                    shaftwidth=0.1,
                    color=vp.vector(1, 1, 1))


####################
# Fonctions utiles #
####################
def plotAttitude():
    for i in range(4):
        plt.plot([dt * i / orbite.getPeriod() for i in range(len(qs))],
                 [q.vec()[i, 0] for q in qs])
    plt.xlabel("t (orbits)")