def _draw_hexagon(self): center_att = Point(*self.center_att) center = Point(*self.center) p6 = Point(*self.p6) vec_AB = center_att - center shape_size = self.size half_length = shape_size / 2.0 thickness = shape_size / 4.0 adjustment = half_length / center.distance(center_att) adj_vec_AB_1 = adjustment * vec_AB adj_vec_AB_2 = -1 * adj_vec_AB_1 x1 = adj_vec_AB_1 + center x2 = adj_vec_AB_2 + center perp1 = normalize(cross(x1 - x2, x2 - p6)) * half_length perp2 = -1 * perp1 o1 = perp1 + x1 o2 = perp1 + x2 o3 = perp2 + x1 o4 = perp2 + x2 d1 = x2 - center # Rotate by 60 degrees to identify other points of the hexagon - note that t5 is the same as n1 outer = [ _rotate(o1, center, o2, alpha, d1) + center for alpha in (0, 45, 135, 180, 225, 315) ] perp_for = thickness * normalize(cross(o1 - o2, o3 - o1)) perp_back = -1 * perp_for color_and_points = dict( front_1=perp_for + outer[0], front_2=perp_for + outer[1], front_3=perp_for + outer[2], front_4=perp_for + outer[3], front_5=perp_for + outer[4], front_6=perp_for + outer[5], back_1=perp_back + outer[0], back_2=perp_back + outer[1], back_3=perp_back + outer[2], back_4=perp_back + outer[3], back_5=perp_back + outer[4], back_6=perp_back + outer[5], center_1=perp_for + center, center_2=perp_back + center, color1=self.color1, color2=self.color2, ) bild = """ .color {color1} .polygon {front_1} {front_2} {center_1} .polygon {front_1} {center_1} {front_6} .polygon {front_3} {center_1} {front_2} .polygon {front_3} {front_4} {center_1} .polygon {front_5} {center_1} {front_4} .polygon {front_5} {front_6} {center_1} .polygon {back_1} {center_2} {back_2} .polygon {back_1} {back_6} {center_2} .polygon {back_3} {back_2} {center_2} .polygon {back_3} {center_2} {back_4} .polygon {back_5} {back_4} {center_2} .polygon {back_5} {center_2} {back_6} .polygon {back_1} {back_2} {front_1} .polygon {back_2} {front_2} {front_1} .polygon {back_2} {back_3} {front_2} .polygon {back_3} {front_3} {front_2} .polygon {back_3} {back_4} {front_3} .polygon {back_4} {front_4} {front_3} .polygon {back_4} {back_5} {front_4} .polygon {back_5} {front_5} {front_4} .polygon {back_5} {back_6} {front_5} .polygon {back_6} {front_6} {front_5} .polygon {back_6} {back_1} {front_6} .polygon {back_1} {front_1} {front_6} """.format(**color_and_points) return self._build_vrml(bild)
def _draw_star(self): center_att = Point(*self.center_att) center = Point(*self.center) p6 = Point(*self.p6) vec_AB = center_att - center shape_size = self.size * 1.5 half_length = shape_size / 2.0 thickness = shape_size / 4.0 adjustment = half_length / center.distance(center_att) adj_vec_AB_1 = adjustment * vec_AB adj_vec_AB_2 = -1 * adj_vec_AB_1 x1 = adj_vec_AB_1 + center x2 = adj_vec_AB_2 + center perp1 = normalize(cross(x1 - x2, x2 - p6)) * half_length perp2 = -1 * perp1 o1 = perp1 + x1 o2 = perp1 + x2 o3 = perp2 + x1 o4 = perp2 + x2 d1 = x2 - center d2 = (x1 - center) * 0.5 # Rotate by 72 degrees to identify other points of the star outer = [ _rotate(o1, center, o2, alpha, d1) + center for alpha in (72, 144, 216, 288, 360) ] inner = [ _rotate(o1, center, o2, alpha, d2) + center for alpha in (72, 144, 216, 288, 360) ] perp_for = thickness * normalize(cross(o1 - o2, o3 - o1)) perp_back = -1 * perp_for center_1 = perp_for + center center_2 = perp_back + center color_and_points = { 'outer_{}'.format(i + 1): value for i, value in enumerate(outer) } color_and_points.update( {'inner_{}'.format(i + 1): value for i, value in enumerate(inner)}) color_and_points.update( dict(color1=self.color1, color2=self.color2, center_1=center_1, center_2=center_2)) bild = """ .color {color1} .polygon {outer_1} {center_1} {inner_3} .polygon {outer_1} {inner_3} {center_2} .polygon {outer_1} {inner_4} {center_1} .polygon {outer_1} {center_2} {inner_4} .polygon {outer_2} {center_1} {inner_4} .polygon {outer_2} {inner_4} {center_2} .polygon {outer_2} {inner_5} {center_1} .polygon {outer_2} {center_2} {inner_5} .polygon {outer_3} {center_1} {inner_5} .polygon {outer_3} {inner_5} {center_2} .polygon {outer_3} {inner_1} {center_1} .polygon {outer_3} {center_2} {inner_1} .polygon {outer_4} {center_1} {inner_1} .polygon {outer_4} {inner_1} {center_2} .polygon {outer_4} {inner_2} {center_1} .polygon {outer_4} {center_2} {inner_2} .polygon {outer_5} {center_1} {inner_2} .polygon {outer_5} {inner_2} {center_2} .polygon {outer_5} {inner_3} {center_1} .polygon {outer_5} {center_2} {inner_3} """.format(**color_and_points) return self._build_vrml(bild)
def _draw_rectangle(self): center_att = Point(*self.center_att) center = Point(*self.center) p6 = Point(*self.p6) vec_AB = center_att - center half_length = self.size / 1.2 thickness = self.size / 1.8 adjustment = half_length / center.distance(center_att) adj_vec_AB_1 = adjustment * vec_AB adj_vec_AB_2 = -adjustment * vec_AB x1 = adj_vec_AB_1 + center x2 = adj_vec_AB_2 + center perp1 = normalize(cross(x1 - x2, x2 - p6)) * half_length perp2 = perp1 * -1 o1 = perp1 + x1 o2 = perp1 + x2 o3 = perp2 + x1 o4 = perp2 + x2 d1 = x2 - center outer = [ _rotate(o1, center, o2, alpha, d1) + center for alpha in (45, 90, 225, 270) ] perp_for = thickness * normalize(cross(o1 - o2, o3 - o1)) perp_back = perp_for * -1 color_and_points = dict(center_1=perp_for + center, center_2=perp_back + center, front_1=perp_for + outer[0], front_2=perp_for + outer[1], front_3=perp_for + outer[2], front_4=perp_for + outer[3], back_1=perp_back + outer[0], back_2=perp_back + outer[1], back_3=perp_back + outer[2], back_4=perp_back + outer[3], color1=self.color1, color2=self.color2) # Draw the rectangle bild = """ .color {color1} .polygon {front_1} {front_2} {center_1} .polygon {front_1} {center_1} {front_4} .polygon {front_3} {center_1} {front_2} .polygon {front_3} {front_4} {center_1} .polygon {back_1} {center_2} {back_2} .polygon {back_1} {back_4} {center_2} .polygon {back_3} {back_2} {center_2} .polygon {back_3} {center_2} {back_4} .polygon {back_1} {back_2} {front_1} .polygon {back_2} {front_2} {front_1} .polygon {back_2} {back_3} {front_2} .polygon {back_3} {front_3} {front_2} .polygon {back_3} {back_4} {front_3} .polygon {back_4} {front_4} {front_3} .polygon {back_4} {back_1} {front_4} .polygon {back_1} {front_1} {front_4} """.format(**color_and_points) return self._build_vrml(bild)
def _draw_cone(self): center_att = Point(*self.center_att) center = Point(*self.center) p6 = Point(*self.p6) vec_AB = center_att - center half_length = self.size / 2.0 # Vec_AB is currently too large, we want it to be adjusted so that the distance is equal to the offset # that will be used to place the points around the geometric center. The equation asks the question, # what factor should be multiplied times the distance in order to prodce $half-length? # Two adjustments are added to shift the geom_center of the shape. _adjustment = half_length / center.distance(center_att) adjustment1 = _adjustment * 0.66 adjustment2 = _adjustment * 1.33 # Adjust vector_AB by the amount determined in both the forward and reverse directions adj_vec_AB_1 = adjustment1 * vec_AB adj_vec_AB_2 = -adjustment2 * vec_AB # Add two points along the line connecting the residues in the forward and reverse direction x1 = adj_vec_AB_1 + center x2 = adj_vec_AB_2 + center # perp_1 represents a point perpendicular to the previously created two perp1 = normalize(cross(x1 - x2, x2 - p6)) perp2 = -0.5 * perp1 o1 = perp1 + x1 o2 = perp2 + x1 perp3 = normalize(cross(o1 - x2, x2 - center_att)) * half_length o3 = perp3 + x1 # Determine coordinates for outer points of the rectangle # Top point of rectangle is $half_length above geometric center # Vector distance between center and top point of rectangle d1 = o3 - x1 # Rotate by 90 degrees to identify other points of the rectangle - note that t5 is the same as x1 outer = [ _rotate(o1, o3, x1, alpha, d1) + x1 for alpha in (45, 90, 135, 180, 225, 270, 315, 360) ] # Draw the cone color_and_points = { 'outer_{}'.format(i + 1): value for i, value in enumerate(outer) } color_and_points.update( dict(x1=x1, x2=x2, color1=self.color1, color2=self.color2)) bild = """ .color {color1} .polygon {outer_1} {outer_2} {x1} .polygon {outer_1} {x1} {outer_8} .polygon {outer_3} {x1} {outer_2} .polygon {outer_3} {outer_4} {x1} .color {color2} .polygon {outer_5} {x1} {outer_4} .polygon {outer_5} {outer_6} {x1} .polygon {outer_7} {x1} {outer_6} .polygon {outer_7} {outer_8} {x1} .color {color1} .polygon {outer_1} {x2} {outer_2} .polygon {outer_1} {outer_8} {x2} .polygon {outer_5} {outer_4} {x2} .polygon {outer_5} {x2} {outer_6} .color {color2} .polygon {outer_3} {outer_2} {x2} .polygon {outer_3} {x2} {outer_4} .polygon {outer_7} {outer_6} {x2} .polygon {outer_7} {x2} {outer_8} """.format(**color_and_points) return self._build_vrml(bild)
def _draw_diamond(self): center_att = Point(*self.center_att) center = Point(*self.center) p6 = Point(*self.p6) vec_AB = center_att - center shape_size = self.size * 0.5 adjustment = shape_size / center.distance(center_att) adj_vec_AB_1 = adjustment * vec_AB adj_vec_AB_2 = -adjustment * vec_AB x1 = adj_vec_AB_1 + center x2 = adj_vec_AB_2 + center perp_1 = cross(x1 - x2, x2 - p6) perp1 = perp_1 * shape_size perp2 = perp_1 * -shape_size # The number of sides to the diamond is up for debate. It was suggested to use six sides since the # diamond could look like a cube that has been rotated; however, four seems to work since the cylinder # goes directly through one corner. Maybe it could be an option for the user? # Each 'o' represents a corner of a square that is centered on $geom_center o1 = perp1 + x1 o2 = perp1 + x2 o3 = perp2 + x1 o4 = perp2 + x2 # Determine coordinates for outer points of the diamond # Top point of star is $shape_size above geometric center # Vector distance between center and top point of star d1 = x2 - center outer = [ _rotate(o1, center, o2, alpha, d1) + center for alpha in (90, 180, 270, 360) ] # The following function creates the top and bottom of the diamond by creating two points at the geometric # center that are perpendicular to the plane of the square (and parallel with the plane of the ring). perp_for = normalize(cross(o1 - o2, o3 - o1)) * shape_size top = perp_for + center bottom = perp_for * -1 + center color_and_points = { 'outer_{}'.format(i + 1): value for i, value in enumerate(outer) } color_and_points.update( dict(top=top, bottom=bottom, color1=self.color1, color2=self.color2)) bild = """ .color {color1} .polygon {outer_1} {bottom} {outer_2} .polygon {outer_1} {outer_4} {bottom} .polygon {outer_3} {top} {outer_2} .polygon {outer_3} {outer_4} {top} .color {color2} .polygon {outer_1} {outer_2} {top} .polygon {outer_1} {top} {outer_4} .polygon {outer_3} {outer_2} {bottom} .polygon {outer_3} {bottom} {outer_4} """.format(**color_and_points) return self._build_vrml(bild)
def _draw_cube(self): center = Point(*self.center) center_att = Point(*self.center_att) p6 = Point(*self.p6) vec_AB = center_att - center # Resize the shape. $size refers to the total size, # $half_length refers to the distance required create # points on either side of the geometric center. half_length = self.size / 2.0 # Vec_AB is currently too large, we want it to be adjusted so that the distance is equal to the offset # that will be used to place the ponits around the geometric center. The equation asks the question, # what factor should be multiplied times the distance in order to prodce $half-length? adjustment = half_length / center.distance(center_att) # Adjust vector_AB by the amount determined in both the forward and reverse directions adj_vec_AB_1 = vec_AB * adjustment adj_vec_AB_2 = adj_vec_AB_1 * -1 # Add two points along the line connecting the residues in the forward and reverse direction x1 = adj_vec_AB_1 + center x2 = adj_vec_AB_2 + center # perp_1 represents a point perpendicular to the previously created two perp_1 = normalize(cross(x1 - x2, x2 - p6)) perp1 = perp_1 * half_length perp2 = perp1 * -1 # Each 'o' represents a point on the box (o stands for original points, which are based on the two that # lie along the line connecting the two residues) o1 = perp1 + x1 o2 = perp1 + x2 o3 = perp2 + x1 o4 = perp2 + x2 # This creates 8 points (the corners of the box) based upon the coordinates of o1-o4 perp_for = normalize(cross(o1 - o2, o3 - o1)) * half_length perp_back = perp_for * -1 points = dict(s1=perp_for + o1, s2=perp_for + o2, s3=perp_for + o3, s4=perp_for + o4, s5=perp_back + o1, s6=perp_back + o2, s7=perp_back + o3, s8=perp_back + o4) # Draw the Cube - some cubes require two colors, so the triangles are intentionally divided so that one # side shows both colors # Color 1 (blue, yellow, or green) bild = """ .color {color1} .polygon {s2} {s3} {s4} .polygon {s1} {s2} {s6} .polygon {s4} {s7} {s8} .polygon {s5} {s6} {s8} .polygon {s2} {s4} {s8} .polygon {s1} {s5} {s7} .color {color2} .polygon {s1} {s3} {s2} .polygon {s3} {s7} {s4} .polygon {s1} {s6} {s5} .polygon {s5} {s8} {s7} .polygon {s2} {s8} {s6} .polygon {s1} {s7} {s3} """.format(color1=self.color1, color2=self.color2, **points) return self._build_vrml(bild)