Created
April 17, 2026 17:00
-
-
Save dwblair/c7c9616d8d25a7138c74e9c8c1dfaa69 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| // Playmobil Curved Sword — parametric OpenSCAD | |
| // Based on hand sketch: curved blade (both edges), guard, rounded pommel | |
| // Print flat on bed. Adjust handle_dia to fit Playmobil hand grip. | |
| /* --- Tunable Parameters --- */ | |
| // Handle (must fit Playmobil C-clip hand) | |
| handle_dia = 3.5; // mm — start here, test fit, adjust +/- 0.2 | |
| handle_len = 12; // mm | |
| // Guard | |
| guard_width = 10; // mm — total width of crossguard | |
| guard_height = 3; // mm — height along blade axis | |
| guard_thick = 3; // mm — thickness (z) | |
| guard_curve_up = 4; // mm — how far the blade-side tip curves upward | |
| guard_bar_dia = 2; // mm — diameter of the guard bar | |
| // Blade | |
| blade_len = 35; // mm — from guard to tip | |
| blade_width = 8; // mm — widest point near guard | |
| blade_thick = 2; // mm — flat profile thickness (z) | |
| blade_curve = 6; // mm — lateral curve offset at midpoint | |
| // Pommel | |
| pommel_dia = 8; // mm | |
| pommel_thick = 6; // mm | |
| // Resolution | |
| $fn = 64; | |
| /* --- Modules --- */ | |
| // Curved blade profile — hull between cross-sections | |
| module blade() { | |
| // Blade is a series of hulled elliptical cross-sections | |
| // from guard to tip, with lateral curve on both edges | |
| steps = 40; | |
| for (i = [0:steps-1]) { | |
| t0 = i / steps; | |
| t1 = (i + 1) / steps; | |
| hull() { | |
| blade_slice(t0); | |
| blade_slice(t1); | |
| } | |
| } | |
| } | |
| module blade_slice(t) { | |
| // t = 0 at guard, t = 1 at tip | |
| // Width tapers from blade_width to 0 | |
| // X position curves using sine for the scimitar sweep | |
| y = guard_height/2 + t * blade_len; | |
| // Curve: sine sweep for scimitar shape | |
| x = blade_curve * sin(t * 120); | |
| // Width taper: starts at blade_width, narrows to point | |
| w = blade_width * (1 - pow(t, 0.8)); | |
| // Thickness taper: slight taper toward tip | |
| th = blade_thick * (1 - 0.3 * pow(t, 1.5)); | |
| translate([x, y, 0]) | |
| scale([max(w, 0.3), 1, max(th, 0.4)]) | |
| sphere(d=1); | |
| } | |
| // Guard — curved crossguard connected at both ends, blade-side curves up | |
| module guard() { | |
| steps = 20; | |
| half_w = guard_width / 2; | |
| // Sweep a circle along a curved path from -half_w to +half_w | |
| for (i = [0:steps-1]) { | |
| t0 = i / steps; | |
| t1 = (i + 1) / steps; | |
| hull() { | |
| guard_point(t0); | |
| guard_point(t1); | |
| } | |
| } | |
| } | |
| module guard_point(t) { | |
| // t goes 0 to 1 across the guard width | |
| half_w = guard_width / 2; | |
| x = -half_w + t * guard_width; | |
| // D-shape: ends connect at blade/handle junction (y=0), center bows downward | |
| curve_factor = 4 * t * (1 - t); // parabola: 0 at ends, 1 at center | |
| y_up = -guard_curve_up * curve_factor; // 0 at ends, dips down at center | |
| translate([x, y_up, 0]) | |
| sphere(d=guard_bar_dia); | |
| } | |
| // Handle — cylinder sized for Playmobil grip | |
| module handle() { | |
| translate([0, -handle_len/2, 0]) | |
| rotate([-90, 0, 0]) | |
| cylinder(d=handle_dia, h=handle_len, center=false); | |
| } | |
| // Pommel — squashed sphere at bottom of handle | |
| module pommel() { | |
| translate([0, -handle_len, 0]) | |
| scale([pommel_dia, pommel_dia * 0.6, pommel_thick]) | |
| sphere(d=1); | |
| } | |
| /* --- Assembly --- */ | |
| module sword() { | |
| color("silver") blade(); | |
| translate([2.5,-5,0]) | |
| rotate([0,0,90]) | |
| color("gold") guard(); | |
| translate([0,-5,0]) | |
| color("sienna") handle(); | |
| translate([0,13,0]) | |
| color("gold") pommel(); | |
| translate([0,1,0]) | |
| color("gold") pommel(); | |
| } | |
| sword(); | |
| // Print info | |
| echo(str("Total length: ~", handle_len + guard_height + blade_len + pommel_dia*0.3, " mm")); | |
| echo(str("Handle diameter: ", handle_dia, " mm (adjust for Playmobil fit)")); | |
| echo(str("Blade thickness: ", blade_thick, " mm (print flat on bed)")); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment