Find coordinates of isosceles triangle with maximum area bounded by ellipse

Viewed 218

"Redirected" here from math overflow: https://mathoverflow.net/questions/372704/find-coordinates-of-isosceles-triangle-with-maximum-area-bounded-by-ellipse

I have a window with an ellipse inscribed inside it. The ellipses radii are screen_width / 2 and screen_height / 2. I want to find the coordinates of the maximum isosceles triangle that will fit in the ellipse without overflowing.

The direction of the triangle's tip is a enum parameter (i.e., N, E, S, W). From what I've read, there is not a unique solution, but the maximum area is a simple formula and there is a way to find a triangle that solves the problem. That way, however, is merely hinted at, and probably involves using linear algebra to normalize the eclipse and isosceles triangle to a unit circle and an equilateral triangle, but no such formula seems to exist online.

3 Answers

An equilateral triangle inscribed in a circle is the triangle that covers the max area of the circle (some theorem that you should look up).

An ellipse is a "squished" circle, therefore, if we squish a circle with an inscribed equilateral triangle, providing we do that along a line of symmetry, we end up with a max area isosceles triangle (two sides get resized by a common factor, the 3rd side gets stretched by another factor).

The angles follow the inscribed angle theorem and complementary angle theorem

Considering your screen is wider than it is high, the coordinates of the 3 apex of the triangle are as follows (in screen coordinates, with the origin at top left)

top: (w/2, 0)  # this one does not change
bot_left = (w/2 - w*cos(pi/6)/2, h/2 + h*sin(pi/6)/2) 
bot_right = (w/2 + w*cos(pi/6)/2, h/2 + h*sin(pi/6)/2) 

enter image description here

Adding to @Reblochon's answer, Here is a complete example. I attempted it, so why not share it :)

import pygame
from math import sin, cos, pi
pygame.init()

SW = 600
SH = 600
WIN = pygame.display
D = WIN.set_mode((SW, SH))

radiiX = SW/2
radiiY = SH/2

def ellipse(center, rx, ry):
    global gotPositions
    angle = 0
    while angle < 6.28:
        angle += 0.0005

        pygame.draw.circle(D, (255, 255, 0), (int(center[0]), int(center[1])), 2)
        x = center[0] + sin(angle)* radiiX
        y = center[1] + cos(angle)* radiiY
        D.set_at((int(x), int(y)), (255, 255, 0))

top= (SW/2, 0)  # this one does not change
bot_left = (SW/2 - SW*cos(pi/6)/2, SH/2 + SH*sin(pi/6)/2) 
bot_right = (SW/2 + SW*cos(pi/6)/2, SH/2 + SH*sin(pi/6)/2)

points = [top, bot_left, bot_right]

while True:
    D.fill((0, 0, 0))
    events = pygame.event.get()
    for event in events:
        if event.type == pygame.QUIT:
            pygame.quit()

    ellipse([radiiX, radiiY], radiiX, radiiY)
    pygame.draw.lines(D, (255, 255, 0), True, points)
    
    pygame.display.flip()

based on notes from Reblochon Masque

def inner_rect (self):
        rect = self.outer_rect ()             # bounding box of ellipse
        x, y, w, h = rect
        r = self.child.orientation.radians () # direction of triangle
        pts = inscribe_polygon (3, r)
        pts = graphics_affines (pts)          # from cartesian
        pts = scale_points (pts, rect)        # scale points to ellipse dims
        o, r = bounding_rect (pts)
        xmin, ymin = o
        dx, dy = r
        return (xmin, ymin, dx, dy)
Related