-
Notifications
You must be signed in to change notification settings - Fork 1
/
generate_two_post_loop.py
152 lines (108 loc) · 5.5 KB
/
generate_two_post_loop.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import argparse
import math
import sys
import build_shape
import combine_functions
import marble_path
"""
Builds a sequence of loops between two posts.
Three loops
-----------
The default arguments build three loops that fit exactly between posts
150 mm tall
python generate_two_post_loop.py
Default shape is 154.59 wide. 154.59 / 2 = 77.29. Assuming loop
length is 82, so the ellipse is 41 long, the post is 31 in diameter,
the tube radius is 12.5, and the wall thickness is 2, we get that this
should be positioned at:
77.29 - 12.5 - 31 + 2 - 41
Loops go at (5.21, 0)
posts go at (0, 32) and (134, 32)
posts rotate by 138
To generate the holes in the post:
python generate_two_post_loop.py --loop_length 82 --tube_radius 10.5 --wall_thickness 11 --tube_start_angle 0 --tube_end_angle 360
Similar math puts the holes at 5.21
1.5 loops going through the posts
---------------------------------
The previous model has the loops going between the posts. This one
has the loop going through the posts. Only 1.5 loops, since more
would make it incredibly unpleasant to get the supports out.
python generate_two_post_loop.py --loop_length 134 --slope_angle 6.5 --num_loops 1 --tube_method OVAL --tube_wall_height 6 --tube_start_angle 0
posts rotate by 158
holes:
left post, with a triangle hole:
python generate_two_post_loop.py --loop_length 134 --slope_angle 6.5 --num_loops 1 --tube_method TRIANGLE_TOP --tube_roof_angle 30 --tube_start_angle 0 --tube_end_angle 360 --tube_radius 10.5 --wall_thickness 11
right post:
python generate_two_post_loop.py --loop_length 134 --slope_angle 6.5 --num_loops 1 --tube_start_angle 0 --tube_end_angle 360 --tube_radius 10.5 --wall_thickness 11
the left bottom hole needs a tunnel. this should work:
python generate_two_post_loop.py --loop_length 134 --slope_angle 6.5 --num_loops 1 --tube_method TRIANGLE_TOP --tube_roof_angle 30 --tube_start_angle 0 --tube_end_angle 360 --tube_radius 12.5
"""
def describe_curve(args):
print("Building loops between two posts")
print("{} loop(s) between posts which are {} apart".format(args.num_loops, args.post_distance))
print("Ellipses making up the loops are {} long and {} wide".format(args.loop_length, args.loop_width))
def build_x_y_r_t(args):
loop_through_post = abs(args.post_distance - args.loop_length) < 0.1
print("Loops go through post: {}".format(loop_through_post))
if loop_through_post:
# extra half curve so it starts and ends at different posts
num_loops = args.num_loops + 0.5
num_loop_steps = args.num_time_steps
t_offset = -math.pi
else:
# start and end segments are the curves into the post
num_loops = args.num_loops
num_segments = 4 * args.num_loops + 2
start_steps = args.num_time_steps // num_segments
end_steps = args.num_time_steps // num_segments
num_loop_steps = args.num_time_steps - start_steps - end_steps
t_offset = -math.pi / 2
def time_t(time_step):
return time_step * 2 * math.pi * num_loops / num_loop_steps + t_offset
def x_t(time_step):
t = time_t(time_step)
return math.cos(t) * args.loop_length / 2 + args.post_distance / 2
def y_t(time_step):
t = time_t(time_step)
return math.sin(t) * args.loop_width / 2
r_t = marble_path.numerical_rotation_function(x_t, y_t)
if not loop_through_post:
slope_angle_t = lambda x: args.slope_angle
args.zero_circle_sides = start_steps
num_time_steps, x_t, y_t, _, r_t = combine_functions.add_zero_circle(args, True, num_loop_steps, x_t, y_t, slope_angle_t, r_t)
args.zero_circle_sides = end_steps
num_time_steps, x_t, y_t, _, r_t = combine_functions.add_zero_circle(args, False, num_time_steps, x_t, y_t, slope_angle_t, r_t, endpoint_x=args.post_distance)
return x_t, y_t, r_t
def parse_args(sys_args=None):
parser = argparse.ArgumentParser(description='Arguments for a two post loop')
marble_path.add_tube_arguments(parser, default_slope_angle=7, default_output_name='loops.stl')
parser.add_argument('--num_time_steps', default=280, type=int,
help='Number of time steps in the whole ramp')
parser.add_argument('--num_loops', default=3, type=int,
help='How many times to loop')
parser.add_argument('--post_distance', default=134, type=float,
help='Distance from one post to another')
parser.add_argument('--post_radius', default=15.5, type=float,
help='Radius of a post')
parser.add_argument('--loop_length', default=None, type=float,
help='The ellipse axis between the posts')
parser.add_argument('--loop_width', default=70, type=float,
help='The ellipse axis perpendicular to the posts')
parser.set_defaults(tube_start_angle=-45)
args = parser.parse_args(args=sys_args)
# To get the loops to just contact the wall of the tube, we calculate:
# the center will be at 67
# the tube radius is 12.5
# the post radius is 15.5
# wall thickness is 2
# 67 - 12.5 - 15.5 + 2 = 41
# so we want the loops to be 82 long
if args.loop_length is None:
args.loop_length = (args.post_distance / 2 - args.tube_radius - args.post_radius + args.wall_thickness) * 2
print("Using a loop length of {}".format(args.loop_length))
return args
def main(sys_args=None):
module = sys.modules[__name__]
build_shape.main(module, sys_args)
if __name__ == '__main__':
main()