mirror of
https://github.com/Theaninova/Brick-Monorail.git
synced 2026-01-09 11:32:52 +00:00
feat: bezier tracks
This commit is contained in:
1
BOSL2
Submodule
1
BOSL2
Submodule
Submodule BOSL2 added at 33914a5d29
24
README.md
24
README.md
@@ -1,5 +1,23 @@
|
|||||||
# Brick Monorail
|
# Brick Monorail
|
||||||
|
|
||||||
|
Parametric Lego-compatible monorail tracks, designed specifically for 3d printing.
|
||||||
|
|
||||||
|
Since the parts are made parametric, you can have any length or curve radius you want,
|
||||||
|
but these are the original tracks you can replicate
|
||||||
|
|
||||||
|
| Lego Name | Parameters |
|
||||||
|
| ----------------- | ------------------------ |
|
||||||
|
| Straight Long | `monorailStraight(l=32)` |
|
||||||
|
| Straight Short | `monorailStraight(l=8)` |
|
||||||
|
| Curve Long | `monorailCurve90(r=28)` |
|
||||||
|
| Curve Short Left | ❌ |
|
||||||
|
| Curve Short Right | ❌ |
|
||||||
|
| Ramp Upper Part | ❌ |
|
||||||
|
| Ramp Lower Part | ❌ |
|
||||||
|
| Monoswitch | ❌ |
|
||||||
|
| Point Right | ❌ |
|
||||||
|
| Point Left | ❌ |
|
||||||
|
|
||||||
## Design differences
|
## Design differences
|
||||||
|
|
||||||
Injection molding has vastly different requirements to 3d printing.
|
Injection molding has vastly different requirements to 3d printing.
|
||||||
@@ -7,8 +25,10 @@ Due to this the original rails print absolutely horribly due to the copious amou
|
|||||||
Surfaces printed on supports just never look good.
|
Surfaces printed on supports just never look good.
|
||||||
|
|
||||||
Because of that, I decided to instead of having a support part on the bottom, I'd carve out space for
|
Because of that, I decided to instead of having a support part on the bottom, I'd carve out space for
|
||||||
two stacked 1x2 plates, as well as a special two-high printable brick you can use for compatibility with the
|
a 1x2 plate, which you can fit there for the same effect.
|
||||||
old support mounts.
|
|
||||||
|
The monorail tracks are also solid now, which is not something you can do in injection molding but leaves
|
||||||
|
a really nice surface finish at the bottom of the rail for us.
|
||||||
|
|
||||||
_These are 3d printing optimized, compatible rails, not replicas. Replicas print horribly due to support._
|
_These are 3d printing optimized, compatible rails, not replicas. Replicas print horribly due to support._
|
||||||
|
|
||||||
|
|||||||
1
lib/BOSL
1
lib/BOSL
Submodule lib/BOSL deleted from 4ce427a8a3
30
track.json
Normal file
30
track.json
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"fileFormatVersion": "1",
|
||||||
|
"parameterSets": {
|
||||||
|
"90 Degree Curve": {
|
||||||
|
"Radius": "28",
|
||||||
|
"Length": "32",
|
||||||
|
"Type": "curve"
|
||||||
|
},
|
||||||
|
"Full Straight": {
|
||||||
|
"Radius": "28",
|
||||||
|
"Length": "32",
|
||||||
|
"Type": "straight"
|
||||||
|
},
|
||||||
|
"Half Straight": {
|
||||||
|
"Radius": "28",
|
||||||
|
"Length": "16",
|
||||||
|
"Type": "straight"
|
||||||
|
},
|
||||||
|
"Quarter Straight": {
|
||||||
|
"Radius": "28",
|
||||||
|
"Length": "8",
|
||||||
|
"Type": "straight"
|
||||||
|
},
|
||||||
|
"4 Studs Straight": {
|
||||||
|
"Radius": "28",
|
||||||
|
"Length": "4",
|
||||||
|
"Type": "straight"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
135
track.scad
135
track.scad
@@ -1,7 +1,17 @@
|
|||||||
include <lib/BOSL/shapes.scad>;
|
include <BOSL2/std.scad>;
|
||||||
include <lib/BOSL/transforms.scad>;
|
include <BOSL2/beziers.scad>;
|
||||||
include <lib/BOSL/constants.scad>;
|
|
||||||
include <lib/BOSL/beziers.scad>;
|
Type="straight"; // [straight, curve]
|
||||||
|
// Only applies to straight tracks
|
||||||
|
Length=8; // [4:1:56]
|
||||||
|
// Only applies to curves
|
||||||
|
Radius=28; // [4:1:36]
|
||||||
|
// The angle at which the curve starts
|
||||||
|
StartAngle=0; // [0:15:360]
|
||||||
|
// The angle at which the curve ends
|
||||||
|
EndAngle=45; // [0:15:360]
|
||||||
|
|
||||||
|
module __CustomizerLimit__() {}
|
||||||
|
|
||||||
$LDU=0.4;
|
$LDU=0.4;
|
||||||
|
|
||||||
@@ -18,10 +28,6 @@ $edgeTolerance=$LDU / 2;
|
|||||||
|
|
||||||
$len = 20;
|
$len = 20;
|
||||||
|
|
||||||
|
|
||||||
//translate([28.75, -232, -5.75]) rotate([0, 0, 90]) import("straight.stl");
|
|
||||||
|
|
||||||
|
|
||||||
$baseHeight = $tile;
|
$baseHeight = $tile;
|
||||||
$baseWidth = 4 * $tile;
|
$baseWidth = 4 * $tile;
|
||||||
|
|
||||||
@@ -51,12 +57,12 @@ module tooth() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module brickSlot(w=1, l=1, h=3) {
|
module brickSlot(w=1, l=1, h=3) {
|
||||||
cuboid([$tile * w, $tile * l, $plate * h], align=V_DOWN);
|
cube([$tile * w, $tile * l, $plate * h], anchor=TOP);
|
||||||
mirror_copy([1, 0, 0])
|
mirror_copy([1, 0, 0])
|
||||||
mirror_copy([0, 1, 0])
|
mirror_copy([0, 1, 0])
|
||||||
translate([$tile / 2, $tile / 2, 0])
|
translate([$tile / 2, $tile / 2, 0])
|
||||||
cyl(d=$fillet, h=$plate * h, align=V_DOWN, $fn=12);
|
cyl(d=$fillet, h=$plate * h, anchor=TOP, $fn=12);
|
||||||
cuboid([$stud, $stud, $studHeight * 2], align=V_TOP);
|
cube([$stud, $stud, $studHeight * 2], anchor=BOTTOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
module endCapStraight() {
|
module endCapStraight() {
|
||||||
@@ -64,44 +70,44 @@ module endCapStraight() {
|
|||||||
union() {
|
union() {
|
||||||
difference() {
|
difference() {
|
||||||
union() {
|
union() {
|
||||||
cuboid([$width, $tile * 2, $tile], edges=EDGE_BOT_FR+EDGE_BOT_RT+EDGE_BOT_LF);
|
cube([$width, $tile * 2, $tile], anchor=CENTER);
|
||||||
difference() {
|
difference() {
|
||||||
mirror_copy([0, 1, 0])
|
mirror_copy([0, 1, 0])
|
||||||
translate([0, $tile / 2, 0])
|
translate([0, $tile / 2, 0])
|
||||||
cyl(l=$width + $studHeight * 2, d=$stud, orient=ORIENT_X, $fn=24);
|
cyl(l=$width + $studHeight * 2 + $LDU / 2, d=$stud + $LDU, orient=LEFT, $fn=24);
|
||||||
mirror_copy([1, 0, 0])
|
mirror_copy([1, 0, 0])
|
||||||
translate([$tile * 2, 0, -$stud / 2])
|
translate([$tile * 2, 0, -$stud / 2 - 0.2])
|
||||||
rotate([0, -14, 0])
|
rotate([0, -7, 0])
|
||||||
cuboid([$studHeight * 10, $tile * 4, $LDU * 2], align=V_TOP+V_LEFT);
|
cube([$studHeight * 10, $tile * 4, $LDU], anchor=BOTTOM+RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
translate([$tile, -$tile, 0]) cuboid([8 * $LDU, $LDU, $tile], align=V_RIGHT+V_FRONT);
|
translate([$tile, -$tile, 0]) cube([8 * $LDU, $LDU, $tile], anchor=LEFT+BACK);
|
||||||
}
|
}
|
||||||
// Fingernail slot
|
|
||||||
mirror_copy([1, 0, 0])
|
|
||||||
translate([$width / 2, 0, $tile / 2])
|
|
||||||
cuboid([$LDU, $tile, $LDU])
|
|
||||||
|
|
||||||
translate([$plate, $tile / 2, $tile - $LDU]) cube([$LDU, $tile, $LDU]);
|
|
||||||
translate([$width + $plate - $LDU, $tile / 2, $tile - $LDU]) cube([$LDU, $tile, $LDU]);
|
|
||||||
|
|
||||||
// Brick slots
|
// Brick slots
|
||||||
mirror_copy([1, 0, 0])
|
mirror_copy([1, 0, 0])
|
||||||
translate([$tile / 2, -$tile / 2, $tile / 2 - $plate * 2])
|
translate([$tile / 2, -$tile / 2, $tile / 2 - $plate * 2])
|
||||||
brickSlot();
|
brickSlot();
|
||||||
// Bridging improvements
|
// Bridging improvements
|
||||||
translate([0, 0, $tile / 2 - $plate * 2]) cuboid([$tile * 2, $tile - 4 * $LDU, $LDU], align=V_FRONT);
|
translate([0, 0, $tile / 2 - $plate * 2]) cube([$tile * 2, $tile - 4 * $LDU, $LDU], anchor=BACK);
|
||||||
translate([0, -4 * $LDU, $tile / 2 - $plate * 2]) cuboid([$tile * 2, $stud, $LDU * 2], align=V_FRONT);
|
translate([0, -4 * $LDU, $tile / 2 - $plate * 2]) cube([$tile * 2, $stud, $LDU * 2], anchor=BACK);
|
||||||
|
|
||||||
|
// Fingernail slot
|
||||||
|
mirror_copy([1, 0, 0])
|
||||||
|
translate([$width / 2, 0, $tile / 2])
|
||||||
|
cube([$LDU * 3, $tile, $LDU * 3], anchor=CENTER)
|
||||||
|
|
||||||
|
translate([$plate, $tile / 2, $tile - $LDU]) cube([$LDU, $tile, $LDU]);
|
||||||
|
translate([$width + $plate - $LDU, $tile / 2, $tile - $LDU]) cube([$LDU, $tile, $LDU]);
|
||||||
|
|
||||||
// End Slots
|
// End Slots
|
||||||
translate([-$tile, -$tile, 0]) cuboid([8 * $LDU, $LDU, $tile], align=V_LEFT+V_BACK);
|
translate([-$tile, -$tile, 0]) cube([8 * $LDU, $LDU, $tile], anchor=RIGHT+FRONT);
|
||||||
place_copies([[-$tile, -$tile + $LDU], [$tile + 8 * $LDU, -$tile, 0]])
|
move_copies([[-$tile, -$tile + $LDU], [$tile + 8 * $LDU, -$tile, 0]])
|
||||||
mirror_copy([1, 0, 0], cp=[-4 * $LDU, 0, 0])
|
mirror_copy([1, 0, 0], cp=[-4 * $LDU, 0, 0])
|
||||||
cyl(d=$fillet, h=$tile, $fn=12);
|
cyl(d=$fillet, h=$tile, $fn=12);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rail
|
// Rail
|
||||||
translate([0, $teethTolerance / 2, $tile / 2]) cuboid([$teethRailWidth, $tile * 2 - $teethTolerance, $plate], align=V_TOP);
|
translate([0, $teethTolerance / 2, $tile / 2]) cuboid([$teethRailWidth, $tile * 2 - $teethTolerance, $plate], anchor=BOTTOM);
|
||||||
translate([0, -$tile, $tile / 2]) group() {
|
translate([0, -$tile, $tile / 2]) group() {
|
||||||
for (i = [0:(2 * $teeth - 1)]) {
|
for (i = [0:(2 * $teeth - 1)]) {
|
||||||
translate([0, i * $teethWidth, 0]) tooth();
|
translate([0, i * $teethWidth, 0]) tooth();
|
||||||
@@ -110,15 +116,66 @@ module endCapStraight() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module curve90(r=12) {
|
module monorailCurve(p0, p1, p2, resolution=512) {
|
||||||
translate([r * $tile, $tile, 0]) endCapStraight();
|
union() {
|
||||||
translate([$tile, r * $tile, 0]) rotate(-90) endCapStraight();
|
/*translate([r * $tile, $tile, 0]) endCapStraight();
|
||||||
//ir = ($r
|
translate([$tile, r * $tile, 0]) rotate(-90) endCapStraight();
|
||||||
path = [[2 * $tile, r * $tile, 0], [r * $tile / 2, r * $tile, 0], [r * $tile, r * $tile / 2, 0], [r * $tile, 2 * $tile, 0]];
|
|
||||||
extrude_2d_shapes_along_bezier(path) {
|
$radius = (r - 2) * $tile;*/
|
||||||
circle(r=10);
|
|
||||||
|
bez = [p0, p1, p2];
|
||||||
|
debug_bezier(bez, N=len(bez)-1);
|
||||||
|
$n_teeth = round(bezier_length(bez) / $tile * $teeth);
|
||||||
|
echo($n_teeth);
|
||||||
|
$points = bezier_curve(bez, $n_teeth);
|
||||||
|
|
||||||
|
translate($points[0]) rot(from=[0, 1, 0], to=bezier_tangent(bez, 0)) fwd($tile) endCapStraight();
|
||||||
|
translate($points[len($points) - 1]) rot(from=[0, -1, 0], to=bezier_tangent(bez, 1)) fwd($tile) endCapStraight();
|
||||||
|
path_sweep([
|
||||||
|
[-$teethRailWidth / 2, $tile / 2 + $plate],
|
||||||
|
[-$teethRailWidth / 2, $tile / 2],
|
||||||
|
[-2 * $tile, $tile / 2],
|
||||||
|
[-2 * $tile, -$tile / 2],
|
||||||
|
[2 * $tile, -$tile / 2],
|
||||||
|
[2 * $tile, $tile / 2],
|
||||||
|
[$teethRailWidth / 2, $tile / 2],
|
||||||
|
[$teethRailWidth / 2, $tile / 2 + $plate],
|
||||||
|
], $points, tangent=bezier_tangent(bez, [0:1/$n_teeth:1]));
|
||||||
|
translate([0, 0, $tile / 2]) path_copies($points, n=$n_teeth) rotate([-90, 90, 0]) tooth();
|
||||||
|
|
||||||
|
//extrude_2d_shapes_along_bezier(path) square([4 * $tile, $tile]);
|
||||||
|
|
||||||
|
/*translate([2 * $tile, 2 * $tile]) intersection() {
|
||||||
|
arced_slot(r=$radius, h=$tile, sd=4 * $tile, sa=sa, ea=ea, $fn=resolution);
|
||||||
|
}
|
||||||
|
translate([2 * $tile, 2 * $tile, $tile / 2])
|
||||||
|
arced_slot($radius, h=$plate, sd=$teethRailWidth, align=V_TOP, sa=sa, ea=ea, $fn=resolution);
|
||||||
|
translate([2 * $tile, 2 * $tile, $tile / 2])
|
||||||
|
arc_of(n = round(((PI * $radius) / (180 / (ea - sa))) / $tile * $teeth), r=(r - 2) * $tile, rot=true, sa=sa, ea=ea, $fn=resolution)
|
||||||
|
tooth();*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//curve90();
|
module monorailStraight(l) {
|
||||||
endCapStraight();
|
union() {
|
||||||
|
translate([0, $tile, 0]) endCapStraight();
|
||||||
|
translate([0, (l - 1) * $tile, 0]) rotate(180) endCapStraight();
|
||||||
|
if (l > 4) {
|
||||||
|
translate([0, $tile * 2, 0]) cube([4 * $tile, (l - 4) * $tile, $tile], anchor=FRONT);
|
||||||
|
translate([0, $tile * 2, $tile / 2]) cube([$teethRailWidth, (l - 4) * $tile, $plate], anchor=BOTTOM+FRONT);
|
||||||
|
translate([0, $tile * 2, $tile / 2]) group() {
|
||||||
|
for (i = [0:($teeth * (l - 4) - 1)]) {
|
||||||
|
translate([0, i * $teethWidth, 0]) tooth();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Type == "straight")
|
||||||
|
monorailStraight(l=Length);
|
||||||
|
else if (Type == "curve")
|
||||||
|
monorailCurve(p0=[0, 0, 0], p1=[5, 40, 0], p2=[80, 80, 0]);
|
||||||
|
|
||||||
|
// endCapStraight();
|
||||||
|
// translate([28.75, -232, -5.75]) rotate([0, 0, 90]) import("straight.stl");
|
||||||
|
|||||||
Reference in New Issue
Block a user