def triangle_circumference(triangle: Triangle,
                           finder: Finder) -> None:
    side1, side2, side3 = triangle.sides
    yield symbol(triangle, 'circumference') \
          - symbol(side1, 'length') \
          - symbol(side2, 'length') \
          - symbol(side3, 'length')
def the_law_of_cosines(triangle: Triangle,
                       finder: Finder) -> None:
    known_sides = triangle.known_sides
    unknown_angles = triangle.unknown_angles
    if len(known_sides) == 3:
        if unknown_angles:
            angle = unknown_angles[0]
            opposite_side = triangle.opposite_side(angle)
            adj_side1, adj_side2 = triangle.adjacent_sides(angle)
            a = adj_side1.length
            b = adj_side2.length
            c = opposite_side.length
            angle_ = math.acos((a * a + b * b - c * c) / (2 * a * b))
            yield symbol(angle, 'angle') - to_degree_measure(angle_)
            # angle.angle = math.acos((a * a + b * b - c * c) / (2 * a * b))
            # angle.angle = to_degree_measure(angle.angle)
            # solving_path.append_deduction(
            #     theory=zh_theory['the_law_of_cosines'], 
            #     eq='Angle_{0} = arccos((Line_{1}^2+Line_{2}^2-Line_{3}^2) / (2*Line_{1}*Line_{2}))'.format(angle.id, adj_side1.id, adj_side2.id, opposite_side.id),
            #     result=angle.angle)
    elif len(known_sides) == 2:
        unknown_side = triangle.unknown_sides[0]
        angle = triangle.opposite_angle(unknown_side)
        if angle.angle is not None:
            a = known_sides[0].length
            b = known_sides[1].length
            cos_c = math.cos(to_radian_measure(angle.angle))
            length = math.sqrt(a * a + b * b - 2 * a * b * cos_c)
            yield symbol(unknown_side, 'length') - length
def triangle_angle_sum(triangle: Triangle,
                       finder: Finder) -> None:
    angle0, angle1, angle2 = triangle.angles
    yield symbol(angle0, 'angle') \
        + symbol(angle1, 'angle') \
        + symbol(angle2, 'angle') \
        - 180
def n_angle_sector_ratio(n_angle_sector: NAngleSector, finder: Finder) -> None:
    angle = n_angle_sector.angle
    line = n_angle_sector.line
    ratio = n_angle_sector.ratio
    nearer_line = n_angle_sector.nearer_line
    if nearer_line is None:
        nearer_line = angle.sides[0]
    angle_mid = finder.find_angle_by_sides(line, nearer_line)
    yield symbol(angle, 'angle') * ratio - symbol(angle_mid, 'angle')
def similar_triangle_ratio(similar_triangle: SimilarTriangle,
                           finder: Finder) -> None:
    ratio = symbol(similar_triangle, 'ratio')
    triangle1 = similar_triangle.triangle1
    triangle2 = similar_triangle.triangle2
    for angle1, angle2 in similar_triangle.corresponding:
        line1 = triangle1.opposite_side(angle1)
        line2 = triangle2.opposite_side(angle2)
        yield symbol(line1, 'length') - ratio*symbol(line2, 'length')
def n_line_sector_ratio(n_line_sector: NLineSector, finder: Finder) -> None:
    line = n_line_sector.line
    ratio = n_line_sector.ratio
    A = n_line_sector.nearer_point
    if A is None:
        A = line.ends[0]
    B = n_line_sector.point
    AB = finder.find_line_by_ends(A, B)
    yield symbol(line, 'length') * ratio - symbol(AB, 'length')
def perpendicular_angle(parallel: Parallel, finder: Finder) -> None:
    line1 = finder.extend_line(parallel.line1)
    line2 = finder.extend_line(parallel.line2)
    link1 = finder.find_link_by_ends(*line1.ends)
    link2 = finder.find_link_by_ends(*line2.ends)
    col1 = Collineation('Collineation ' + line1.id, points=link1)
    col2 = Collineation('Collineation ' + line2.id, points=link2)

    for angle1, angle2 in _find_alternate_angels(col1, col2, finder):
        yield symbol(angle1, 'angle') - symbol(angle2, 'angle')
def common_vertex_angle_sum(common_vertex_angle: CommonVertexAngle,
                            finder: Finder) -> None:
    lines = common_vertex_angle.lines
    num_lines = len(lines)

    for i in range(num_lines):
        for j in range(i + 1, num_lines):
            for k in range(j + 1, num_lines):
                angle_ij = finder.find_angle_by_sides(lines[i], lines[j])
                angle_jk = finder.find_angle_by_sides(lines[j], lines[k])
                angle_ik = finder.find_angle_by_sides(lines[i], lines[k])
                yield symbol(angle_ij, 'angle') \
                    + symbol(angle_jk, 'angle') \
                    - symbol(angle_ik, 'angle')
def collineation_line_length_sum(collineation: Collineation,
                                 finder: Finder) -> None:
    points = collineation.points
    num_points = len(points)
    if num_points < 3:
        return

    for i in range(num_points):
        for j in range(i + 1, num_points):
            for k in range(j + 1, num_points):
                line_ij = finder.find_line_by_ends(points[i], points[j])
                line_jk = finder.find_line_by_ends(points[j], points[k])
                line_ik = finder.find_line_by_ends(points[i], points[k])
                yield symbol(line_ij, 'length') \
                    + symbol(line_jk, 'length') \
                    - symbol(line_ik, 'length')
def helen_formula(triangle: Triangle,
                  finder: Finder) -> None:
    known_sides = triangle.known_sides
    if len(known_sides) == 3:
        a = known_sides[0].length
        b = known_sides[1].length
        c = known_sides[2].length
        p = (a + b + c) / 2
        area = math.sqrt(p * (p - a) * (p - b) * (p - c))
        yield symbol(triangle, 'area') - area
示例#11
0
 def _update_entity(self, result, e: Entity) -> None:
     for attr, value in e.__dict__.items():
         # If value is unkonwn, check it.
         if value is not None:
             continue
         symbol_ = symbol(e, attr)
         if isinstance(symbol_, Symbol):
             try:
                 value = result[symbol_]
                 if isinstance(value, Number):
                     # Deduction success if update entity.
                     setattr(e, attr, value)
                     self.success = True
             except KeyError:
                 pass
示例#12
0
def perpendicular_angle(perpendicular: Perpendicular,
                       finder: Finder) -> None:
    line1 = perpendicular.line1
    line2 = perpendicular.line2
    # Extend line first.
    line1 = finder.extend_line(line1)
    line2 = finder.extend_line(line2)
    # Find intersection.
    intersection = finder.find_lines_intersection(line1, line2)
    if len(intersection) != 1:
        raise Exception('Perpendicular relationship is suppposed to include '
                        'two perpendicular line. Except 1, got {}.'
                        .format(len(intersection)))
    cross_p = intersection[0]
    for p1 in line1.ends:
        for p2 in line2.ends:
            if p1 == cross_p or p2 == cross_p:
                continue
            line1_ = finder.find_line_by_ends(p1, cross_p)
            line2_ = finder.find_line_by_ends(p2, cross_p)
            angle = finder.find_angle_by_sides(line1_, line2_)
            yield symbol(angle, 'angle') - 90
def vertical_angle_equality(opposite_vertical_angle: OppositeVerticalAngle,
                            finder: Finder) -> None:
    angle1 = opposite_vertical_angle.angle1
    angle2 = opposite_vertical_angle.angle2
    yield symbol(angle1, 'angle') - symbol(angle2, 'angle')
def similar_triangle_angle_equality(similar_triangle: SimilarTriangle,
                                    finder: Finder) -> None:
    for angle1, angle2 in similar_triangle.corresponding:
        yield symbol(angle1, 'angle') - symbol(angle2, 'angle')
def the_law_of_sines(triangle: Triangle,
                     finder: Finder) -> None:
    # known_angles = triangle.known_angles
    # if len(known_angles) == 1 and known_angles[0].angle >= 90:
    #     # if only one angle is known and it larger than 90 degree,
    #     # asin only has one solution.
    #     angle = known_angles[0]
    #     opposite_side = triangle.opposite_side(angle)
    #     if opposite_side.length is not None:
    #         for side in triangle.adjacent_sides(angle):
    #             if side.length is not None:
    #                 unknown_angle = triangle.opposite_angle(side)
    #                 sin_angle = math.sin(to_radian_measure(angle.angle)) * \
    #                     (side.length / opposite_side.length)
    #                 unknown_angle.angle = to_degree_measure(
    #                     math.asin(sin_angle))
    #                 solving_path.append_deduction(
    #                     theory=zh_theory['the_law_of_sines'],
    #                     eq='Angle_{0} = arcsin(sin(Angle_{1}) * (Line_{2} / Line_{3}))'.format(unknown_angle.id, angle.id, side.id, opposite_side.id),
    #                     result=unknown_angle.angle)
    #                 return
    # else:
    #     for angle in triangle.angles:
    #         side = triangle.opposite_side(angle)
    #         if angle.angle is not None:
    #             yield symbol(side, 'length') / sympy.sin(to_radian_measure(symbol(angle, 'angle'))) \
    #                 - 2 * symbol(triangle, 'r_outer')

    known_angles = triangle.known_angles
    if len(known_angles) == 0:
        return
    elif len(known_angles) == 1:
        angle = known_angles[0]
        opposite_side = triangle.opposite_side(angle)
        if opposite_side.length is not None:
            for side in triangle.adjacent_sides(angle):
                if side.length is not None:
                    unknown_angle = triangle.opposite_angle(side)
                    sin_angle = math.sin(to_radian_measure(angle.angle)) * \
                        (side.length / opposite_side.length)
                    angle_ =to_degree_measure(
                        math.asin(sin_angle))
                    yield symbol(unknown_angle, 'angle') - angle_
                    # unknown_angle.angle = to_degree_measure(
                    #     math.asin(sin_angle))
                    # solving_path.append_deduction(
                    #     theory=zh_theory['the_law_of_sines'],
                    #     eq='Angle_{0} = arcsin(sin(Angle_{1}) * (Line_{2} / Line_{3}))'.format(unknown_angle.id, angle.id, side.id, opposite_side.id),
                    #     result=unknown_angle.angle)
                    return
    elif len(known_angles) > 1:
        opposite_sides = \
            [triangle.opposite_side(angle) for angle in known_angles]
        for index1, side1 in enumerate(opposite_sides):
            for index2, side2 in enumerate(opposite_sides):
                if side1.length is None and side2.length is not None:
                    angle1 = to_radian_measure(known_angles[index1].angle)
                    angle2 = to_radian_measure(known_angles[index2].angle)
                    length = side2.length * math.sin(angle1) / math.sin(angle2)
                    yield symbol(side1, 'length') - length
                    # side1.length = side2.length * math.sin(angle1) / math.sin(angle2)
                    # solving_path.append_deduction(
                    #     theory=zh_theory['the_law_of_sines'],
                    #     eq='Line_{0} = Line_{1} * sin({2}) / sin({3})'.format(side1.id, side2.id, known_angles[index1].id, known_angles[index2].id),
                    #     result=side1.length)
                    return
示例#16
0
def supplementary_angle_sum(supplementary_angle: SupplementaryAngle,
                            finder: Finder) -> None:
    angle1 = supplementary_angle.angle1
    angle2 = supplementary_angle.angle2
    yield symbol(angle1, 'angle') + symbol(angle2, 'angle') - 180