def face(center, rpos): n = rpos.shape[0] # normalize relative vectors normalized = np.zeros_like(rpos) for i in range(n): normalized[i] = rpos[i] / np.linalg.norm(rpos[i]) #normal for each triangle normals = np.zeros_like(rpos) for i in range(n): normals[i] = np.cross(normalized[i-1], normalized[i]) # central normal c_normal = np.sum(normals, axis=0) c_normal /= np.linalg.norm(c_normal) if np.dot(c_normal, sun) < 0.0: c_normal = - c_normal normals = - normals hue, sat = hue_sat[n] bri = 1 r,g,b = colorsys.hsv_to_rgb(hue/360., sat, bri) pos = rpos + center v_center = vp.vertex( pos=vp.vector(*center), normal=vp.vector(*c_normal), color=vp.vector(r,g,b)) vertices = [vp.vertex( pos=vp.vector(*p), normal=vp.vector(*(normals[i])), color=vp.vector(r,g,b) ) for i,p in enumerate(pos)] faces = set() for i in range(n): faces.add(vp.triangle(v0=vertices[i-1], v1=vertices[i], v2=v_center, )) # group.add(sw.shapes.Polygon(pos, fill=rgb, stroke_linejoin="round", fill_opacity="1.0", stroke="#444", stroke_width=3)) return faces
def Quad(): """how to make a quad""" a = vertex(pos=vec(0, 0, 0), color=color.red) b = vertex(pos=vec(1, 0, 0), color=color.blue) c = vertex(pos=vec(1, 1, 0), color=color.green) d = vertex(pos=vec(0, 1, 0), color=color.yellow) return quad(vs=[a, b, c, d])
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
def vlst(self, q): vtex = [] for i in range(0,len(q),4): a, b, c, d = [vec(q[i+j,0],q[i+j,1],q[i+j,2]) for j in [0,1,2,3]] n=(c-a).cross(d-b).norm() vtex.append([vp.vertex(pos=a, color=self.color, normal=n), vp.vertex(pos=b, color=self.color, normal=n), vp.vertex(pos=c, color=self.color, normal=n), vp.vertex(pos=d, color=self.color, normal=n)]) return vtex
def vertices(R=0, C=0): lowerRight = (2 * R + 1, 2 * C) upperRight = (2 * R + 1, 2 * C + 1) upperLeft = (2 * R, 2 * C + 1) lowerLeft = (2 * R, 2 * C) return [ vertex(pos=vertexes[lowerRight], color=color.red), vertex(pos=vertexes[upperRight], color=color.blue), vertex(pos=vertexes[upperLeft], color=color.green), vertex(pos=vertexes[lowerLeft], color=color.yellow) ]
def endPolygon(self): """Only works for convex polygons in a single plane. This is just simple fan triangulation """ self.polygon = False for i in range(2, len(self.listOfVectors)): triangle(vs=[ vertex(pos=self.listOfVectors[0], color=self.currentColor), vertex(pos=self.listOfVectors[i - 1], color=self.currentColor), vertex(pos=self.listOfVectors[i], color=self.currentColor) ]) self.listOfVectors = []
def vlst(self, q): vtex = [] for i in range(0, len(q), 4): a, b, c, d = [ vec(q[i + j, 0], q[i + j, 1], q[i + j, 2]) for j in [0, 1, 2, 3] ] n = (c - a).cross(d - b).norm() vtex.append([ vp.vertex(pos=a, color=self.color, normal=n), vp.vertex(pos=b, color=self.color, normal=n), vp.vertex(pos=c, color=self.color, normal=n), vp.vertex(pos=d, color=self.color, normal=n) ]) return vtex
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
def __init__(self, poly, center=[0, 0, 0]): self.poly = poly self.nfaces = len(self.poly.faces) colors = [vp.vector(*np.random.rand(3)) for i in range(self.nfaces)] self.vcenter = vp.vector(*center) self.vcolors = colors center = sum([v for v in self.poly.vertices]) / len(self.poly.vertices) vertices = [vertex - center for vertex in self.poly.vertices] vpoints = [vp.sphere(pos=self.vcenter+vp.vector(*v),\ radius=0.02, emissive=True, opacity=0.6)\ for v in vertices] vfaces = [] vnormals = [] vedges = [] for f, face in enumerate(self.poly.faces): vtriangles = [] for tri in itertools.combinations(face.vertices, 3): triangle = vp.triangle(vs=[vp.vertex(pos=self.vcenter+vp.vector(*vertices[v]),\ color=self.vcolors[f],\ opacity=0.5,\ emissive=True,\ shininess=0.5) for v in tri]) vtriangles.append(triangle) vfaces.append(vtriangles) face_center = sum([vertices[vertex] for vertex in face.vertices ]) / len(face.vertices) vnormals.append(vp.arrow(pos=self.vcenter+vp.vector(*face_center), color=self.vcolors[f],\ opacity=0.5,\ axis=vp.vector(*face.unormal)/3)) self.vpoints, self.vfaces, self.vnormals = vpoints, vfaces, vnormals
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)
def update(self, poly): self.poly = poly center = sum([v for v in self.poly.vertices]) / len(self.poly.vertices) vertices = [vertex - center for vertex in self.poly.vertices] for i, v in enumerate(vertices): self.vpoints[i].pos = self.vcenter + vp.vector(*v) for vface in self.vfaces: for vtri in vface: vtri.visible = False self.vfaces = [] for f, face in enumerate(self.poly.faces): vtriangles = [] for tri in itertools.combinations(face.vertices, 3): triangle = vp.triangle(vs=[vp.vertex(pos=self.vcenter+vp.vector(*vertices[v]),\ color=self.vcolors[f],\ opacity=0.5,\ emissive=True,\ shininess=0.5) for v in tri]) vtriangles.append(triangle) self.vfaces.append(vtriangles) face_center = sum([vertices[vertex] for vertex in face.vertices ]) / len(face.vertices) self.vnormals[f].pos = self.vcenter + vp.vector(*face_center) self.vnormals[f].axis = vp.vector(*face.unormal) / 3
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)
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 ])
def face(center, rpos): n = rpos.shape[0] # normalize relative vectors normalized = np.zeros_like(rpos) for i in range(n): normalized[i] = rpos[i] / np.linalg.norm(rpos[i]) #normal for each triangle normals = np.zeros_like(rpos) for i in range(n): normals[i] = np.cross(normalized[i - 1], normalized[i]) # central normal c_normal = np.sum(normals, axis=0) c_normal /= np.linalg.norm(c_normal) if np.dot(c_normal, sun) < 0.0: c_normal = -c_normal normals = -normals hue, sat = hue_sat[n] bri = 1 r, g, b = colorsys.hsv_to_rgb(hue / 360., sat, bri) pos = rpos + center v_center = vp.vertex(pos=vp.vector(*center), normal=vp.vector(*c_normal), color=vp.vector(r, g, b)) vertices = [ vp.vertex(pos=vp.vector(*p), normal=vp.vector(*(normals[i])), color=vp.vector(r, g, b)) for i, p in enumerate(pos) ] faces = set() for i in range(n): faces.add( vp.triangle( v0=vertices[i - 1], v1=vertices[i], v2=v_center, )) # group.add(sw.shapes.Polygon(pos, fill=rgb, stroke_linejoin="round", fill_opacity="1.0", stroke="#444", stroke_width=3)) return faces
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
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 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)
def recalc_y_values(): ## make diamond-square map (a list of lists of integer values) of y-values cells = len( range(0, Game.world_size + 1, Game.grid_size)) # +1 is important because quads need neighbors map1 = DS.diamond_square(shape=(cells, cells), min_height=Game.min_y, max_height=Game.max_y, roughness=Game.roughness) Game.points = [] for z, line in enumerate(map1): pointline = [] for x, y_value in enumerate(line): pointline.append( v.vertex(pos=v.vec(x, y_value, z), color=get_color_from_y(y_value))) Game.points.append(pointline) #Game.points = points create_landscape_from_points()
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 create_flag(particles): flag = [[Seam() for y in range(NUM_COLUMNS)] for x in range(NUM_ROWS)] for r in range(NUM_ROWS): for c in range(NUM_COLUMNS): seam = flag[r][c] if r + 1 < NUM_ROWS and c + 1 < NUM_COLUMNS: if r >= NUM_ROWS // 2: color = vp.color.red else: color = vp.color.white seam.tr1 = vp.triangle( v0=vp.vertex(pos=particles[r][c].pos, color=color), v1=vp.vertex(pos=particles[r][c + 1].pos, color=color), v2=vp.vertex(pos=particles[r + 1][c + 1].pos, color=color)) seam.tr2 = vp.triangle( v0=vp.vertex(pos=particles[r][c].pos, color=color), v1=vp.vertex(pos=particles[r + 1][c + 1].pos, color=color), v2=vp.vertex(pos=particles[r + 1][c].pos, color=color)) return flag
def vertex(x: float, y: float, z: float) -> vpython.vertex: return vpython.vertex(pos=vpython.vector(x, y, z))
def vertex(self, p, n): return vertex(pos=p, color=color.blue, normal=n)
import vpython as vp N = 100 m = 8 vp.scene.width = vp.scene.height = N * m vp.scene.center = vp.vec(N * m / 2, N * m / 2, 0) vp.scene.range = 0.5 * N * m v = [] quads = [] for x in range(N): for y in range(N): c = vp.color.hsv_to_rgb(vp.vec(x / N, 1, 1)) v.append( vp.vertex(pos=vp.vec(x, y, 0), color=c, normal=vp.vec(0, 0, 1))) for x in range(N - 1): for y in range(N - 1): quads.append( vp.quad(vs=[ v[N * x + y], v[N * x + N + y], v[N * x + N + y + 1], v[N * x + y + 1] ])) q = vp.compound(quads) clones = [] n = N - 1 for x in range(m): for y in range(m): clones.append(q.clone(pos=vp.vec(n * x + N / 2, n * y + N / 2, 0))) q.visible = False # make the original object invisible
info = dict(fname=fname, shape=Z.shape, max_value=max_value, min_value=min_value, num_points=idx - 1, center=center) print('-' * 80) print('Basic info:') pprint(info) ################################################ # Draw ground color = vector(0.2, 0.2, 0.2) v0 = vertex(pos=vector(0, 0, 0) - center, color=color) v1 = vertex(pos=vector(shape[0], 0, 0) - center, color=color) v2 = vertex(pos=vector(shape[0], shape[1], 0) - center, color=color) v3 = vertex(pos=vector(0, shape[1], 0) - center, color=color) quad(vs=[v0, v1, v2, v3]) # Draw quad using vertex in xys 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
def make_vertex(self, x, y, value): return vp.vertex(pos=vp.vector(y, value, x), color=vp.color.cyan, normal=vp.vector(0, 1, 0))
radius=max_coord / 50, color=yellow, opacity=0.9)) # for pt in intersection_point: # Figures.append(sphere(pos = vector(*pt), # radius = max_coord/70, # color = turquoise, # opacity = 0.5)) simpl = [] for sim in intersectiong_triang.simplices: pts = [intersectiong_triang.points[pt] for pt in sim] simpl.append( triangle(vs=[ vertex(pos=vector(*ver, sel_z), color=turquoise, opacity=0.9) for ver in pts ])) #drawing lines between couples for couple in couples: v1 = vector(*vor.vertices[sel_reg][couple[0]]) v2 = vector(*vor.vertices[sel_reg][couple[1]]) Figures.append( cylinder(pos=v1, axis=v2 - v1, radius=0.01, opacity=0.5, color=color.gray(0.2))) for pt in container_points:
#Main - Drawing each cell by the walls. scene = vp.canvas(width = 1200, height = 1000, title = '3D Maze') vp.sphere(pos = vp.vector(0,0,0),radius = 0.1, color = vp.vector(1,1,1)) #Origin vp.sphere(pos = vp.vector(0,5,7),radius = 0.2, color = vp.vector(1,0,0)) #start vp.sphere(pos = vp.vector(6,0,0),radius = 0.2, color = vp.vector(0,0,1)) #end quadArray = [] #walls will be added here for i in range(len(maze.grid)): for j in range(len(maze.grid[0])): for k in range(len(maze.grid[0][0])): #Using if statements for each wall, draw the ones that exist. abspos = vp.vector(maze.grid[i][j][k].pos[1], maze.height - maze.grid[i][j][k].pos[0], maze.length - maze.grid[i][j][k].pos[2]) cellcolor = vp.vector(random.random(),random.random(),random.random()) DBL = vp.vertex(pos = abspos + vp.vector(0,-1,-1), color = cellcolor) DBR = vp.vertex(pos = abspos + vp.vector(1,-1,-1), color = cellcolor) DFR = vp.vertex(pos = abspos + vp.vector(1,-1,0), color = cellcolor) DFL = vp.vertex(pos = abspos + vp.vector(0,-1,0), color = cellcolor) UFL = vp.vertex(pos = abspos, color = cellcolor) UFR = vp.vertex(pos = abspos + vp.vector(1,0,0), color = cellcolor) UBR = vp.vertex(pos = abspos + vp.vector(1,0,-1), color = cellcolor) UBL = vp.vertex(pos = abspos + vp.vector(0,0,-1), color = cellcolor) if maze.grid[i][j][k].walls[0]: quadArray.append(vp.quad(vs = [UFL,UFR,UBR,UBL])) if maze.grid[i][j][k].walls[1]: quadArray.append(vp.quad(vs = [UFL,UBL,DBL,DFL])) if maze.grid[i][j][k].walls[2]: quadArray.append(vp.quad(vs = [UFL,UFR,DFR,DFL])) if maze.grid[i][j][k].walls[3]: quadArray.append(vp.quad(vs = [UFR,DFR,DBR,UBR]))
#------------------------------------------------------------------------------- #%%DRAWING scene = canvas(width=900, height=700, center=vector(5, 5, 0)) turquoise = color.hsv_to_rgb(vector(0.5, 1, 0.8)) red = color.red white = color.white colors = [turquoise, red, white] Figures = [] #Central sphere Figures.append(sphere(pos=vector(*cord_c), radius=r, opacity=0.8)) vec_vertices = [vector(*ver) for ver in vor.vertices] for n, ver in enumerate(vec_vertices): Figures.append(sphere(pos=ver, color=white, radius=0.1)) #Drawing Voronoi Cropped Region for n, reg in enumerate(crop_reg): # region = [vector(*vor.vertices[ver]) for ver in reg] # drawPoints(region, color = colors[region_id[n]]) #Overdrawing of points conv_hull = ConvexHull([vor.vertices[ver] for ver in reg]) for sim in conv_hull.simplices: pts = [conv_hull.points[pt] for pt in sim] Figures.append( triangle(vs=[ vertex( pos=vector(*ver), color=colors[region_id[n]], opacity=0.05) for ver in pts ]))
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])
def vertices(R=0, C=0): lowerRight = (2 * R + 1, 2 * C) upperRight = (2 * R + 1, 2 * C + 1) upperLeft = (2 * R, 2 * C + 1) lowerLeft = (2 * R, 2 * C) return [ vertex(pos=vertexes[lowerRight], color=color.red), vertex(pos=vertexes[upperRight], color=color.blue), vertex(pos=vertexes[upperLeft], color=color.green), vertex(pos=vertexes[lowerLeft], color=color.yellow) ] cells = dict() for row in range(Rows): for col in range(Cols): cells[row, col] = quad(vs=vertices(row, col)) #make lefties for row, col in cells.keys(): cell = cells[row, col] #vertices of the cell ll, lr, ur, ul = cell.vs #corners of the cell to be UR = ul LR = ll LL = vertex(color=color.white, pos=vec(0, 0, 0)) UL = vertex(color=color.white, pos=vec(1, 1, 0)) q = quad(vs=[LL, LR, UR, UL])
def make_vertex(self, x, y, value): for i in range(self.count_vertex): if (x - self.spatial_area[i][0])*(self.spatial_area[(i + 1) % self.count_vertex][1] - self.spatial_area[i][1]) - \ (y - self.spatial_area[i][1]) * (self.spatial_area[(i + 1) % self.count_vertex][0] - self.spatial_area[i][0]) > 0: return vertex(pos=vec(y, value, x), color=color.black, normal=vec(0, 1, 0)) return vertex(pos=vec(y, value, x), color=color.cyan, normal=vec(0, 1, 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