Created
May 7, 2021 18:40
-
-
Save NoraCodes/57abd00bb12cf58e6b11cf0cbec91967 to your computer and use it in GitHub Desktop.
Melodies from the Area of the Triangle Swept Out by Bodies on Circular Orbits
This file contains 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 matplotlib.pyplot as plt | |
import math | |
# Radii of the bodies. | |
RAD0 = 7 | |
RAD1 = 11 | |
RAD2 = 15 | |
# How many cycles to compute. | |
CYC = 1 | |
# Sample/Hold conditions. The least restrictive condition is chosen. | |
SH = { | |
#"always": True, # Uncomment for smooth, unS&H'd output | |
#"timer": 13, # Uncomment to sample every N steps. Primes are the best. | |
"triggers": True, # Uncomment to trigger on zeniths | |
} | |
class Body: | |
def __init__(self, radius, angle): | |
self.radius = radius | |
self.angle = angle | |
def position(self): | |
return [self.radius * math.cos(self.angle), self.radius * math.sin(self.angle)] | |
fig, ax = plt.subplots() | |
def positions_of_body_at_radius(radius): | |
positions = [] | |
body = Body(radius, 0) | |
time_multiplier = 100 / radius | |
for angle in range(0, 360 * CYC): | |
body.angle = math.radians(angle * time_multiplier) | |
positions += [body.position()] | |
return positions | |
positions_zip = zip(positions_of_body_at_radius(RAD0), positions_of_body_at_radius(RAD1), positions_of_body_at_radius(RAD2)) | |
def distance(p0, p1): | |
return math.sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2) | |
def close(x0, x1): | |
return abs(x0 - x1) < 0.01 | |
def condition(a, b, c, tak): | |
if "always" in SH: | |
return True | |
if "timer" in SH: | |
return tak % SH["timer"] == 0 | |
if "triggers" in SH: | |
return close(RAD0 - RAD1, a) or close(RAD1 - RAD2, b) or close(RAD2 - RAD0, c) or close(RAD0 + RAD1, a) or close(RAD1 + RAD2, b) or close(RAD2 + RAD0, c) | |
areas = [] | |
xs = [] | |
lastarea = 0 | |
for (tak, (p0, p1, p2)) in enumerate(positions_zip): | |
a = distance(p0, p1) | |
b = distance(p1, p2) | |
c = distance(p2, p0) | |
s = (a + b + c)/2 | |
if condition(a, b, c, tak): | |
lastarea = [(s*(s-a)*(s-b)*(s-c)) ** 0.5] | |
xs += [tak] | |
areas += [lastarea] | |
ax.plot(xs, areas) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment