def calculate_graph_layout(self, draw, font): text_size = draw.textsize(text=self.label_string, font=font) text_width = text_size[0] text_height = text_size[1] total_width = 0.0 margin = 2.0 for key in self.sub_node_map: sub_node = self.sub_node_map[key] sub_node.calculate_graph_layout(draw, font) sub_node.calculate_bounding_box() total_width += sub_node.bounding_box.Width() + 2.0 * margin location = Vector(-total_width / 2.0 + margin, -2.0 * text_height) for key in self.sub_node_map: sub_node = self.sub_node_map[key] transform = AffineTransform() upper_left_corner = Vector(sub_node.bounding_box.min_point.x, sub_node.bounding_box.max_point.y) transform.Translation(location - upper_left_corner) sub_node.transform_graph_layout(transform) location.x += sub_node.bounding_box.Width() + 2.0 * margin self.label_box.min_point = Vector(-text_width / 2.0 - 3.0, -text_height / 2.0 - 3.0) self.label_box.max_point = Vector(text_width / 2.0 + 3.0, text_height / 2.0 + 3.0)
def __init__(self): super().__init__() cut_region = CutRegion() cut_region.GenerateRegularPolygon(4, 7.0 * math.sqrt(2.0)) hole = Polygon() hole.MakeRegularPolygon(4, 5.0 * math.sqrt(2.0)) cut_region.region.sub_region_list[0].hole_list.append(hole) transform = AffineTransform() transform.RigidBodyMotion(math.pi / 4.0, Vector(3.0, 3.0)) cut_region.Transform(transform) self.cut_region_list.append(cut_region) cut_region = CutRegion() cut_region.GenerateRegularPolygon(4, 7.0 * math.sqrt(2.0)) hole = Polygon() hole.MakeRegularPolygon(4, 5.0 * math.sqrt(2.0)) cut_region.region.sub_region_list[0].hole_list.append(hole) transform = AffineTransform() transform.RigidBodyMotion(math.pi / 4.0, Vector(-3.0, -3.0)) cut_region.Transform(transform) self.cut_region_list.append(cut_region) cut_region = CutRegion() cut_region.GenerateRegularPolygon(4, 3.0 * math.sqrt(2.0)) transform = AffineTransform() transform.RigidBodyMotion(math.pi / 4.0, Vector(0.0, 0.0)) cut_region.Transform(transform) self.cut_region_list.append(cut_region)
def __init__(self): super().__init__() sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(-1.0, -math.sqrt(3.0))) sub_region.polygon.vertex_list.append(Vector(3.0, -math.sqrt(3.0))) sub_region.polygon.vertex_list.append(Vector(1.0, math.sqrt(3.0))) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) self.cut_region_list.append(cut_region) sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(1.0, math.sqrt(3.0))) sub_region.polygon.vertex_list.append(Vector(-3.0, math.sqrt(3.0))) sub_region.polygon.vertex_list.append(Vector(-1.0, -math.sqrt(3.0))) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) self.cut_region_list.append(cut_region) # A reflection symmetry of this rectangle won't be accessible. Hmmmm... sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(-3.0, math.sqrt(3.0))) sub_region.polygon.vertex_list.append(Vector(-3.0, -math.sqrt(3.0))) sub_region.polygon.vertex_list.append(Vector(3.0, -math.sqrt(3.0))) sub_region.polygon.vertex_list.append(Vector(3.0, math.sqrt(3.0))) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) self.cut_region_list.append(cut_region)
def calculate_bounding_rectangle(self, targets=True): rect = AxisAlignedRectangle() rect.min_point = self.target_position if targets else self.position rect.max_point = self.target_position if targets else self.position rect.min_point -= Vector(0.5, 0.5) rect.max_point += Vector(0.5, 0.5) return rect
def __init__(self): super().__init__() cut_region = CutRegion() cut_region.GenerateRegularPolygon(8, 1.0) self.cut_region_list.append(cut_region) cut_region = CutRegion() cut_region.GenerateRegularPolygon(8, 2.0) self.cut_region_list.append(cut_region) cut_region = CutRegion() cut_region.GenerateRegularPolygon(8, 3.0) self.cut_region_list.append(cut_region) cut_region = CutRegion() cut_region.GenerateRegularPolygon(8, 4.0) self.cut_region_list.append(cut_region) sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(0.0, 0.0)) sub_region.polygon.vertex_list.append(Vector(4.0, 0.0)) sub_region.polygon.vertex_list.append(Vector(4.0 * math.cos(math.pi / 4.0), 4.0 * math.sin(math.pi / 4))) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) self.cut_region_list.append(cut_region) transform = AffineTransform() transform.Rotation(Vector(0.0, 0.0), math.pi / 2.0 - math.pi / 8.0) for cut_region in self.cut_region_list: cut_region.Transform(transform)
def GeneratePolygon(self): from math2d_polygon import Polygon polygon = Polygon() polygon.vertex_list.append(Vector(self.min_point.x, self.min_point.y)) polygon.vertex_list.append(Vector(self.max_point.x, self.min_point.y)) polygon.vertex_list.append(Vector(self.max_point.x, self.max_point.y)) polygon.vertex_list.append(Vector(self.min_point.x, self.max_point.y)) return polygon
def GenerateRectangle(self, width, height): sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(-width / 2.0, -height / 2.0)) sub_region.polygon.vertex_list.append(Vector(width / 2.0, -height / 2.0)) sub_region.polygon.vertex_list.append(Vector(width / 2.0, height / 2.0)) sub_region.polygon.vertex_list.append(Vector(-width / 2.0, height / 2.0)) self.region = Region() self.region.sub_region_list.append(sub_region)
def mouseMoveEvent(self, event): if self.dragging: sensativity = 0.003 * self.proj_rect.Width() delta = event.pos() - self.dragPos delta = Vector(-float(delta.x()), float(delta.y())) * sensativity self.dragPos = event.pos() self.proj_rect.min_point += delta self.proj_rect.max_point += delta self.update()
def render_graph(self, draw, image, font, person_subset): image_rect = AxisAlignedRectangle( Vector(0.0, 0.0), Vector(float(image.width), float(image.height))) world_rect = self.bounding_box.Copy() world_rect.ExpandToMatchAspectRatioOf(image_rect) for node in self.all_nodes(): node.render_edges(draw, font, image_rect, world_rect) for node in self.all_nodes(): node.render_label_box(draw, font, image_rect, world_rect, person_subset)
def Inverted(self): try: det = self.Determinant() inverse = LinearTransform() scale = 1.0 / det inverse.x_axis = Vector(self.y_axis.y, -self.x_axis.y) * scale inverse.y_axis = Vector(-self.y_axis.x, self.x_axis.x) * scale return inverse except ZeroDivisionError: return None
def PopulatePointCloudForPermutationGroup(self, cloud, graph): for x in range(0, 5): for y in range(0, 4): if (x < 2 and y == 3) or (x > 2 and y == 0): continue center = Vector(x + 0.5, y + 0.5) cloud.Add(center + Vector(-0.3, -0.3)) cloud.Add(center + Vector(0.3, -0.3)) cloud.Add(center + Vector(0.3, 0.3)) cloud.Add(center + Vector(-0.3, 0.3)) return True
def DrawPreviewImage(self, graph, preview_image, rect, anti_alias=False, thickness=2.0): preview_image_rect = AxisAlignedRectangle( Vector(0.0, 0.0), Vector(float(preview_image.width), float(preview_image.height))) preview_draw = ImageDraw.Draw(preview_image) if anti_alias: for i in range(preview_image.width): for j in range(preview_image.height): point = Vector(float(i), float(preview_image.height - 1 - j)) smallest_distance = 999999.0 for edge in graph.GenerateEdgeSegments(): edge = rect.Map(edge, preview_image_rect) distance = edge.Distance(point) if distance < smallest_distance: smallest_distance = distance if smallest_distance <= thickness: t = smallest_distance / thickness current_pixel = preview_image.getpixel((i, j)) target_pixel = (0, 0, 0, 255) pixel = ( int( round( float(current_pixel[0]) * t + float(target_pixel[0]) * (1.0 - t))), int( round( float(current_pixel[1]) * t + float(target_pixel[1]) * (1.0 - t))), int( round( float(current_pixel[2]) * t + float(target_pixel[2]) * (1.0 - t))), int( round( float(current_pixel[3]) * t + float(target_pixel[3]) * (1.0 - t))), ) preview_draw.point((i, j), fill=pixel) else: for edge in graph.GenerateEdgeSegments(): edge = rect.Map(edge, preview_image_rect) edge = [ int(edge.point_a.x), preview_image.height - 1 - int(edge.point_a.y), int(edge.point_b.x), preview_image.height - 1 - int(edge.point_b.y) ] preview_draw.line(edge, fill=(0, 0, 0, 255), width=2)
def Deserialize(self, json_data): if type(json_data) is list: return super().Deserialize(json_data) elif type(json_data) is dict: self.point_list = [] self.point_list.append(Vector().Deserialize( json_data['start_pos'])) self.point_list.append(Vector().Deserialize(json_data['end_pos'])) self.point_list.append(Vector().Deserialize( json_data['start_tan'])) self.point_list.append(Vector().Deserialize(json_data['end_tan'])) return self
def __init__(self): super().__init__() # It's amazing how hard or easy 2 overlapping squares is. # It depends on _how_ the squares overlap! sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(0.0, 0.0)) sub_region.polygon.vertex_list.append(Vector(3.0, 0.0)) sub_region.polygon.vertex_list.append(Vector(3.0, 3.0)) sub_region.polygon.vertex_list.append(Vector(0.0, 3.0)) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) self.cut_region_list.append(cut_region) sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(2.0, 1.0)) sub_region.polygon.vertex_list.append(Vector(5.0, 1.0)) sub_region.polygon.vertex_list.append(Vector(5.0, 4.0)) sub_region.polygon.vertex_list.append(Vector(2.0, 4.0)) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) self.cut_region_list.append(cut_region)
def assign_initial_positions(self, parent_position=None): if parent_position is None: parent_position = Vector(0.0, 0.0) if self.position is None: self.position = parent_position for child in self.child_list: child.assign_initial_positions(self.position)
def __init__(self): super().__init__() cut_region = CutRegion() cut_region.GenerateRegularPolygon(3, 4.0) transform = AffineTransform() transform.Translation(Vector(-2.5, 0.0)) cut_region.Transform(transform) self.cut_region_list.append(cut_region) cut_region = CutRegion() cut_region.GenerateRegularPolygon(3, 4.0) transform = AffineTransform() transform.RigidBodyMotion(math.pi / 3.0, Vector(2.5, 0.0)) cut_region.Transform(transform) self.cut_region_list.append(cut_region)
def SortKey(entry): if entry['normal'].y <= -epsilon: entry['normal'] = -entry['normal'] angle = Vector(1.0, 0.0).SignedAngleBetween(entry['normal']) if angle < 0.0: angle += 2.0 * math.pi return angle
def Deserialize(self, json_data): self.edge_list = json_data['edge_list'][:] self.vertex_list = [ Vector().Deserialize(vertex_data) for vertex_data in json_data['vertex_list'] ] return self
def AveragePoint(self): if len(self.point_list) == 0: return None avg_point = Vector(0.0, 0.0) for point in self.point_list: avg_point += point avg_point *= 1.0 / float(len(self.point_list)) return avg_point
def __init__(self): super().__init__() radius = 7.0 x = radius * math.cos(math.pi / 3.0) y = radius * math.sin(math.pi / 3.0) cut_region = CutRegion() cut_region.GenerateRegularPolygon(6, radius) self.cut_region_list.append(cut_region) sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(radius, 0.0)) sub_region.polygon.vertex_list.append(Vector(x, y)) sub_region.polygon.vertex_list.append(Vector(x, -y)) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) self.cut_region_list.append(cut_region) sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(radius, 0.0)) sub_region.polygon.vertex_list.append(Vector(x, y)) sub_region.polygon.vertex_list.append(Vector(-x, y)) sub_region.polygon.vertex_list.append(Vector(-radius, 0.0)) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) self.cut_region_list.append(cut_region)
def MakeRegularPolygon(self, sides, radius=1.0, center=None): for i in range(sides): point = Vector(angle=2.0 * math.pi * float(i) / float(sides), radius=radius) if center is None: self.vertex_list.append(point) else: self.vertex_list.append(point + center) return self
def Render(self, sides=12): from OpenGL.GL import glBegin, glEnd, glVertex2f, GL_TRIANGLE_FAN glBegin(GL_TRIANGLE_FAN) try: glVertex2f(self.center.x, self.center.y) for i in range(sides + 1): angle = 2.0 * math.pi * (float(i) / float(sides)) point = self.center + Vector(radius=self.radius, angle=angle) glVertex2f(point.x, point.y) finally: glEnd()
def __init__(self): super().__init__() cut_region = CutRegion() cut_region.GenerateRegularPolygon(4, 3.0) self.cut_region_list.append(cut_region) cut_region = CutRegion() cut_region.GenerateRegularPolygon(4, 3.5) transform = AffineTransform() transform.RigidBodyMotion(0.0, Vector(-4.0, 0.0)) cut_region.Transform(transform) self.cut_region_list.append(cut_region) cut_region = CutRegion() cut_region.GenerateRegularPolygon(4, 3.0) transform = AffineTransform() transform.RigidBodyMotion(0.0, Vector(4.0, 0.0)) cut_region.Transform(transform) self.cut_region_list.append(cut_region)
def calculate_target_positions(self): self.target_position = Vector(0.0, 0.0) for node in self.child_list: node.calculate_target_positions() rect_list = [ node.calculate_subtree_bounding_rectangle(targets=True) for node in self.child_list ] padding = 0.5 total_width = sum([rect.Width() for rect in rect_list ]) + float(len(rect_list) - 1) * padding position = Vector(-total_width / 2.0, -2.0) for i, node in enumerate(self.child_list): rect = rect_list[i] position += Vector(rect.Width() / 2.0, 0.0) node.translate_target_positions(position) position += Vector(rect.Width() / 2.0, 0.0) position += Vector(padding, 0.0)
def __init__(self): super().__init__() cut_region = CutRegion() cut_region.GenerateRegularPolygon(4, 2.0) self.cut_region_list.append(cut_region) sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(1.0, 0.0)) sub_region.polygon.vertex_list.append(Vector(4.0, 0.0)) sub_region.polygon.vertex_list.append( Vector(2.5, math.sqrt(3.0) * 3.0 / 2.0)) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) self.cut_region_list.append(cut_region) # This shape has reflection symmetry, but no rotational symmetry. sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(-1.0, 0.0)) sub_region.polygon.vertex_list.append(Vector(-1.0, 2.0)) sub_region.polygon.vertex_list.append(Vector(-3.0, 0.0)) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) self.cut_region_list.append(cut_region)
def __init__(self): super().__init__() cut_region = CutRegion() cut_region.GenerateRegularPolygon(4, 3.0 * math.sqrt(2.0)) transform = AffineTransform() transform.RigidBodyMotion(math.pi / 4.0, Vector(0.0, 0.0)) cut_region.Transform(transform) self.cut_region_list.append(cut_region) cut_region = CutRegion() cut_region.GenerateRegularPolygon(4, math.sqrt(2.0)) transform = AffineTransform() transform.RigidBodyMotion(math.pi / 4.0, Vector(-1.5, -1.5)) cut_region.Transform(transform) self.cut_region_list.append(cut_region) cut_region = CutRegion() cut_region.GenerateRegularPolygon(4, math.sqrt(2.0)) transform = AffineTransform() transform.RigidBodyMotion(math.pi / 4.0, Vector(3.0, 3.0)) cut_region.Transform(transform) self.cut_region_list.append(cut_region)
def __init__(self): super().__init__() cut_region = CutRegion() cut_region.GenerateRegularPolygon(5, 5.0) hole = Polygon() hole.MakeRegularPolygon(5, 4.0) cut_region.region.sub_region_list[0].hole_list.append(hole) self.cut_region_list.append(cut_region) cut_region = CutRegion() cut_region.GenerateRegularPolygon(5, 3.0) hole = Polygon() hole.MakeRegularPolygon(5, 2.0) cut_region.region.sub_region_list[0].hole_list.append(hole) self.cut_region_list.append(cut_region) # This is almost like puzzle 4, but with a subtle difference. cut_region = CutRegion() cut_region.GenerateRectangle(5.0, 1.0) transform = AffineTransform() transform.translation = Vector(-3.0, 0.0) cut_region.Transform(transform) self.cut_region_list.append(cut_region)
def __init__(self): super().__init__() cut_region = CutRegion() cut_region.GenerateRegularPolygon(5, 5.0) hole = Polygon() hole.MakeRegularPolygon(5, 4.0) cut_region.region.sub_region_list[0].hole_list.append(hole) self.cut_region_list.append(cut_region) cut_region = CutRegion() cut_region.GenerateRegularPolygon(5, 3.0) hole = Polygon() hole.MakeRegularPolygon(5, 2.0) cut_region.region.sub_region_list[0].hole_list.append(hole) self.cut_region_list.append(cut_region) cut_region = CutRegion() cut_region.GenerateRectangle(5.0, 1.0) transform = AffineTransform() transform.translation = Vector(3.5 * math.cos(math.pi * 4.0 / 5.0), 0.0) cut_region.Transform(transform) self.cut_region_list.append(cut_region)
def __init__(self): super().__init__() sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(-1.0, -1.0)) sub_region.polygon.vertex_list.append(Vector(1.0, -1.0)) sub_region.polygon.vertex_list.append(Vector(1.0, 1.0)) sub_region.polygon.vertex_list.append(Vector(-1.0, 1.0)) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) self.cut_region_list.append(cut_region) sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(-1.0, -1.0)) sub_region.polygon.vertex_list.append(Vector(1.0, -1.0)) sub_region.polygon.vertex_list.append(Vector(1.0, 1.0)) sub_region.polygon.vertex_list.append(Vector(-1.0, 1.0)) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) transform = AffineTransform() transform.Translation(Vector(2.0, 0.0)) cut_region.Transform(transform) self.cut_region_list.append(cut_region) sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(-1.0, -1.0)) sub_region.polygon.vertex_list.append(Vector(1.0, -1.0)) sub_region.polygon.vertex_list.append(Vector(1.0, 1.0)) sub_region.polygon.vertex_list.append(Vector(-1.0, 1.0)) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) transform = AffineTransform() transform.Translation(Vector(-2.0, 0.0)) cut_region.Transform(transform) self.cut_region_list.append(cut_region) sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(-1.0, -1.0)) sub_region.polygon.vertex_list.append(Vector(1.0, -1.0)) sub_region.polygon.vertex_list.append(Vector(1.0, 1.0)) sub_region.polygon.vertex_list.append(Vector(-1.0, 1.0)) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) transform = AffineTransform() transform.Translation(Vector(2.0, -2.0)) cut_region.Transform(transform) self.cut_region_list.append(cut_region) sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(-1.0, -1.0)) sub_region.polygon.vertex_list.append(Vector(1.0, -1.0)) sub_region.polygon.vertex_list.append(Vector(1.0, 1.0)) sub_region.polygon.vertex_list.append(Vector(-1.0, 1.0)) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) transform = AffineTransform() transform.Translation(Vector(-2.0, 2.0)) cut_region.Transform(transform) self.cut_region_list.append(cut_region) sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(-2.0, 0.0)) sub_region.polygon.vertex_list.append(Vector(2.0, 0.0)) sub_region.polygon.vertex_list.append(Vector(2.0, -4.0)) sub_region.polygon.vertex_list.append(Vector(4.0, -4.0)) sub_region.polygon.vertex_list.append(Vector(4.0, 2.0)) sub_region.polygon.vertex_list.append(Vector(-2.0, 2.0)) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) self.cut_region_list.append(cut_region) sub_region = SubRegion() sub_region.polygon.vertex_list.append(Vector(2.0, 0.0)) sub_region.polygon.vertex_list.append(Vector(-2.0, 0.0)) sub_region.polygon.vertex_list.append(Vector(-2.0, 4.0)) sub_region.polygon.vertex_list.append(Vector(-4.0, 4.0)) sub_region.polygon.vertex_list.append(Vector(-4.0, -2.0)) sub_region.polygon.vertex_list.append(Vector(2.0, -2.0)) cut_region = CutRegion() cut_region.region = Region() cut_region.region.sub_region_list.append(sub_region) self.cut_region_list.append(cut_region)
def __init__(self, center=None, normal=None): self.center = center if center is not None else Vector(0.0, 0.0) self.normal = normal if normal is not None else Vector(1.0, 0.0)