You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
3.0 KiB
95 lines
3.0 KiB
#!/usr/local/bin/python3
|
|
"""Script to generate a fixture of a box falling on a saw."""
|
|
|
|
import argparse
|
|
import json
|
|
import pathlib
|
|
|
|
import numpy
|
|
|
|
from fixture_utils import *
|
|
|
|
|
|
def generate_fixture(args: argparse.Namespace) -> dict:
|
|
"""Generate a fixture of Newton's cradle."""
|
|
fixture = generate_custom_fixture(args)
|
|
rigid_bodies = fixture["rigid_body_problem"]["rigid_bodies"]
|
|
|
|
radius = 0.5
|
|
|
|
hx = (args.num_balls * (2 * radius + 0.1) + 4.1) / 2
|
|
cx = hx - 4.1
|
|
rigid_bodies.append(generate_walls_body(hx, hx, numpy.array([cx, 0]), 0.1))
|
|
|
|
ball_vertices = generate_regular_ngon_vertices(args.num_points, radius)
|
|
ball_edges = generate_ngon_edges(args.num_points)
|
|
|
|
ball_mass = 1
|
|
ball_area = compute_regular_ngon_area(ball_vertices)
|
|
ball_density = ball_mass / ball_area
|
|
|
|
ball = {
|
|
"vertices": ball_vertices.tolist(),
|
|
"polygons": [ball_vertices.tolist()],
|
|
"edges": ball_edges.tolist(),
|
|
"oriented": True,
|
|
"is_dof_fixed": [False, False, False],
|
|
"masses": numpy.full(args.num_points,
|
|
ball_mass / args.num_points).tolist(),
|
|
"density": ball_density
|
|
}
|
|
for i in range(args.num_balls):
|
|
ball["position"] = [
|
|
-3 if i == 0 else ((i - 1) * (2 * radius + 0.1)), 0.0
|
|
]
|
|
ball["theta"] = ((i % 2) if args.rotated else 1) * numpy.rad2deg(
|
|
numpy.pi / args.num_points)
|
|
ball["velocity"] = [10.0 if i == 0 else 0.0, 0, 0]
|
|
rigid_bodies.append(ball.copy())
|
|
|
|
return fixture
|
|
|
|
|
|
def main():
|
|
"""Parse command-line arguments to generate the desired fixture."""
|
|
parser = create_argument_parser(
|
|
description="generate a Newton's Cradle fixture",
|
|
default_initial_epsilon=1e-2,
|
|
default_restitution_coefficient=1)
|
|
parser.add_argument("--num-balls",
|
|
type=int,
|
|
default=5,
|
|
help="number of balls in the cradle")
|
|
parser.add_argument(
|
|
"--num-points",
|
|
type=int,
|
|
default=8,
|
|
help="number of points/edges used to discritize the balls")
|
|
parser.add_argument("--not-rotated",
|
|
action="store_false",
|
|
dest="rotated",
|
|
help="do not rotate alternating balls")
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.out_path is None:
|
|
directory = (pathlib.Path(__file__).resolve().parents[1] / "fixtures" /
|
|
"newtons-cradle")
|
|
filename = ("newtons-cradle"
|
|
f"-num_balls={args.num_balls:d}"
|
|
f"-num_points={args.num_points:d}"
|
|
f"{'' if args.rotated else '-not-rotated':s}"
|
|
f"-cor={args.restitution_coeff:g}"
|
|
".json")
|
|
args.out_path = directory / filename
|
|
args.out_path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
print_args(args)
|
|
|
|
fixture = generate_fixture(args)
|
|
|
|
save_fixture(fixture, args.out_path)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|