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