def createPlacement(self): scene = Scene() triangle = scene.nondegenerate_triangle(labels=('A', 'B', 'C')) A, B, C = triangle.points bisectorA = A.angle(B, C).bisector_line() bisectorB = B.angle(A, C).bisector_line() bisectorC = C.angle(A, B).bisector_line() X_bisector = bisectorA.intersection_point(bisectorB, label='X_bisector') Y_bisector = bisectorA.intersection_point(bisectorC, label='Y_bisector') altitudeA = A.line_through(scene.perpendicular_foot_point(A, B.line_through(C))) altitudeB = B.line_through(scene.perpendicular_foot_point(B, A.line_through(C))) altitudeC = C.line_through(scene.perpendicular_foot_point(C, A.line_through(B))) X_altitude = altitudeA.intersection_point(altitudeB, label='X_altitude') Y_altitude = altitudeA.intersection_point(altitudeC, label='Y_altitude') perpA = B.segment(C).perpendicular_bisector_line() perpB = A.segment(C).perpendicular_bisector_line() perpC = A.segment(B).perpendicular_bisector_line() X_perp = perpA.intersection_point(perpB, label='X_perp') Y_perp = perpA.intersection_point(perpC, label='Y_perp') medianA = A.line_through(B.segment(C).middle_point()) medianB = B.line_through(A.segment(C).middle_point()) medianC = C.line_through(A.segment(B).middle_point()) X_median = medianA.intersection_point(medianB, label='X_median') Y_median = medianA.intersection_point(medianC, label='Y_median') return iterative_placement(scene)
def createPlacement(self): scene = Scene() triangle = scene.nondegenerate_triangle(labels=('A', 'B', 'C')) O = scene.circumcentre_point(triangle, label='O') return iterative_placement(scene)
def createPlacement(self): scene = Scene() triangle = scene.nondegenerate_triangle(labels=('A', 'B', 'C')) A, B, C = triangle.points A1 = scene.free_point(label='A1') B1 = scene.free_point(label='B1') C1 = scene.free_point(label='C1') A1.inside_triangle_constraint(triangle) B1.inside_triangle_constraint(triangle) C1.inside_triangle_constraint(triangle) angleA = A.angle(B, C) angleA.ratio_constraint(A.angle(B, C1), 3) angleA.ratio_constraint(A.angle(C1, B1), 3) angleA.ratio_constraint(A.angle(B1, C), 3) angleB = B.angle(A, C) angleB.ratio_constraint(B.angle(C, A1), 3) angleB.ratio_constraint(B.angle(A1, C1), 3) angleB.ratio_constraint(B.angle(C1, A), 3) angleC = C.angle(A, B) angleC.ratio_constraint(C.angle(A, B1), 3) angleC.ratio_constraint(C.angle(B1, A1), 3) angleC.ratio_constraint(C.angle(A1, B), 3) return iterative_placement(scene)
def createPlacement(self): scene = Scene() triangle = scene.nondegenerate_triangle(labels=('A', 'B', 'C')) A, B, C = triangle.points D = scene.orthocentre_point(triangle) D.inside_triangle_constraint(triangle) A.segment(B).congruent_constraint(C.segment(D)) return iterative_placement(scene)
def createPlacement(self): scene = Scene() A, B, C = scene.nondegenerate_triangle(labels=('A', 'B', 'C')).points A.segment(B).congruent_constraint(A.segment(C)) altitude = A.perpendicular_line(B.line_through(C), label='AD') D = altitude.intersection_point(B.line_through(C, label='BC')) B.segment(C).ratio_constraint(A.segment(D), 2 / sp.sqrt(3)) return iterative_placement(scene)
def createPlacement(self): scene = Scene() triangle = scene.nondegenerate_triangle(labels=('A', 'B', 'C')) A, B, C = triangle.points A.segment(B).ratio_constraint(B.segment(C), 2) A.segment(B).perpendicular_constraint(B.segment(C)) F = scene.incentre_point(triangle, label='F') E = scene.perpendicular_foot_point(B, A.line_through(F), label='E') return iterative_placement(scene)
def createPlacement(self): scene = Scene() A = scene.free_point(label='A', x=1, y=1) B = scene.free_point(label='B', x=5, y=-3) C = scene.free_point(label='C', x=3, y=10) D = scene.free_point(label='D', x=4, y=11) AB = A.line_through(B) CD = C.line_through(D) AB.intersection_point(CD, label='E') return iterative_placement(scene)
def createPlacement(self): scene = Scene() triangle = scene.nondegenerate_triangle(labels=('A', 'B', 'C')) A, B, C = triangle.points A.distance_constraint('B', 5) C.distance_constraint('B', 4) C.distance_constraint('A', 3) scene.incircle(triangle, label='incircle') scene.circumcircle(triangle, label='circumcircle') return iterative_placement(scene)
def createPlacement(self): scene = Scene() A, B, C = scene.nondegenerate_triangle(labels=('A', 'B', 'C')).points A.distance_constraint(B, 5) C.distance_constraint(B, 3) C.distance_constraint(A, 4) D = scene.free_point(label='D') A.vector(D).parallel_constraint(C.vector(B)) B.vector(D).parallel_constraint(C.vector(A)) return iterative_placement(scene)
def createPlacement(self): scene = Scene() A = scene.free_point(label='A') B = scene.free_point(label='B') C = scene.free_point(label='C') M = A.segment(B).middle_point(label='M') l = C.line_through(M) D = l.free_point(label='D') para = scene.parallel_line(A.line_through(B), D) A1 = para.intersection_point(A.line_through(C), label='A1') B1 = para.intersection_point(B.line_through(C), label='B1') return iterative_placement(scene)
def createPlacement(self): scene = Scene() circle = scene.free_point().circle_through(scene.free_point()) A = circle.free_point(label='A') B = circle.free_point(label='B') C = circle.free_point(label='C') D = circle.free_point(label='D') E = circle.free_point(label='E') scene.convex_polygon_constraint(A, B, C, D, E) A.segment(B).congruent_constraint(B.segment(C)) A.segment(B).congruent_constraint(C.segment(D)) A.segment(B).congruent_constraint(D.segment(E)) A.segment(B).congruent_constraint(E.segment(A)) return iterative_placement(scene)
def createPlacement(self): scene = Scene() O = scene.free_point(label='O', x=0, y=0) A = scene.free_point(label='A') circle = O.circle_through(A) B = circle.free_point(label='B') C = circle.free_point(label='C') D = circle.free_point(label='D') scene.quadrilateral_constraint(A, B, C, D) A.distance_constraint(B, 3) B.distance_constraint(C, 4) C.distance_constraint(D, 5) A.distance_constraint(D, 2) return iterative_placement(scene)
def createPlacement(self): scene = Scene() triangle = scene.nondegenerate_triangle(labels=('A', 'B', 'C')) A, B, C = triangle.points def napoleonic(A: Scene.Point, B: Scene.Point, C: Scene.Point): c0 = A.circle_through(B) c1 = B.circle_through(A) line = A.line_through(B, layer='auxiliary') V = c0.intersection_point(c1, label=C.label + '1') equilateral = Scene.Triangle(A, B, V) V.opposite_side_constraint(C, line) scene.centroid_point(equilateral, label=C.label + '2') napoleonic(A, B, C) napoleonic(C, A, B) napoleonic(B, C, A) return iterative_placement(scene)
def run_sample(scene, *props): parser = argparse.ArgumentParser() parser.add_argument('--max-layer', default='user', choices=CoreScene.layers) parser.add_argument('--dump', nargs='+', choices=('scene', 'constraints', 'stats', 'result', 'properties', 'explanation'), default=('stats', 'result')) parser.add_argument('--run-hunter', action='store_true') parser.add_argument('--extra-rules', nargs='+', choices=('advanced', 'circles', 'trigonometric'), default=()) parser.add_argument('--profile', action='store_true') args = parser.parse_args() if 'scene' in args.dump: scene.dump(include_constraints='constraints' in args.dump, max_layer=args.max_layer) if args.run_hunter: placement = iterative_placement(scene) hunter = Hunter(placement) hunter.hunt() properties = hunter.properties else: properties = [] options = {'max_layer': args.max_layer} for extra in args.extra_rules: options[extra] = True explainer = Explainer(scene, options=options) if args.profile: import cProfile cProfile.runctx('explainer.explain()', {'explainer': explainer}, {}) else: explainer.explain() if 'properties' in args.dump: explainer.dump(properties) if 'stats' in args.dump: explainer.stats(properties).dump() if 'result' in args.dump: for prop in props: explanation = explainer.explanation(prop) if explanation: print('\tExplained: %s' % explanation) else: print('\tNot explained: %s' % prop) if 'explanation' in args.dump: def dump(prop, level=0): print('\t' + ' ' * level + str(prop) + ': ' + str(prop.reason.comment)) if prop.reason.premises: for premise in prop.reason.premises: dump(premise, level + 1) def depth(prop): if prop.reason.premises: return 1 + max(depth(p) for p in prop.reason.premises) return 0 def full_size(prop): if prop.reason.premises: return 1 + sum(full_size(p) for p in prop.reason.premises) return 1 def all_premises(prop): premises = PropertySet(explainer.context.points) for p in prop.reason.all_premises: premises.add(p) return premises for prop in props: explanation = explainer.explanation(prop) if explanation: dump(explanation) print('Depth = %s' % depth(explanation)) print('Full size = %s' % full_size(explanation)) cumulative_priorities = {} def cumu(prop): cached = cumulative_priorities.get(prop) if cached is not None: return cached if prop.reason.premises: cu = 0.7 * prop.priority + 0.3 * max( cumu(p) for p in prop.reason.premises) else: cu = prop.priority cumulative_priorities[prop] = cu return cu priorities = {} for p in explanation.reason.all_premises: priority = cumu(p) priorities[priority] = priorities.get(priority, 0) + 1 pairs = list(priorities.items()) pairs.sort(key=lambda pair: -pair[0]) count_all = len(explanation.reason.all_premises) print('Props = %d (%s)' % (count_all, ', '.join(['%.3f: %d' % p for p in pairs]))) all_premises(explanation).stats().dump() rules_map = {} for prop in explanation.reason.all_premises: key = type(prop.rule).__name__ if hasattr( prop, 'rule') else 'Unknown' rules_map[key] = rules_map.get(key, 0) + 1 items = list(rules_map.items()) items.sort(key=lambda pair: -pair[1]) print('Rules:') for pair in items: print('\t%s: %s' % pair)