[Math] Can the median, angle bisector and the altitude of a triangle intersect to form an equilateral triangle

geometry

On a sheet of paper, a blue triangle is drawn. A median, a bisector and an altitude of this triangle (not necessarily from three distinct vertices) are drawn red. The triangle dissects into several parts. Is it possible that one of these parts is an equilateral triangle with red sides?

I tried to get the angles of the triangle formed, but failed because I was not able to find the angle formed by the median.

Best Answer

I found $4$ situations where a median, a bisector and an altitude form an equilateral triangle. I believe this listing to be exhaustive. Note that half of them use external angle bisectors, and most of them have at least some part of the red triangle outside the blue, so not just a decomposition of the blue one. All of them reuse one original vertex. I'll leave it to you to decide which of these you consider solutions. Click on figures for a bigger view.

  • Edge length ratio $1:\sqrt{13}:4$
    Angles ca. $13.9°, 60°, 106.1°$

  • Edge length ratio $\sqrt3-1:\sqrt2:2 = 1:\sqrt{\sqrt3+2}:\sqrt3+1$
    Angles $15°, 30°, 135°$

  • Edge length ratio $\sqrt2:2:\sqrt3+1 = 1:\sqrt2:\sqrt{\sqrt3+2}$
    Angles $30°, 45°, 105°$

  • Edge length ratio $1:2:\sqrt7$
    Angles ca. $19.1°, 40.9°, 120°$

I found this via a considerable bit of Sage computation. The core idea is using homogeneous coordinates, and parametrizing the triangle as a set of three tangents to the unit circle. That way, the angular bisector can be expressed easily by connecting one vertex to the center of the circle, which is either the incircle or some excircle. Two tangents to the unit circle are parametrized using the tangent half-angle formula, while the third is fixed to the one tangent the formula won't cover. If you care about the details, here they are:

import itertools
import string

PR.<t,u> = QQ[]

def simpl(v):
    if not v:
        return v
    g = gcd(v.list())
    return v.parent()(v / g)

def cp(a, b):
    return simpl(a.cross_product(b))

def mp(a, b):
    return simpl(b[-1]*a + a[-1]*b)

AB = vector([1-t^2, 2*t, 1+t^2])
AC = AB(t=u)
BC = vector([-1, 0, 1])
A = cp(AB, AC)
B = cp(AB, BC)
C = cp(AC, BC)
O = vector([0, 0, 1])
ortho = diagonal_matrix([1, 1, 0])
ABC = matrix([A, B, C]).det()
medians = [cp(A, mp(B, C)), cp(B, mp(C, A)), cp(C, mp(A, B))]
bisectors = [cp(A, O), cp(B, O), cp(C, O)]
altitudes = [cp(A, ortho*BC), cp(B, ortho*AC), cp(C, ortho*AB)]
triplets = [_ for _ in itertools.product(medians, bisectors, altitudes) if matrix(_).det()]

def dehom(v):
    return v[:-1]/v[-1]

def distsq(a, b):
    d = a - b
    return d*d

def equilat(ab, bc, ac):
    a = cp(ab, ac)
    b = cp(ab, bc)
    c = cp(ac, bc)
    abc = matrix([a, b, c]).det()
    da = dehom(a)
    db = dehom(b)
    dc = dehom(c)
    dab = distsq(da, db)
    dbc = distsq(db, dc)
    dac = distsq(da, dc)
    eq1 = (dab - dbc).numerator()
    eq2 = (dab - dac).numerator()
    eq3 = (dac - dbc).numerator()
    g = gcd([eq1, eq2, eq3])
    if g == 0:
        return
    if g != 1:
        for f, p in g.factor(False):
            i = PR.ideal([f])
            assert abc in i  # Equilateral triangle would become degenerate
    i = PR.ideal([eq1 // g, eq2 // g, eq3 // g])
    dim = i.dimension()
    assert dim == 0  # Finite set of solutions
    for s in i.variety(AA):
        if not abc(t=s[t], u=s[u]):
            # Equilateral triangle would be degenerate
            continue
        if not ABC(t=s[t], u=s[u]):
            # Original triangle would be degenerate
            continue
        names = dict((str(k), v) for k, v in s.items())
        pts1 = [A, B, C, a, b, c]
        pts2 = [_(**names) for _ in pts1]
        if not all(_[-1] for _ in pts2):
            # Exclude points at infinity
            continue
        pts3 = [dehom(_) for _ in pts2]
        assert dab(**names) == dbc(**names) == dac(**names)
        A3, B3, C3 = pts3[:3]
        pts4 = pts3[3:]
        dAB = (A3 - B3).norm()
        dAC = (A3 - C3).norm()
        dBC = (B3 - C3).norm()
        if dAB >= dAC >= dBC:
            yield transform(A3, B3, C3, pts4)
        if dAC >= dAB >= dBC:
            yield transform(A3, C3, B3, pts4)
        if dAB >= dBC >= dAC:
            yield transform(B3, A3, C3, pts4)
        if dBC >= dAC >= dAB:
            yield transform(C3, B3, A3, pts4)
        if dBC >= dAB >= dAC:
            yield transform(B3, C3, A3, pts4)
        if dAC >= dBC >= dAB:
            yield transform(C3, A3, B3, pts4)

def transform(A, B, C, abc):
    B2x, B2y = (B - A).list()
    M1 = matrix([[B2x, -B2y], [B2y, B2x]])
    M2 = M1.inverse()
    R = A.parent().base_ring()
    assert M2 * (B - A) == vector([1, 0])
    C2 = M2 * (C - A)
    if C2[1] < 0:
        M2 = diagonal_matrix([1, -1])*M2
        C2 = M2 * (C - A)
    abc2 = sorted(M2 * (_ - A) for _ in abc)
    pts = [vector(R, [0,0]), vector(R, [1,0]), C2] + abc2
    for p in pts:
        p.set_immutable()
    return tuple(pts)

unique = sorted(set(j for i in triplets for j in equilat(*i)))

def svg(f, A, B, C, a, b, c):
    f.write("""<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="1000px" height="400px" viewBox="-0.5, -0.7, 2.0, 0.8"
     stroke-width="0.008"
     version="1.1" xmlns="http://www.w3.org/2000/svg">
""")
    dAB = (A - B).norm()
    dAC = (A - C).norm()
    dBC = (B - C).norm()
    l1 = dAC / dBC
    l2 = dAB / dBC
    f.write("""<descr>
Answer to https://math.stackexchange.com/q/3028611/35416
with edge length ratio 1 : {} : {}
</descr>
""".format(l1.radical_expression(), l2.radical_expression()))
    f.write('<g stroke="blue">\n')
    for p1, p2 in [(A, B), (B, C), (C, A)]:
        p3 = list(map(float, p1 + 10*(p1 - p2)))
        p4 = list(map(float, p2 + 10*(p2 - p1)))
        f.write('<line x1="{}" y1="{}" x2="{}" y2="{}"/>\n'.format(*(p3+p4)))
    f.write('</g>\n')
    f.write('<g stroke="red">\n')
    for p1, p2 in [(a, b), (b, c), (c, a)]:
        p3 = list(map(float, p1 + 10*(p1 - p2)))
        p4 = list(map(float, p2 + 10*(p2 - p1)))
        f.write('<line x1="{}" y1="{}" x2="{}" y2="{}"/>\n'.format(*(p3+p4)))
    f.write('</g>\n')
    f.write('<g stroke="black" fill="blue">\n')
    for p1 in [A, B, C]:
        p2 = list(map(float, p1))
        f.write('<circle cx="{}" cy="{}" r="0.025"/>\n'.format(*(p2)))
    f.write('</g>\n')
    f.write('<g stroke="black" fill="red">\n')
    for p1 in [a, b, c]:
        p2 = list(map(float, p1))
        f.write('<circle cx="{}" cy="{}" r="0.025"/>\n'.format(*(p2)))
    f.write('</g>\n')
    f.write('</svg>\n')

flip = diagonal_matrix([1, -1])
for i, s in enumerate(unique):
    with open('MX3028611{}.svg'.format(string.letters[i]), 'w') as f:
        svg(f, *(flip*_ for _ in s))

You could also consider a slightly different question: Draw all the medians, internal and external bisectors and altitudes for a total of 12 red lines. Can you now find an equilateral triangle with only red edges? This yields a family of situations where you have a $60°$ angle with an angle bisector dividing it, and the heights through the opposite vertices.

This family also includes situations where the bisector becomes the external bisector of a $120°$ vertex, thus still dividing a $60°$ angle. You can obtain one from the other by moving the edge opposite the $60°$ angle in any way you like.

Apart from this one-parameter family there are six more sporadic solutions:

  • Edge length ratio $1:1:1$
    Angles $60°, 60°, 60°$

  • Edge length ratio $1:2:\sqrt7$ (which we already saw above)
    Angles ca. $19.1°, 40.9°, 120°$

    and

  • Edge length ratio $2 : \sqrt5 + 3 : 2\sqrt5 + 2$
    Angles ca. $15.5°, 44.5°, 120°$

  • Edge length ratio $1:\sqrt7:\sqrt7$
    Angles ca. $21.8°, 79.1°, 79.1°$

  • Edge length ratio $1 : \sqrt[3]{\frac19\sqrt{57} + 1} + \frac{2}{3\sqrt[3]{\frac19\sqrt{57} + 1}} + 1 : \frac{\sqrt[3]{6\sqrt{57} + 46}}3 + \frac4{3\sqrt[3]{6\sqrt{57} + 46}} + \frac43$
    (I wonder whether @Blue will come up with something nicer for this here as well…)
    Angles ca. $18.2°, 60°, 101.8°$

Related Question