def generate_polygon_on_xz_side_length(edges,side_length,offset=0) : ''' Return an polygon on plan XZ: with edges edges from length side_length, with offset offset. z / _____/____x / / plan XZ. ''' angle=360.0/side_length polygon=[] # Polygon vertice container. scale=360.0/edges # Computing of the angle separating 2 points from the polygon. start_vertex1=Vertex(-side_length/2.,0.0,0) start_vertex2=Vertex(side_length/2.,0.0,0) point_to_rotate=start_vertex1 rotate_point=start_vertex2 polygon.append(point_to_rotate) polygon.append(rotate_point) i=2 while i < edges : vertex=rotate_on_xz(rotate_point,abs(180-scale),point_to_rotate) point_to_rotate=rotate_point rotate_point=vertex polygon.append(vertex) i += 1 center=get_center_from_polygon(polygon) # Compute polygon center. tmp=[] for v in polygon : # Translate polygon vertices so as his center is the display center. tmp.append(translate(v,-center.wx,-center.wy,-center.wz)) if offset : offset_set=[] for v in tmp : offset_set.append(rotate_y(v,offset)) tmp=offset_set polygon=tmp return polygon
def generate_tetrahedron(side_length): ''' Generate an tetrahedron in relationship to the given side length. And return an sequence from triangles composing the tetrahedron. ''' # Compute cube side length to get the diagonale length egal to the given argument, # so that the inscribe tetrahedron have the correct side length. side_length = sqrt(pow(side_length, 2) + pow(side_length, 2)) / 2. # Generate the cube where the tetrahedron is inscribe. vertex_list = [ # We begin with the back side. Vertex(-side_length / 2., -side_length / 2., -side_length / 2.), Vertex(side_length / 2., -side_length / 2., -side_length / 2.), Vertex(side_length / 2., side_length / 2., -side_length / 2.), Vertex(-side_length / 2., side_length / 2., -side_length / 2.), # Then with the front side. Vertex(-side_length / 2., -side_length / 2., side_length / 2.), Vertex(side_length / 2., -side_length / 2., side_length / 2.), Vertex(side_length / 2., side_length / 2., side_length / 2.), Vertex(-side_length / 2., side_length / 2., side_length / 2.) ] # Define the 4 triangles composing the tetrahedron: tetrahedron_triangle_1 = (vertex_list[6], vertex_list[3], vertex_list[4]) tetrahedron_triangle_2 = (vertex_list[6], vertex_list[3], vertex_list[1]) tetrahedron_triangle_3 = (vertex_list[4], vertex_list[1], vertex_list[3]) tetrahedron_triangle_4 = (vertex_list[4], vertex_list[1], vertex_list[6]) # Assemble triangles to an tetrahedron: tetrahedron = (tetrahedron_triangle_1, tetrahedron_triangle_2, tetrahedron_triangle_3, tetrahedron_triangle_4) return tetrahedron
def __mul__(self,mult) : ''' Multiply sign wrapper. ''' if isinstance(mult,Vertex) : # The right operator is an vertex. res_x= mult.wx * self.main_matrix[0] + mult.wy * self.main_matrix[4] + mult.wz * self.main_matrix[8] + self.main_matrix[12] res_y= mult.wx * self.main_matrix[1] + mult.wy * self.main_matrix[5] + mult.wz * self.main_matrix[9] + self.main_matrix[13] res_z= mult.wx * self.main_matrix[2] + mult.wy * self.main_matrix[6] + mult.wz * self.main_matrix[10] + self.main_matrix[14] return Vertex(res_x,res_y,res_z) elif isinstance(mult,Vector) : # The right operator is an vector. x= mult.x*self.main_matrix[0] + mult.y*self.main_matrix[4] + mult.z*self.main_matrix[8] y= mult.x*self.main_matrix[1] + mult.y*self.main_matrix[5] + mult.z*self.main_matrix[9] z= mult.x*self.main_matrix[2] + mult.y*self.main_matrix[6] + mult.z*self.main_matrix[10] return Vector(x,y,z) else : # The right operator is suppose to be an Localview otherwise. try : mult.pos=self.mult_vertex(mult.pos) # Localview position multiplying. mult.right=self.mult_vector(mult.right) # Localview X axe vector multiplying. mult.up=self.mult_vector(mult.up) # Localview Y axe vector multiplying. mult.sight=self.mult_vector(mult.sight) # Localview Z axe vector multiplying. return mult except : return None
def get_middle_from_segment(vertex1,vertex2) : ''' Return the middle point of an segment as an object from type Vertex ''' if not isinstance(vertex1,Vertex) or not isinstance(vertex2,Vertex) : raise TypeError(Vertex) return Vertex((vertex1.wx+vertex2.wx)/2.,(vertex1.wy+vertex2.wy)/2.,(vertex1.wz+vertex2.wz)/2.)
def get_result(self) : ''' Return an vertex issue from the main matrix multiplying. ''' res_x= self.x * self.main_matrix[0] + self.y * self.main_matrix[4] + self.z * self.main_matrix[8] + self.main_matrix[12] res_y= self.x * self.main_matrix[1] + self.y * self.main_matrix[5] + self.z * self.main_matrix[9] + self.main_matrix[13] res_z= self.x * self.main_matrix[2] + self.y * self.main_matrix[6] + self.z * self.main_matrix[10] + self.main_matrix[14] return Vertex(res_x,res_y,res_z)
def scale(vertex, factor): ''' Scale from the given factor. ''' if not isinstance(vertex, Vertex): # Type control. raise TypeError(Vertex) # We simply multiply every vertex component (wx,wy,wz) with the given scaling factor. return Vertex(vertex.wx * factor, vertex.wy * factor, vertex.wz * factor)
def __init__(self,x=0.0,y=0.0,z=0.0) : ''' Create an localview object with: -) an position represented by an Vertex. -) 3 free axes initialise as the X, Y, Z axes. ''' self.pos=Vertex(x,y,z) # Position from the localview. self.right=Vector(1.,0.,0.) # Axe X representing vector. self.up=Vector(0.,1.,0.) # Axe Y representing vector. self.sight=Vector(0.,0.,1.) # Axe Z representing vector.
def add_vertex(self,vertex,vector=False) : ''' Add the given vertex and vector and return the result as an Vertex object. ''' if not isinstance(vertex,Vertex) : raise TypeError(Vertex) if vector : if not isinstance(vector,Vector) : raise TypeError(Vector) return Vertex(vector.x + vertex.wx, vector.y + vertex.wy, vector.z + vertex.wz) else : self.x=self.x + vertex.wx self.y=self.y + vertex.wy self.z=self.z + vertex.wz return Vertex(self.x,self.y,self.z)
def div_segment_into_vertices(vertex1, vertex2, divider): ''' Return an sequence from vertices between vertex1 and vertex2. which has divide the segment (vertex1,vertex2) in the given number of vertices. ''' if not isinstance(vertex1, Vertex) or not isinstance(vertex2, Vertex): raise TypeError(Vertex) if not isinstance(divider, int): raise TypeError(int) if divider <= 1: raise ValueError(divider) # Define a vertice representing the length between vertex1 and vertex2 length_vertex = Vertex(vertex2.wx - vertex1.wx, vertex2.wy - vertex1.wy, vertex2.wz - vertex1.wz) divider += 1 # Increment divider to get the right result. mult = 1.0 / divider # Compute the value for step unit setting. # Define a step vertice representing a step in the segment division into vertices. step_vertex = Vertex(length_vertex.wx * mult, length_vertex.wy * mult, length_vertex.wz * mult) position = vertex1 # Setting the start position. steps_vertices = [] # Add the initial position to the result: steps_vertices.append(position) for x in range(divider): # Computing next vertice. position = Vertex(position.wx + step_vertex.wx, position.wy + step_vertex.wy, position.wz + step_vertex.wz) steps_vertices.append(position) return steps_vertices # We could return only the vertices between the start and end position: steps_vertices[1:-1]
def mult_vertex(self,vertex) : ''' Multiply the current main matrix with the given vertex. And return the result as an Vertex. ''' if not isinstance(vertex,Vertex) : raise TypeError(Vertex) res_x= vertex.wx * self.main_matrix[0] + vertex.wy * self.main_matrix[4] + vertex.wz * self.main_matrix[8] + self.main_matrix[12] res_y= vertex.wx * self.main_matrix[1] + vertex.wy * self.main_matrix[5] + vertex.wz * self.main_matrix[9] + self.main_matrix[13] res_z= vertex.wx * self.main_matrix[2] + vertex.wy * self.main_matrix[6] + vertex.wz * self.main_matrix[10] + self.main_matrix[14] return Vertex(res_x,res_y,res_z)
def get_center_from_polyhedron(points) : ''' Return the center of an polyhedron as an object from type Vertex ''' if not isinstance(points,tuple) and not isinstance(points,list) : raise TypeError(tuple,list) for v in points : if not isinstance(v,Vertex) : raise TypeError(Vertex) center=[(max(map(lambda e : e.wx ,points))+min(map(lambda e : e.wx,points)))/2.,(max(map(lambda e : e.wy,points))+min(map(lambda e : e.wy,points)))/2.,(max(map(lambda e : e.wz,points))+min(map(lambda e : e.wz,points)))/2.] return Vertex(vertexv=center)
def rotate_z(vertex, angle): ''' Rotate an vertice around the z axe and return the result position vertice. ''' if not isinstance(vertex, Vertex): # Type control. raise TypeError(Vertex) x = cos(radians(angle)) * vertex.wx - sin( radians(angle)) * vertex.wy # Sea explications. y = sin(radians(angle)) * vertex.wx + cos( radians(angle)) * vertex.wy # Sea explications. z = vertex.wz # Because we rotate on the z axe the z value don't change. return Vertex(x, y, z)
def rotate_x(vertex, angle): ''' Rotate an vertice around the x axe and return the result position vertice. ''' if not isinstance(vertex, Vertex): # Type control. raise TypeError(Vertex) x = vertex.wx # Because we rotate on the x axe the x value don't change. y = (cos(radians(angle)) * vertex.wy) - (sin(radians(angle)) * vertex.wz ) # Sea explications. z = (sin(radians(angle)) * vertex.wy) + (cos(radians(angle)) * vertex.wz ) # Sea explications. return Vertex(x, y, z)
def generate_cube(side_length): ''' Generate an cube in relationship to the given side length. And return an sequence from quads composing the cube. ''' cube_vertex_list = [ # We begin with the back side. Vertex(-side_length / 2., side_length / 2., side_length / 2.), Vertex(side_length / 2., side_length / 2., side_length / 2.), Vertex(side_length / 2., -side_length / 2., side_length / 2.), Vertex(-side_length / 2., -side_length / 2., side_length / 2.), # Then with the front side. Vertex(-side_length / 2., side_length / 2., -side_length / 2.), Vertex(side_length / 2., side_length / 2., -side_length / 2.), Vertex(side_length / 2., -side_length / 2., -side_length / 2.), Vertex(-side_length / 2., -side_length / 2., -side_length / 2.) ] front = [ cube_vertex_list[4], cube_vertex_list[5], cube_vertex_list[6], cube_vertex_list[7] ] # Front QUADS. back = [ cube_vertex_list[0], cube_vertex_list[1], cube_vertex_list[2], cube_vertex_list[3] ] # Back QUADS. left = [ cube_vertex_list[0], cube_vertex_list[4], cube_vertex_list[7], cube_vertex_list[3] ] # Left QUADS. right = [ cube_vertex_list[5], cube_vertex_list[1], cube_vertex_list[2], cube_vertex_list[6] ] # right QUADS. up = [ cube_vertex_list[0], cube_vertex_list[1], cube_vertex_list[5], cube_vertex_list[4] ] # up QUADS. down = [ cube_vertex_list[7], cube_vertex_list[6], cube_vertex_list[2], cube_vertex_list[3] ] # down QUADS. return (front, back, left, right, up, down)
def translate(vertex, value_x, value_y, value_z): ''' Translate an vertice from the given offset in every axe. ''' if not isinstance(vertex, Vertex): # Type control. raise TypeError(Vertex) x = ( value_x + vertex.wx ) # We simply add the given value to translate vertex in direction x, even if it is an negativ value it work. y = ( value_y + vertex.wy ) # We simply add the given value to translate vertex in direction y, even if it is an negativ value it work. z = ( value_z + vertex.wz ) # We simply add the given value to translate vertex in direction z, even if it is an negativ value it work. return Vertex(x, y, z)
def rotate_on_xz(center, angle, vertex): ''' Function to rotate an vertex given as the argument vertex around a center vertex in the xz plan from the value angle in clock sens. Return the rotated vertex as an object from <type 'Vertex'>. ''' if not isinstance(center, Vertex): raise TypeError(Vertex) if not isinstance(vertex, Vertex): raise TypeError(Vertex) return_x = vertex.wx * cos(radians(angle)) - vertex.wz * sin( radians(angle)) + center.wx * ( 1 - cos(radians(angle))) + center.wz * sin(radians(angle)) return_z = vertex.wx * sin(radians(angle)) + vertex.wz * cos( radians(angle)) + center.wz * ( 1 - cos(radians(angle))) - center.wx * sin(radians(angle)) return Vertex(return_x, 0., return_z)
def get_center_from_polygon(points) : ''' Return the center of an polygon as an object from type Vertex ''' if not isinstance(points,tuple) and not isinstance(points,list) : raise TypeError(tuple,list) for v in points : if not isinstance(v,Vertex) : raise TypeError(Vertex) tmp=[] i=-1 while i < len(points)-1 : # We compute the inner (inscribe) circle points. To get the right polygone center. tmp.append(get_middle_from_segment(points[i],points[i+1])) i += 1 points=tmp center=[(max(map(lambda e : e.wx ,points))+min(map(lambda e : e.wx,points)))/2.,(max(map(lambda e : e.wy,points))+min(map(lambda e : e.wy,points)))/2.,(max(map(lambda e : e.wz,points))+min(map(lambda e : e.wz,points)))/2.] return Vertex(vertexv=center)
def generate_toros(base, base_radius, toros_radius): ''' Generate an toros in relationship to the given settings: base: the toros basis polygon. base_radius: the toros basis polygon radius. toros_radius: the toros radius (without the base polygon radius). and return an sequence of polygons base from the toros. ''' base_polygon = generate_polygon_on_yz_radius(base, base_radius, Vertex(0., 0., 0.)) i = 0 toros = [] while i < 360.0: polygon = [] for v in base_polygon: vertex = rotate_y(translate(v, 0.0, 0.0, toros_radius), i) polygon.append(vertex) i += 360.0 / base toros.append(polygon) return toros
def generate_polygon_on_xz_radius(edges,radius,center,offset=0) : ''' Return an polygon on plan XZ: from edges sides, from radius radius, with offset offset. z / _____/____x / / plan XZ. ''' if not isinstance(center,Vertex) : raise TypeError(Vertex) polygon=[] # Polygon vertice container. scale=360./edges # Computing of the angle separating 2 points from the polygon. i=0 while i < edges : polygon.append(Vertex(radius*cos(radians((scale*i)+offset))+center.wx,center.wy,radius*sin(radians((scale*i)+offset))+center.wz)) i += 1 return polygon
def __init__(self,base_polygon,base_radius,toros_radius,display_mode="lined",lines_color=False,faces_color=False,lines_width=1,display_ls=False) : ''' Generate an toros object with the given radius and basis polygone settings. base_polygon = the toros basis polygon. base_radius = the toros basis polygon radius. toros_radius = the toros radius (without the base polygon radius). display_mode = "lined" -> only the lines will be displayed. display_mode = "faced" -> only the faces will be displayed. display_mode = "twice" -> The lines and the faces will be displayed. lines_color = an objet <type 'Color'> representing the lines color. faces_color = an objet <type 'Color'> representing the faces color. line_width = an integer representing the lines width. ''' if not isinstance(base_polygon,int) : raise TypeError("base_polygon argument",int) if base_polygon <= 2 : print "the base polygon must be greater than 2 " quit() if not isinstance(base_radius,int) and not isinstance(base_radius,float) : raise TypeError("base_radius argument",int,float) elif base_radius <= 0.0 : raise ValueError("Value of base_radius must be greater than 0.0") if not isinstance(toros_radius,int) and not isinstance(toros_radius,float) : raise TypeError("toros_radius argument",int,float) elif toros_radius <= 0.0 : raise ValueError("Value of toros_radius must be greater than 0.0") if display_mode == "lined" or display_mode == "faced" or display_mode == "twice" : self.display_mode=display_mode else : raise ValueError("Argument display_mode","lined","faced","twice") if lines_color : if not isinstance(lines_color,Color) : raise TypeError("Argument lines_color",Color) if faces_color : if not isinstance(faces_color,Color) : raise TypeError("Argument faces_color",Color) if not isinstance(lines_width,int) : raise TypeError(lines_width,int) elif lines_width < 1 : raise ValueError("Lines width value too little.") if isinstance(lines_color,Color) : if type(lines_color.a) == bool : lines_color.a=0 if isinstance(faces_color,Color) : if type(faces_color.a) == bool : faces_color.a=0 if isinstance(display_ls,bool) : self.display_ls=display_ls self.base_polygon=base_polygon self.base_radius=base_radius self.toros_radius=toros_radius self.lines_color=lines_color self.faces_color=faces_color self.lines_width=lines_width self.toros=generate_toros(base_polygon,base_radius,toros_radius) self.ls=Localview() self.center=Vertex(0.0,0.0,0.0)
def __init__(self, side_length, display_mode="lined", lines_color=False, quads_color=False, triangles_color=False, lines_width=1, display_ls=False): ''' generate an 26 faces polyhedron object with the given side length settings. display_mode = "lined" -> only the lines will be displayed. display_mode = "faced" -> only the faces will be displayed. display_mode = "twice" -> The lines and the faces will be displayed. lines_color = an objet <type 'Color'> representing the lines color. quads_color = an objet <type 'Color'> representing the quads color. an 18-items-list contains <type 'Color'> objects. triangles_color = an objet <type 'Color'> representing the triangles color. an 8-items-list contains <type 'Color'> objects. line_width = an integer representing the lines width. ''' if not isinstance(side_length, int) and not isinstance( side_length, float): raise TypeError(int, float) elif side_length < 0.0: raise ValueError("Value of side_length must be greater than 0.0") if display_mode == "lined" or display_mode == "faced" or display_mode == "twice": self.display_mode = display_mode else: raise ValueError("lined", "faced", "twice") if lines_color: if not isinstance(lines_color, Color): raise TypeError(lines_color, Color) if quads_color: if not isinstance(quads_color, Color) and not isinstance( quads_color, list): raise TypeError(quads_color, Color, list) elif isinstance(quads_color, list) and len(quads_color) != 18: print "Error quads_color argument:\nYou must give an list from 18 Color objects.\nOne Color object per face." quit() elif isinstance(quads_color, list) and len(quads_color) == 18: tmp = [] quads_color_index = 0 while quads_color_index < 18: if type(quads_color[quads_color_index].a) == bool: quads_color[quads_color_index].a = 0 quads_color_index += 1 if triangles_color: if not isinstance(triangles_color, Color) and not isinstance( triangles_color, list): raise TypeError(triangles_color, Color, list) elif isinstance(triangles_color, list) and len(triangles_color) != 8: print "Error triangles_color argument:\nYou must give an list from 8 Color objects.\nOne Color object per face." quit() elif isinstance(triangles_color, list) and len(triangles_color) == 8: tmp = [] triangles_color_index = 0 while triangles_color_index < 8: if type(triangles_color[triangles_color_index].a) == bool: triangles_color[triangles_color_index].a = 0 triangles_color_index += 1 if not isinstance(lines_width, int): raise TypeError(lines_width, int) elif lines_width < 1: raise ValueError(lines_width, "Lines width value too little.") if isinstance(lines_color, Color): if type(lines_color.a) == bool: lines_color.a = 0 if isinstance(quads_color, Color): if type(quads_color.a) == bool: quads_color.a = 0 if isinstance(triangles_color, Color): if type(triangles_color.a) == bool: triangles_color.a = 0 if isinstance(display_ls, bool): self.display_ls = display_ls self.side_length = side_length self.lines_color = lines_color self.quads_color = quads_color self.triangles_color = triangles_color self.lines_width = lines_width self.triangles, self.quads = generate_polyhedron_26_faces(side_length) self.ls = Localview() self.center = Vertex(0.0, 0.0, 0.0)
def __init__(self, side_length, display_mode="lined", lines_color=False, pentagons_color=False, hexagons_color=False, lines_width=1, display_ls=False): ''' generate an cube object with the given side length settings. display_mode = "lined" -> only the lines will be displayed. display_mode = "faced" -> only the faces will be displayed. display_mode = "twice" -> The lines and the faces will be displayed. lines_color = an objet <type 'Color'> representing the lines color. pentagons_color = an objet <type 'Color'> representing the pentagons color. an 12-items-list contains <type 'Color'> objects. hexagons_color = an objet <type 'Color'> representing the hexagons color. an 20-items-list contains <type 'Color'> objects. line_width = an integer representing the lines width. ''' if not isinstance(side_length, int) and not isinstance( side_length, float): raise TypeError(int, float) elif side_length <= 0.0: raise ValueError("Value of side_length must be greater than 0.0") if display_mode == "lined" or display_mode == "faced" or display_mode == "twice": self.display_mode = display_mode else: raise ValueError("lined", "faced", "twice") if lines_color: if not isinstance(lines_color, Color): raise TypeError(lines_color, Color) if pentagons_color: if not isinstance(pentagons_color, Color) and not isinstance( pentagons_color, list): raise TypeError(pentagons_color, Color, list) elif isinstance(pentagons_color, list) and len(pentagons_color) != 12: print "Error pentagons_color argument:\nYou must give an list from 12 Color objects.\nOne Color object per face." quit() elif isinstance(pentagons_color, list) and len(pentagons_color) == 12: tmp = [] pentagons_color_index = 0 while pentagons_color_index < 12: if type(pentagons_color[pentagons_color_index].a) == bool: pentagons_color[pentagons_color_index].a = 0 pentagons_color_index += 1 if hexagons_color: if not isinstance(hexagons_color, Color) and not isinstance( hexagons_color, list): raise TypeError(hexagons_color, Color, list) elif isinstance(hexagons_color, list) and len(hexagons_color) != 20: print "Error hexagons_color argument:\nYou must give an list from 20 Color objects.\nOne Color object per face." quit() elif isinstance(hexagons_color, list) and len(hexagons_color) == 20: tmp = [] hexagons_color_index = 0 while hexagons_color_index < 20: if type(hexagons_color[hexagons_color_index].a) == bool: hexagons_color[hexagons_color_index].a = 0 hexagons_color_index += 1 if not isinstance(lines_width, int): raise TypeError(lines_width, int) elif lines_width < 1: raise ValueError(lines_width, "Lines width value too little.") if isinstance(lines_color, Color): if type(lines_color.a) == bool: lines_color.a = 0 if isinstance(pentagons_color, Color): if type(pentagons_color.a) == bool: pentagons_color.a = 0 if isinstance(hexagons_color, Color): if type(hexagons_color.a) == bool: hexagons_color.a = 0 if isinstance(display_ls, bool): self.display_ls = display_ls self.side_length = side_length self.lines_color = lines_color self.pentagons_color = pentagons_color self.hexagons_color = hexagons_color self.lines_width = lines_width self.hexagons, self.pentagons = generate_fulleren(side_length) self.ls = Localview() self.center = Vertex(0.0, 0.0, 0.0)
def generate_quad_sphere(basis,radius) : ''' Generate an quads sphere and return an tuple from 2 arrays: (lined displaying vertices sequence list, surface displaying vertices sequence list). In relationship with the base for the sphere generating: faces count = basis * basis and the given sphere radius. ''' if not isinstance(basis,int) : raise TypeError(int) if basis < 6 or basis % 2 : print "the basis for the sphere must be greater as 5 and basis % 2 == 0 " quit() if not isinstance(radius,int) and not isinstance(radius,float) : raise TypeError(int,float) # We generate the base polygon for the sphere generating with the given radius: polygon_1=generate_polygon_on_xy_radius(basis,radius,Vertex(0.0,0.0,0.0),0) polygons=[] # Container for the polygons. i=2 # The iterator variable is initialise with the value 2 # because this one is used for string formating and the polygon_1 variable exist. while i <= basis : # Generate from empty lists by execution, with the directive exec(), # from formattted strings. # Instead of defining variables because the number of polygons is relativ to the basis argument value. exec("polygon_{0}=[]".format(i)) exec("polygons.append(polygon_{0})".format(i)) i += 1 for v in polygon_1 : # Iteration over every vertice from our base polygon. i=0 angle=360.0/basis # Computing of the degress between 2 polygons on the XZ surface. while i < len(polygons) : # generating of all polygons containing the vertices from the sphere. polygons[i].append(rotate_y(v,angle)) i += 1 angle += 360./basis polygons_array=[] # temporary container variable definition. i=1 # The iterator variable is initialise with the value 1 # because this one is used for string formating. while i <= basis : # Filling from the temporary container variable # with the computed polygons containing the vertice from our sphere. # Which we gonna need to compute the quads from composing the sphere . exec("polygons_array.append(polygon_{0})".format(i)) i += 1 i=0 tmp_1=[] while i < len(polygons_array) : # Iteration over the temporary polygon container variable to compute the quads. ii=0 tmp_2=[] while ii < basis-1 : # We compute the quads: from the polygons list to an quads list. if not i == basis-1 : tmp_2.append(polygons_array[i][ii]) tmp_2.append(polygons_array[i+1][ii]) tmp_2.append(polygons_array[i+1][ii+1]) tmp_2.append(polygons_array[i][ii+1]) else : tmp_2.append(polygons_array[i][ii]) tmp_2.append(polygons_array[0][ii]) tmp_2.append(polygons_array[0][ii+1]) tmp_2.append(polygons_array[i][ii+1]) ii += 1 tmp_1.append(tmp_2) i += 1 polygons_line_array=polygons_array # Affectation of the variable to return for the case of lined sphere displaying. polygons_quad_array=tmp_1 # Affectation of the variable to return for the case of surfaces sphere displaying. return (polygons_line_array,polygons_quad_array)
def generate_trigon_sphere(basis,radius) : ''' Sphere generating function which has for faces triangles and return an tuple from 2 arrays: (lined displaying vertices sequence list, surface displaying vertices sequence list). In relationship with the base for the sphere generating: faces count = basis * basis and the given sphere radius. ''' if not isinstance(basis,int) : raise TypeError(int) if basis < 8 or basis % 4 : print "the basis for the sphere miust be greater as 7 and basis % 4 == 0 " quit() if not isinstance(radius,int) and not isinstance(radius,float) : raise TypeError(int,float) # We generate the base polygon for the sphere generating with the given radius: base_polygon=generate_polygon_on_xy_radius(basis,radius,Vertex(0.0,0.0,0.0),0) polygons=[] # Polygon for trigonized sphere generating container. i=0 angle=360./basis # Computing of the degress between 2 polygons on the XZ surface. while i < basis : # Loop generating an quads sphere polygons list. tmp=[] for v in base_polygon : # Iteration over every vertice from the base polygon # and compting from the next polygon vertices rotate from # the distance between the base polygon and the next polygon. tmp.append(rotate_y(v,angle)) polygons.append(tmp) i += 1 angle += 360./basis # Distance between the base polygon and the next polygon inctrementing. boolean=False tmp_1=[] i=0 while i < len(polygons) : # Iteration over the quads sphere polygons # to compute the polygons on the XZ surface with an alternativ offset. ii=0 tmp_2=[] while ii < len(polygons[0]) : if boolean : tmp_2.append(rotate_y(polygons[ii][i],360./basis/2.)) else : tmp_2.append(polygons[ii][i]) ii += 1 if boolean : boolean=False else : boolean=True i += 1 tmp_1.append(tmp_2) tmp_2=tmp_1 i=-1 polygons_trigons_array=[] boolean=False while i < len(tmp_2)-1 : # Loop to compute the triangles from our sphere. # Throught iterating over the polygons on the XZ surface. ii=-1 while ii < len(tmp_2[i])-1 : tmp=[] if boolean : tmp.append(tmp_2[i][ii]) tmp.append(tmp_2[i][ii+1]) tmp.append(tmp_2[i+1][ii]) else : tmp.append(tmp_2[i][ii]) tmp.append(tmp_2[i][ii+1]) tmp.append(tmp_2[i+1][ii+1]) polygons_trigons_array.append(tmp) ii += 1 if boolean : boolean=False else : boolean=True i += 1 polygon_vertice_array=tmp_1 # Return an polygon array building an sphere and an array of triangles composing our trigon sphere. return (polygon_vertice_array,polygons_trigons_array)
def __init__(self, side_length, display_mode="lined", lines_color=False, faces_color=False, lines_width=1, display_ls=False): ''' Generate an Icosahedron object with the given side length settings. display_mode = "lined" -> Only the lines will be displayed. display_mode = "faced" -> Only the faces will be displayed. display_mode = "twice" -> The lines and the faces will be displayed. lines_color = An objet <type 'Color'> representing the lines color. faces_color = An objet <type 'Color'> representing the faces color. An 8-items-list from object <type 'Color'>. One item per icosahedron face. lines_width = An integer representing the lines width. display_ls = Define if the localview should be display. ''' if not isinstance(side_length, int) and not isinstance( side_length, float): raise TypeError("Argument side_length", int, float) elif side_length <= 0.0: raise ValueError( "Value of argument side_length must be greater than 0.0") if display_mode == "lined" or display_mode == "faced" or display_mode == "twice": self.display_mode = display_mode else: raise ValueError("Argument display_mode", "lined", "faced", "twice") if lines_color: if not isinstance(lines_color, Color): raise TypeError("Argument lines_color", Color) if faces_color: if not isinstance(faces_color, Color) and not isinstance( faces_color, list): raise TypeError(faces_color, Color, list) elif isinstance(faces_color, list) and len(faces_color) != 20: print "Error faces_color argument:\nYou must give an list from 20 Color objects.\nOne Color object per face." quit() elif isinstance(faces_color, list) and len(faces_color) == 20: tmp = [] faces_color_index = 0 while faces_color_index < 20: if type(faces_color[faces_color_index].a) == bool: faces_color[faces_color_index].a = 0 faces_color_index += 1 if not isinstance(lines_width, int): raise TypeError("Argument lines_width", int) elif lines_width < 1: raise ValueError(lines_width, "Lines width value too little.") if isinstance(lines_color, Color): if type(lines_color.a) == bool: lines_color.a = 0 if isinstance(faces_color, Color): if type(faces_color.a) == bool: faces_color.a = 0 if isinstance(display_ls, bool): self.display_ls = display_ls self.side_length = side_length self.lines_color = lines_color self.faces_color = faces_color self.lines_width = lines_width self.polyhedron = generate_icosahedron(side_length)[1] self.ls = Localview() self.center = Vertex(0.0, 0.0, 0.0)
def generate_icosahedron(side_length): ''' Generate an icosahedron from the given side length and return an array of 20 triangles component from the icosahedron and his construction base quad set. ''' side_lt = side_length # Define the littler side of the rectangle. side_gt = side_length * ( (1 + sqrt(5)) / 2. ) # Compute the length of the greater side with the gold number ( (1+sqrt(5))/2. ) # Define the base quad so that his center is Vertex(0.0, 0.0, 0.0) : quad1 = [ Vertex(-side_lt / 2., -side_gt / 2., 0.0), Vertex(side_lt / 2., -side_gt / 2., 0.0), Vertex(side_lt / 2., side_gt / 2., 0.0), Vertex(-side_lt / 2., side_gt / 2., 0.0) ] # Rotate the base quad on the y and z axes from 90°, to obtain the second crossing quad. quad2 = [ rotate_z(rotate_y(quad1[0], 90), 90), rotate_z(rotate_y(quad1[1], 90), 90), rotate_z(rotate_y(quad1[2], 90), 90), rotate_z(rotate_y(quad1[3], 90), 90) ] # Rotate the base quad on the y and x axes from 90°, to obtain the third crossing quad. quad3 = [ rotate_x(rotate_y(quad1[0], 90), 90), rotate_x(rotate_y(quad1[1], 90), 90), rotate_x(rotate_y(quad1[2], 90), 90), rotate_x(rotate_y(quad1[3], 90), 90) ] icosahedron_base_quads = [ quad1, quad2, quad3 ] # We set the bases quads for our polyhedron: an icosahedron. # Define an array composed of triangles because an icosahedron is composed from 20 equilateral triangles: icosahedron_triangle_array = [ (icosahedron_base_quads[0][0], icosahedron_base_quads[0][1], icosahedron_base_quads[2][1]), (icosahedron_base_quads[0][1], icosahedron_base_quads[1][0], icosahedron_base_quads[1][1]), (icosahedron_base_quads[0][0], icosahedron_base_quads[0][1], icosahedron_base_quads[2][2]), (icosahedron_base_quads[0][0], icosahedron_base_quads[1][2], icosahedron_base_quads[1][3]), (icosahedron_base_quads[0][0], icosahedron_base_quads[1][3], icosahedron_base_quads[2][1]), (icosahedron_base_quads[0][1], icosahedron_base_quads[2][1], icosahedron_base_quads[1][0]), (icosahedron_base_quads[0][1], icosahedron_base_quads[1][1], icosahedron_base_quads[2][2]), (icosahedron_base_quads[0][0], icosahedron_base_quads[2][2], icosahedron_base_quads[1][2]), (icosahedron_base_quads[0][2], icosahedron_base_quads[0][3], icosahedron_base_quads[2][3]), (icosahedron_base_quads[0][3], icosahedron_base_quads[1][2], icosahedron_base_quads[1][3]), (icosahedron_base_quads[0][2], icosahedron_base_quads[0][3], icosahedron_base_quads[2][0]), (icosahedron_base_quads[0][2], icosahedron_base_quads[1][0], icosahedron_base_quads[1][1]), (icosahedron_base_quads[0][2], icosahedron_base_quads[1][1], icosahedron_base_quads[2][3]), (icosahedron_base_quads[0][3], icosahedron_base_quads[2][3], icosahedron_base_quads[1][2]), (icosahedron_base_quads[0][3], icosahedron_base_quads[1][3], icosahedron_base_quads[2][0]), (icosahedron_base_quads[0][2], icosahedron_base_quads[2][0], icosahedron_base_quads[1][0]), (icosahedron_base_quads[2][0], icosahedron_base_quads[2][1], icosahedron_base_quads[1][3]), (icosahedron_base_quads[2][0], icosahedron_base_quads[2][1], icosahedron_base_quads[1][0]), (icosahedron_base_quads[2][2], icosahedron_base_quads[2][3], icosahedron_base_quads[1][1]), (icosahedron_base_quads[2][2], icosahedron_base_quads[2][3], icosahedron_base_quads[1][2]) ] # We return the base quad set and the triangle array. return [quad1, quad2, quad3], icosahedron_triangle_array
def __init__(self,radius,basis,display_mode="lined",lines_color=False,faces_color=False,lines_width=1,display_ls=False) : ''' generate an trigon sphere object with the given radius and polygone basis. basis = Integer taken as basis for the sphere generating. radius = Radius of the sphere. display_mode = "lined" -> only the lines will be displayed. display_mode = "faced" -> only the faces will be displayed. display_mode = "twice" -> The lines and the faces will be displayed. lines_color = an objet <type 'Color'> representing the lines color. faces_color = an objet <type 'Color'> representing the faces color. line_width = an integer representing the lines width. ''' if not isinstance(radius,int) and not isinstance(radius,float) : raise TypeError(int,float) elif radius <= 0.0 : raise ValueError("Value of radius must be greater than 0.0") if not isinstance(basis,int) : raise TypeError(int) if basis < 6 or basis % 4 : print "the basis for the sphere must be greater as 5 and basis % 4 == 0 " quit() if display_mode == "lined" or display_mode == "faced" or display_mode == "twice" : self.display_mode=display_mode else : raise ValueError("Argument display_mode","lined","faced","twice") if lines_color : if not isinstance(lines_color,Color) : raise TypeError("Argument lines_color",Color) if faces_color : if not isinstance(faces_color,Color) : raise TypeError("Argument faces_color",Color) if not isinstance(lines_width,int) : raise TypeError(lines_width,int) elif lines_width < 1 : raise ValueError("Lines width value too little.") if isinstance(lines_color,Color) : if type(lines_color.a) == bool : lines_color.a=0 if not type(faces_color) == bool : if type(faces_color.a) == bool : faces_color.a=0 if isinstance(display_ls,bool) : self.display_ls=display_ls self.lines_color=lines_color self.faces_color=faces_color self.lines_width=lines_width self.basis=basis self.radius=radius self.trigons=generate_trigon_sphere(basis,radius)[0] self.ls=Localview() self.center=Vertex(0.0,0.0,0.0)