# Special Points of Triangle
# Lauri Ruotsalainen, 2010
xy = [0]*3
# Return the intersection point of the bisector of the angle <(A[a],A[c],A[b]) and the unit circle. Angles given in radians.
def half(A, a, b, c):
if (A[a] < A[b] and (A[c] < A[a] or A[c] > A[b])) or (A[a] > A[b] and (A[c] > A[a] or A[c] < A[b])):
p = A[a] + (A[b] - A[a]) / 2.0
else:
p = A[b] + (2*pi - (A[b]-A[a])) / 2.0
return (cos(p), sin(p))
# Returns the distance between points (x1,y1) and (x2,y2)
def distance((x1, y1), (x2, y2)):
return sqrt((x2-x1)^2 + (y2-y1)^2)
# Returns the line (graph) going through points (x1,y1) and (x2,y2)
def line_to_points((x1, y1), (x2, y2), **plot_kwargs):
return plot((y2-y1) / (x2-x1) * (x-x1) + y1, x, **plot_kwargs)
@interact
def special_points(
a0 = slider(0, 360, 1, 30, label="A"),
a1 = slider(0, 360, 1, 180, label="B"),
a2 = slider(0, 360, 1, 300, label="C"),
show_median = checkbox(False, label="Medians"),
show_pb = checkbox(False, label="Perpendicular Bisectors"),
show_alt = checkbox(False, label="Altitudes"),
show_ab = checkbox(False, label="Angle Bisectors"),
show_incircle = checkbox(False, label="Incircle"),
show_euler = checkbox(False, label="Euler's Line")
):
# Coordinates of the angles
a = [math.radians(a0), math.radians(a1), math.radians(a2)]
for i in range(3):
xy[i] = (cos(a[i]), sin(a[i]))
# Labels of the angles drawn in a distance from points
a_label = text("A", (xy[0][0]*1.07, xy[0][1]*1.07))
b_label = text("B", (xy[1][0]*1.07, xy[1][1]*1.07))
c_label = text("C", (xy[2][0]*1.07, xy[2][1]*1.07))
labels = a_label + b_label + c_label
C = circle((0, 0), 1, aspect_ratio=1)
# Triangle
triangle = line([xy[0], xy[1], xy[2], xy[0]], rgbcolor="black")
triangle_points = point(xy, pointsize=30)
# Side lengths (bc, ca, ab) corresponding to triangle vertices (a, b, c)
ad = [distance(xy[1], xy[2]), distance(xy[2], xy[0]), distance(xy[0], xy[1])]
# Midpoints of edges (bc, ca, ab)
a_middle = [
((xy[1][0] + xy[2][0])/2.0, (xy[1][1] + xy[2][1])/2.0),
((xy[2][0] + xy[0][0])/2.0, (xy[2][1] + xy[0][1])/2.0),
((xy[0][0] + xy[1][0])/2.0, (xy[0][1] + xy[1][1])/2.0)
]
# Incircle
perimeter = ad[0] + ad[1] + ad[2]
incircle_center = (
(ad[0]*xy[0][0] + ad[1]*xy[1][0] + ad[2]*xy[2][0]) / perimeter,
(ad[0]*xy[0][1] + ad[1]*xy[1][1] + ad[2]*xy[2][1]) / perimeter
)
if show_incircle:
s = perimeter/2.0
incircle_r = sqrt((s - ad[0]) * (s - ad[1]) * (s - ad[2]) / s)
incircle_graph = circle(incircle_center, incircle_r)
else:
incircle_graph = Graphics()
# Angle Bisectors
if show_ab:
a_ab = line([xy[0], half(a, 1, 2, 0)], rgbcolor="blue", alpha=0.6)
b_ab = line([xy[1], half(a, 2, 0, 1)], rgbcolor="blue", alpha=0.6)
c_ab = line([xy[2], half(a, 0, 1, 2)], rgbcolor="blue", alpha=0.6)
ab_point = point(incircle_center, rgbcolor="blue", pointsize=28)
ab_graph = a_ab + b_ab + c_ab + ab_point
else:
ab_graph = Graphics()
# Medians
if show_median:
a_median = line([xy[0], a_middle[0]], rgbcolor="green", alpha=0.6)
b_median = line([xy[1], a_middle[1]], rgbcolor="green", alpha=0.6)
c_median = line([xy[2], a_middle[2]], rgbcolor="green", alpha=0.6)
median_point = point(
(
(xy[0][0]+xy[1][0]+xy[2][0])/3.0,
(xy[0][1]+xy[1][1]+xy[2][1])/3.0
), rgbcolor="green", pointsize=28
)
median_graph = a_median + b_median + c_median + median_point
else:
median_graph = Graphics()
# Perpendicular Bisectors
if show_pb:
a_pb = line_to_points(a_middle[0], half(a, 1, 2, 0), rgbcolor="red", alpha=0.6)
b_pb = line_to_points(a_middle[1], half(a, 2, 0, 1), rgbcolor="red", alpha=0.6)
c_pb = line_to_points(a_middle[2], half(a, 0, 1, 2), rgbcolor="red", alpha=0.6)
pb_point = point((0, 0), rgbcolor="red", pointsize=28)
pb_graph = a_pb + b_pb + c_pb + pb_point
else:
pb_graph = Graphics()
# Altitudes
if show_alt:
xA, xB, xC = xy[0][0], xy[1][0], xy[2][0]
yA, yB, yC = xy[0][1], xy[1][1], xy[2][1]
a_alt = plot(((xC-xB)*x+(xB-xC)*xA)/(yB-yC)+yA, x, rgbcolor="brown", alpha=0.6)
b_alt = plot(((xA-xC)*x+(xC-xA)*xB)/(yC-yA)+yB, x, rgbcolor="brown", alpha=0.6)
c_alt = plot(((xB-xA)*x+(xA-xB)*xC)/(yA-yB)+yC, x, rgbcolor="brown", alpha=0.6)
alt_lx = (xA*xB*(yA-yB)+xB*xC*(yB-yC)+xC*xA*(yC-yA)-(yA-yB)*(yB-yC)*(yC-yA))/(xC*yB-xB*yC+xA*yC-xC*yA+xB*yA-xA*yB)
alt_ly = (yA*yB*(xA-xB)+yB*yC*(xB-xC)+yC*yA*(xC-xA)-(xA-xB)*(xB-xC)*(xC-xA))/(yC*xB-yB*xC+yA*xC-yC*xA+yB*xA-yA*xB)
alt_intersection = point((alt_lx, alt_ly), rgbcolor="brown", pointsize=28)
alt_graph = a_alt + b_alt + c_alt + alt_intersection
else:
alt_graph = Graphics()
# Euler's Line
if show_euler:
euler_graph = line_to_points(
(0, 0),
(
(xy[0][0]+xy[1][0]+xy[2][0])/3.0,
(xy[0][1]+xy[1][1]+xy[2][1])/3.0
),
rgbcolor="purple",
thickness=2,
alpha=0.7
)
else:
euler_graph = Graphics()
show(
C + triangle + triangle_points + labels + ab_graph + median_graph +
pb_graph + alt_graph + incircle_graph + euler_graph,
figsize=[5,5], xmin=-1, xmax=1, ymin=-1, ymax=1
)