Created
May 17, 2024 14:31
-
-
Save TERNION-1121/49c3113bdfbc365bed2b093f94e2dc85 to your computer and use it in GitHub Desktop.
A script that simulates the trigonometric functions on the unit circle
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import math | |
import pygame | |
from pygame import Vector2 | |
import pygame_widgets | |
from pygame_widgets.slider import Slider | |
from pygame_widgets.textbox import TextBox | |
pygame.init() | |
# colors | |
BLACK = (50, 50, 50) | |
BLUE = (76, 194, 255) | |
GRAY = (100, 110, 110) | |
GREEN = (5, 255, 175) | |
LIGHT_BLUE = (173, 216, 230) | |
LAVENDER = (230, 230, 250) | |
ORANGE = (255, 160, 100) | |
PEACH = (255, 218, 185) | |
PINK = (255, 112, 119) | |
WHITE = (211, 211, 211) | |
# screen initialisations | |
RADIUS = 150 | |
SCREEN_SIZE = Vector2(1000, 600) | |
ORIGIN = SCREEN_SIZE / 2 | |
screen = pygame.display.set_mode(SCREEN_SIZE) | |
pygame.display.set_caption("Unit Circle Simulation") | |
font = pygame.font.Font(None, 20) | |
text = { | |
'sin': font.render('sin', True, PEACH), | |
'cos': font.render('cos', True, LIGHT_BLUE), | |
'tan': font.render('tan', True, GREEN), | |
'csc': font.render('csc', True, ORANGE), | |
'sec': font.render('sec', True, BLUE), | |
'cot': font.render('cot', True, PINK) | |
} | |
def blit_text(): | |
h = 50 | |
for render in text.values(): | |
screen.blit(render, (50, h)) | |
h += 20 | |
slider = Slider(screen, 300, 550, 400, 20, min=0, max=100, step=0.5, initial=12.5) | |
output_rad = TextBox(screen, 300, 500, 100, 40, fontSize=25) | |
output_deg = TextBox(screen, 570, 500, 130, 40, fontSize=25) | |
output_rad.disable() # act as label instead of textbox | |
output_deg.disable() | |
def draw_graph(rad: float): | |
mid_width = ORIGIN[0] | |
mid_height = ORIGIN[1] | |
# cartesian plane | |
pygame.draw.line(screen, WHITE, (mid_width, 0), (mid_width, 2 * mid_height), 2) | |
pygame.draw.line(screen, WHITE, (0, mid_height), (2 * mid_width, mid_height), 2) | |
# circle | |
pygame.draw.circle(screen, WHITE, ORIGIN, RADIUS, 2) | |
# angle | |
rect = pygame.Rect(ORIGIN - Vector2(20, 20), (40, 40)) | |
pygame.draw.arc(screen, WHITE, rect, 0, rad) | |
# vector magnitude represents function value | |
cos = Vector2(math.cos(rad), 0) * RADIUS | |
sin = Vector2(0, -math.sin(rad)) * RADIUS | |
sec = Vector2(math.cos(rad) ** -1, 0) * RADIUS | |
csc = Vector2(0, -math.sin(rad) ** -1) * RADIUS | |
# point on circle | |
p = cos + sin | |
pygame.draw.aaline(screen, WHITE, ORIGIN, ORIGIN + p) # radius | |
pygame.draw.line(screen, LIGHT_BLUE, ORIGIN + sin, ORIGIN + p, 3) # cos | |
pygame.draw.line(screen, PEACH, ORIGIN + cos , ORIGIN + p, 3) # sin | |
pygame.draw.line(screen, BLUE, ORIGIN, ORIGIN + sec, 3) # sec | |
pygame.draw.line(screen, ORANGE, ORIGIN, ORIGIN + csc, 3) # csc | |
pygame.draw.line(screen, GREEN, ORIGIN + p, ORIGIN + sec, 3) # tan | |
pygame.draw.line(screen, PINK, ORIGIN + p, ORIGIN + csc, 3) # cot | |
running = True | |
while running: | |
events = pygame.event.get() | |
for event in events: | |
if event.type == pygame.QUIT: | |
running = False | |
screen.fill(GRAY) | |
if (percent := slider.getValue()) == 100 or percent == 0: | |
slider.setValue(10e-20) | |
percent = slider.getValue() | |
rad = 2 * math.pi * percent / 100 | |
deg = 360 * percent / 100 | |
output_rad.setText(f"{rad:.2f} rad") | |
output_deg.setText(f"{deg:0>{6}.2f} deg") | |
draw_graph(rad) | |
blit_text() | |
pygame_widgets.update(events) | |
pygame.display.update() | |
pygame.quit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment