[Math] Geometry/Programming- Draw An Equilateral Triangle Given One Point And A Desired Rotation

geometryrotationstriangles

I feel this question has a stronger mathematical basis than strictly computer science.

I am currently drawing an equilateral triangle given its center and its radius like so.

First triangle

I would like to tweak the function to be able to draw another (given a slightly smaller radius) equilateral triangle with its "peak" perpendicular to a midpoint of any of the sides of the first triangle as shown below.

Second trangle

Here is the code I am currently using to draw the first triangle.

import sys
import pygame
import math


class Point2D:
    def __init__(self, xP, yP):
        self.x = xP
        self.y = yP

    def point(self):
        return self.x, self.y


def drawCircumscribedTriangle(center, radius, window):
    xoffset = math.cos(math.pi/6) * radius
    yoffset = math.sin(math.pi/6) * radius

    pygame.draw.line(window, (255, 255, 255),
                     (center.x, center.y - radius), (center.x + xoffset, center.y + yoffset))
    pygame.draw.line(window, (255, 255, 255),
                     (center.x + xoffset, center.y + yoffset), (center.x - xoffset, center.y + yoffset))
    pygame.draw.line(window, (255, 255, 255),
                     (center.x - xoffset, center.y + yoffset), (center.x, center.y - radius))

pygame.init()

#create the screen
screenWidth = 640
screenHeight = 480
rad = 20
centerPoint = Point2D(screenWidth/2, screenHeight/2)

window = pygame.display.set_mode((640, 480))
drawCircumscribedTriangle(centerPoint, rad, window)

#draw it to the screen
pygame.display.flip()

#input handling (somewhat boilerplate code):
while True:
   for event in pygame.event.get():
      if event.type == pygame.QUIT:
          sys.exit(0)

What would be a good way to not only draw based on a "peak" point and rotation, but also, upon drawing the desired triangle, return a list of the angles of that triangle's sides so that subsequent calls could be made drawing more triangles with their peaks oriented similarly inside the one that was just drawn?

Thank you for any help.

EDIT:

After writing the desired program, here is one of the images I have created!

enter image description here

Best Answer

Ok, this answer is a bit lame but anyway.

To achieve what you are searching for you need just two functions

  1. A function that draw a triangle with a given corner point and a rotation and a radius lets call this one drawTriangle
  2. A function that draws supsequent triangles drawMoreTriangles

The problem I ran into when I wanted to create the second part (after getting pygame work again) was that you your triangle drawing function does not work with any rotation but just with a very specific one ($\frac{\pi}{6}$). I noticed this after implementing part 2!

The Problem here is that your Point2D class has really less functionality to work with what you need is a class like this:

class Point2D:
   def __init__(self, x,y):
       self.x = x
       self.y = y

   def __add__(self, obj):
       """ This Function will translate a Point """
       self.x = obj.x
       self.y = obj.y

   def rotate(self, arc):
       """ This function will rotate by arc around (0,0) """
       sa = math.sin(arc)
       ca = math.cos(arc)

       x = ca * self.x - sa * self.y
       self.y = sa * self.x + ca * self.y
       self.x = x

Now you can implement your triangle (part 1) really easy:

def drawTriangle(window, center, radius, rotation):
    corner = Point2D(radius, 0)

    pointlist = [None]

    for i in range(3):
        pointlist[i] = [int(corner.x+center.x), int(corner.y+center.y)]

        if i == 2:
           break

        # Rotate the corner by 60 degrees
        corner = corner.rotate(math.pi/3)        


    pygame.draw.polygon(window, color, pointlist, width)

Now you can also easily achieve (part 2), by using the above function for drawing triangles (if it works did not test yet) and using rotation and translation!

Gonna post a bit more if I've got more time!

Related Question