def test_plot_obstacles(): obs = [ billiards.obstacles.Disk((0, 0), 10), billiards.obstacles.InfiniteWall((-1, -20), (1, -20)), ] bld = billiards.Billiard(obstacles=obs) fig, ax = visualize.default_fig_and_ax() artists = visualize.plot_obstacles(bld, ax) assert len(artists) == len(bld.obstacles)
def _create_newtons_cradle(num_balls=5, with_walls=True): if with_walls: left = -4 right = 2 * num_balls + 3 obs = [ InfiniteWall((left, -2), (left, 2), "right"), InfiniteWall((right, -2), (right, 2)), ] else: obs = [] bld = billiards.Billiard(obstacles=obs) bld.add_ball((-3, 0), (1, 0), 1) for i in range(1, num_balls): bld.add_ball((2 * i, 0), (0, 0), radius=1) return bld
def make_data(obs): ics = [] Xs = [] Ys = [] tss = [] angle = np.random.uniform(low=0, high=(2 * pi), size=(10,)) vels = 0.2 * np.vstack(([np.cos(angle), np.sin(angle)])).T positions = np.vstack(([np.random.uniform(low=-2, high=2, size=(10,)), np.random.uniform(low=-2, high=2, size=(10,))])).T for i in positions: for j in vels: ic = [] ts = [0] bld = billiards.Billiard(obstacles=obs) #print(i.shape, j.shape) bld.add_ball(i, j, radius=0) for k in range(10): [(fl, _)] = bld.obstacles_toi bld.evolve(fl) p, v = bld.balls_position, bld.balls_velocity #print(p.shape, v.shape, fl.shape) ic.append(np.hstack((p, v))) ts.append(fl.reshape(1, 1)) tss.append(ts) #print(np.asarray(ic).shape) ics.append(ic) for i in ics: X = i[:-1] Y = i[1:] Xs.append(X) Ys.append(Y) Xs , Ys = np.asarray(Xs).reshape((100, 9, 4)), np.asarray(Ys).reshape((100, 9, 4)) Ts = np.asarray(tss) np.save("time_steps.npy", Ts, allow_pickle=True) np.save("input.npy", Xs, allow_pickle=True) np.save("output.npy", Ys, allow_pickle=True) print(Ts) print(Xs.shape) print(Ys.shape)
from math import cos, pi, sin from pathlib import Path import matplotlib.pyplot as plt import numpy as np from tqdm import tqdm import billiards from billiards import visualize here = Path(__file__).parent.resolve() # should be docs folder # Quickstart - Setup obstacles = [billiards.obstacles.InfiniteWall((0, -1), (0, 1), inside="right")] bld = billiards.Billiard(obstacles) bld.add_ball((3, 0), (0, 0), radius=0.2) bld.add_ball((6, 0), (-1, 0), radius=1, mass=100 ** 5) fig = visualize.plot(bld) fig.savefig(here / "_images/quickstart_1.svg") v_squared = (bld.balls_velocity ** 2).sum(axis=1) print(f"Kinetic energy before: {(v_squared * bld.balls_mass).sum() / 2}") print() # Quickstart - Iteration print(bld.toi_next) total_collisions = 0 for i in [1, 2, 3, 4, 5]: total_collisions += len(bld.evolve(i))
Reference: Gregory Galperin, "Playing pool with π (the number π from a billiard point of view)", Regular and Chaotic Dynamics, 2003, 8 (4), 375-394 """ from math import isinf, pi import matplotlib.pyplot as plt import billiards from billiards import visualize digits = 6 # number of digits of pi # setup the billiard table: Wall -- mass -<- MASS obstacles = [billiards.obstacles.InfiniteWall((0, -1), (0, 1), inside="right")] bld = billiards.Billiard(obstacles) bld.add_ball((3, 0), (0, 0), radius=0.2) bld.add_ball((6, 0), (-1, 0), radius=1, mass=100 ** (digits - 1)) # simulate until there are no more collisions and print the total number of collisions total_collisions = 0 while not isinf(bld.toi_next[0]) or not isinf(bld.obstacles_next[0]): num_collisions = len(bld.evolve(bld.time + 1)) print(f"From t = {bld.time - 1:4} to t = {bld.time:4}: {num_collisions} collisions") total_collisions += num_collisions print(f"Total number of collisions: {total_collisions}") print(f"Value of pi: {pi}") # reset billiard bld = billiards.Billiard(obstacles)
from billiards import visualize # global settings disk_radius = 0.5 # radius of the disk in the middle num_balls = 300 # increase this if your computer can handle it np.random.seed(0) # fix random state for reproducibility # construct the billiard table obs = [ billiards.InfiniteWall((-1, -1), (1, -1)), # bottom side billiards.InfiniteWall((1, -1), (1, 1)), # right side billiards.InfiniteWall((1, 1), (-1, 1)), # top side billiards.InfiniteWall((-1, 1), (-1, -1)), # left side billiards.Disk((0, 0), radius=disk_radius), # disk in the middle ] bld = billiards.Billiard(obstacles=obs) # distribute particles uniformly in the square, moving in random directions but # with the same speed for _i in range(num_balls): pos = np.random.uniform((-1, -1), (1, 1)) angle = np.random.uniform(0, 2 * pi) vel = [cos(angle), sin(angle)] bld.add_ball(pos, vel, radius=0) bld.balls_velocity /= 5 # slow down # start the animation anim = visualize.animate(bld, end_time=10) anim._fig.set_size_inches((6, 6))
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import billiards print(os.getcwd()) # print current working directory # Quickstart bld = billiards.Billiard() fig_name = "_images/quickstart_1.svg" bld.add_ball((2, 0), (4, 0), radius=1) bld.evolve(end_time=10.0) fig = billiards.visualize.plot(bld) fig.savefig(fig_name) print(fig_name) fig2_name = "_images/quickstart_2.svg" bld.add_ball((50, 18), (0, -9), radius=1, mass=2) bld.evolve(14.0) fig2 = billiards.visualize.plot(bld) fig2.savefig(fig2_name) print(fig2_name) # Usage: Newton's cradle anim_name = "_static/newtons_cradle.mp4" bld = billiards.Billiard() bld.add_ball((0, 0), (1, 0), 1)