ambi-recurve-parts.scad raw
1 // Ambidextrous Recurve Bow — Exploded Parts View
2 // All dimensions in mm. Each part is a separate module.
3 // Render with OpenSCAD: openscad ambi-recurve-parts.scad
4 //
5 // Parts:
6 // 1. Riser (mulberry wood)
7 // 2. Limb strip (316L SS, tapered, recurved tips with flared folds)
8 // 3. M6 countersunk bolts × 3
9 // 4. M6 threaded inserts (heli-coils) × 3
10 // 5. Belleville washer stacks × 3 (recoil dampening at limb-riser interface)
11 // 6. Bowstring (1.5mm SS wire rope)
12 // 7. String dampers × 2
13 // 8. Nocking point ferrule
14 // 9. Arrow shaft (mulberry)
15 // 10. Arrow point (316 SS, machined from bolt)
16 // 11. Cam-flight nock (316L sheet)
17
18 $fn = 64;
19
20 // ============================================================
21 // COLORS
22 // ============================================================
23 wood_color = [0.55, 0.35, 0.18];
24 steel_color = [0.7, 0.72, 0.74];
25 steel_dark = [0.25, 0.26, 0.27]; // QPQ black nitride
26 wire_color = [0.6, 0.62, 0.64];
27 rubber_color = [0.15, 0.15, 0.15];
28
29 // ============================================================
30 // 1. RISER
31 // ============================================================
32 module riser() {
33 color(wood_color)
34 difference() {
35 // Main body — tapered profile with grip narrowing
36 hull_riser();
37 // Limb groove — full length slot
38 limb_groove();
39 // Bolt holes × 3
40 for (i = [-1, 0, 1])
41 translate([0, i * 30, 0])
42 rotate([0, 90, 0])
43 cylinder(d=6.5, h=80, center=true);
44 // Arrow shelves — two symmetric cutouts at ±75mm from center
45 for (s = [-1, 1])
46 translate([s > 0 ? -20 : 10, s * 75, 8])
47 cube([12, 20, 12]);
48 // Sight windows — mirrored cutouts above shelves
49 for (s = [-1, 1])
50 translate([s > 0 ? -18 : 8, s * 75 + s * 10, 4])
51 cube([10, 30, 20]);
52 }
53 }
54
55 module hull_riser() {
56 // C2-symmetric riser body, 280mm long, tapered width
57 // Grip at center is 76mm wide, throat narrows to 31mm
58 // Depth 28mm at grip
59 translate([0, 0, 0])
60 linear_extrude(height=28, center=false)
61 riser_profile_2d();
62 }
63
64 module riser_profile_2d() {
65 // 2D outline: widest at center (76mm), narrowing toward ends
66 // Total length 280mm, symmetric
67 polygon(points=[
68 // Right side (positive X), from bottom to top
69 [-38, -140], // bottom tip, half-width 38 (76/2) — but narrower at ends
70 [-15.5, -140], // narrow at bottom end (31mm total)
71 [-20, -120],
72 [-28, -80],
73 [-34, -40],
74 [-38, 0], // widest at center grip
75 [-34, 40],
76 [-28, 80],
77 [-20, 120],
78 [-15.5, 140], // narrow at top end
79 [15.5, 140],
80 [20, 120],
81 [28, 80],
82 [34, 40],
83 [38, 0],
84 [34, -40],
85 [28, -80],
86 [20, -120],
87 [15.5, -140],
88 ]);
89 }
90
91 module limb_groove() {
92 // Slot through riser back face, tapered width matching limb strip
93 // Center: 44mm wide × 3.5mm deep
94 // Ends: 40mm wide × 3.0mm deep
95 // Runs full 280mm length
96 for (i = [0:27]) {
97 frac = abs(i - 13.5) / 13.5;
98 w = 44 - frac * 4; // 44 at center, 40 at ends
99 d = 3.5 - frac * 0.5; // 3.5 at center, 3.0 at ends
100 translate([0, -140 + i * 10, 28 - d])
101 cube([w, 10.1, d + 0.1], center=true);
102 }
103 }
104
105
106 // ============================================================
107 // 2. LIMB STRIP — Single piece 316L SS
108 // ============================================================
109 module limb_strip() {
110 color(steel_dark) {
111 // Central flat section (inside riser, 280mm)
112 limb_flat_section();
113 // Upper working limb with recurve
114 translate([0, 140, 0])
115 limb_arm(1);
116 // Lower working limb with recurve (mirror)
117 translate([0, -140, 0])
118 mirror([0, 1, 0])
119 limb_arm(1);
120 }
121 }
122
123 module limb_flat_section() {
124 // Tapered strip, 280mm long, center in riser
125 // Center: 44mm × 3.5mm, ends: 40mm × 3.0mm
126 for (i = [0:27]) {
127 frac = abs(i - 13.5) / 13.5;
128 w = 44 - frac * 4;
129 t = 3.5 - frac * 0.5;
130 translate([0, -140 + i * 10, 28 - t])
131 cube([w, 10.1, t], center=true);
132 }
133 }
134
135 module limb_arm(side) {
136 // Working limb: 300mm, tapering, with recurve at tip
137 // Taper from riser exit to tip
138 segments = 30;
139 seg_len = 300 / segments;
140
141 for (i = [0:segments-1]) {
142 frac = i / segments;
143 // Width taper: 40mm at base to 20mm at tip
144 w = 40 - frac * 20;
145 // Thickness taper: 3.0mm at base to 1.4mm at tip
146 t = 3.0 - frac * 1.6;
147
148 // Recurve: last 100mm bends forward (away from archer, +X direction)
149 recurve_start = 200; // mm from riser exit
150 pos_y = i * seg_len;
151 pos_x = 0;
152 pos_z = 28 - t;
153
154 if (pos_y > recurve_start) {
155 // Recurve section — arc bending forward
156 angle = (pos_y - recurve_start) / 100 * 70; // up to 70 degrees
157 r = 30; // bend radius
158 arc_x = r * (1 - cos(angle));
159 arc_y = recurve_start + r * sin(angle);
160 translate([arc_x, arc_y, pos_z])
161 rotate([0, 0, 0])
162 cube([w, seg_len, t], center=true);
163 } else {
164 translate([pos_x, pos_y, pos_z])
165 cube([w, seg_len, t], center=true);
166 }
167 }
168
169 // Tip folds — flared string retention (J-shaped fold)
170 translate([0, 280, 24])
171 tip_fold();
172 }
173
174 module tip_fold() {
175 // Flared fold at limb tip for string retention
176 // 15-20mm folded back, flared trumpet shape
177 color(steel_dark) {
178 // Main fold — curved back
179 for (a = [0:5:130]) {
180 r = 5; // mandrel radius
181 translate([r * (1 - cos(a)), -r * sin(a) * 0.1, 0])
182 rotate([a, 0, 0])
183 cube([20, 1.4, 1.4], center=true);
184 }
185 }
186 }
187
188
189 // ============================================================
190 // 3. M6 COUNTERSUNK BOLTS × 3
191 // ============================================================
192 module m6_bolt() {
193 color(steel_color) {
194 // Countersunk head
195 cylinder(d1=12, d2=6, h=3.3);
196 // Shaft
197 translate([0, 0, -20])
198 cylinder(d=6, h=20);
199 }
200 }
201
202
203 // ============================================================
204 // 4. M6 THREADED INSERTS (HELI-COILS) × 3
205 // ============================================================
206 module helicoil() {
207 color(steel_color)
208 difference() {
209 cylinder(d=10, h=10);
210 cylinder(d=5, h=10.1);
211 }
212 }
213
214
215 // ============================================================
216 // 5. BELLEVILLE WASHER STACK — Recoil Dampening
217 // Spring-valve at limb-riser interface
218 // Cut from SS sheet, no new material needed
219 // ============================================================
220 module belleville_washer() {
221 color(steel_color)
222 difference() {
223 // Conical disc spring
224 cylinder(d1=14, d2=12, h=1.2);
225 cylinder(d=6.5, h=1.3);
226 }
227 }
228
229 module belleville_stack() {
230 // Stack of 4 Belleville washers in alternating orientation
231 // Provides spring compliance + friction damping between faces
232 for (i = [0:3]) {
233 translate([0, 0, i * 1.0])
234 if (i % 2 == 0)
235 belleville_washer();
236 else
237 translate([0, 0, 1.2])
238 mirror([0, 0, 1])
239 belleville_washer();
240 }
241 }
242
243
244 // ============================================================
245 // 6. BOWSTRING — 1.5mm SS wire rope
246 // ============================================================
247 module bowstring() {
248 color(wire_color) {
249 // Main string — simplified as a cylinder arc
250 // Brace height ~190mm, string length ~820mm
251 translate([19, 0, 14]) // brace height offset from riser
252 rotate([90, 0, 0])
253 cylinder(d=1.5, h=800, center=true);
254
255 // Thimble loops at each end
256 for (s = [-1, 1])
257 translate([19, s * 400, 14])
258 rotate([0, 90, 0])
259 difference() {
260 torus(r1=6, r2=0.75);
261 }
262
263 // Crimp ferrules at loops
264 for (s = [-1, 1])
265 translate([19, s * 395, 14])
266 cylinder(d=3, h=5, center=true);
267 }
268 }
269
270 module torus(r1, r2) {
271 rotate_extrude()
272 translate([r1, 0, 0])
273 circle(r=r2);
274 }
275
276
277 // ============================================================
278 // 7. STRING DAMPERS × 2
279 // ============================================================
280 module string_damper() {
281 color(rubber_color)
282 difference() {
283 cylinder(d=12, h=4, center=true);
284 cylinder(d=2, h=4.1, center=true);
285 }
286 }
287
288
289 // ============================================================
290 // 8. NOCKING POINT FERRULE
291 // ============================================================
292 module nocking_point() {
293 color(steel_color)
294 difference() {
295 cylinder(d=4, h=3, center=true);
296 cylinder(d=1.6, h=3.1, center=true);
297 }
298 }
299
300
301 // ============================================================
302 // 9. ARROW SHAFT — Mulberry wood
303 // ============================================================
304 module arrow_shaft() {
305 color(wood_color)
306 rotate([90, 0, 0])
307 cylinder(d=8.5, h=700); // ~700mm shaft length
308 }
309
310
311 // ============================================================
312 // 10. ARROW POINT — Machined from M12 316 SS bolt
313 // ============================================================
314 module arrow_point() {
315 color(steel_dark) {
316 // Socket (rear) — accepts shaft, 20mm deep, 8.5mm bore
317 difference() {
318 cylinder(d=11, h=25);
319 translate([0, 0, -0.1])
320 cylinder(d=8.6, h=20.1);
321 }
322 // Body (middle) — 11mm diameter, 35mm long
323 translate([0, 0, 25])
324 cylinder(d=11, h=35);
325 // Tip (front) — tapered cone, 30mm long
326 translate([0, 0, 60])
327 cylinder(d1=11, d2=1, h=30);
328 }
329 }
330
331
332 // ============================================================
333 // 11. CAM-FLIGHT NOCK — Unified component from 316L sheet
334 // ============================================================
335 module cam_flight_nock() {
336 color(steel_dark) {
337 // Cylinder base — rolled from sheet, threaded internally at 45°
338 difference() {
339 cylinder(d=12, h=14);
340 // Bore for shaft
341 cylinder(d=8.6, h=14.1);
342 }
343 // String groove
344 translate([0, 0, 13])
345 rotate([90, 0, 0])
346 cylinder(d=2.5, h=14, center=true);
347
348 // Two wings at 180° — cam-flight surfaces
349 for (a = [0, 180]) {
350 rotate([0, 0, a])
351 translate([0, 0, 0])
352 cam_wing();
353 }
354 }
355 }
356
357 module cam_wing() {
358 // Wing: 25mm long, 10mm tall, 0.9mm thick
359 // Forward section: slight helical twist (cam)
360 // Rear section: flat vane (flight surface)
361 color(steel_dark)
362 translate([0, -0.45, 0]) {
363 // Cam section (forward, attached to cylinder)
364 for (i = [0:9]) {
365 twist = i * 2; // slight twist for cam indexing
366 translate([0, 0, -i * 1.5])
367 rotate([0, twist, 0])
368 cube([10, 0.9, 1.5]);
369 }
370 // Flight section (rearward)
371 translate([0, 0, -25])
372 cube([10, 0.9, 10]);
373 }
374 }
375
376
377 // ============================================================
378 // LAYOUT — Exploded view, all parts spread for visibility
379 // ============================================================
380
381 // Spacing for exploded layout
382 explode = 60;
383
384 // === BOW ASSEMBLY ===
385
386 // 1. Riser
387 translate([0, 0, 0])
388 riser();
389
390 // 2. Limb strip — offset behind riser
391 translate([0, 0, -explode])
392 limb_strip();
393
394 // 3-4-5. Bolts, inserts, and Belleville stacks × 3
395 for (i = [-1, 0, 1]) {
396 // Bolt (approaching from back)
397 translate([-explode, i * 30, 28 + 10])
398 rotate([0, -90, 0])
399 m6_bolt();
400
401 // Belleville stack (between bolt head and limb strip)
402 translate([-explode + 20, i * 30, 28 + 5])
403 belleville_stack();
404
405 // Heli-coil insert (in front face of riser)
406 translate([explode, i * 30, 14])
407 rotate([0, 90, 0])
408 helicoil();
409 }
410
411 // 6. Bowstring — offset to the side
412 translate([explode * 2, 0, 0])
413 bowstring();
414
415 // 7. String dampers — on the bowstring
416 translate([explode * 2 + 19, -160, 14])
417 string_damper();
418 translate([explode * 2 + 19, 160, 14])
419 string_damper();
420
421 // 8. Nocking point
422 translate([explode * 2 + 19, 0, 14])
423 nocking_point();
424
425 // === ARROW (representative, 1 of 6) ===
426
427 // 9. Arrow shaft
428 translate([0, -explode * 5, 50])
429 arrow_shaft();
430
431 // 10. Arrow point — in front of shaft
432 translate([0, -explode * 5 - 710, 50])
433 rotate([-90, 0, 0])
434 arrow_point();
435
436 // 11. Cam-flight nock — behind shaft
437 translate([0, -explode * 5 + 10, 50])
438 rotate([-90, 0, 0])
439 cam_flight_nock();
440
441
442 // === LABELS (comment annotations) ===
443 // OpenSCAD doesn't support text labels in 3D easily,
444 // but parts are spatially separated for identification:
445 //
446 // Center: Riser + Limb strip + bolts/inserts/Bellevilles
447 // Right (+X): Bowstring assembly (string, dampers, nocking point)
448 // Front (-Y): Arrow assembly (point, shaft, cam-flight nock)
449 //
450 // The Belleville washer stacks sit between each bolt head
451 // and the limb strip surface. Under draw and at rest, the
452 // bolt preload compresses the stack. On shot release, the
453 // recoil impulse drives additional compression; friction
454 // between alternating washer faces converts the return
455 // energy to heat, acting as a one-way energy valve —
456 // the "spring valve" vibration diode described in the
457 // design conversation.
458