Compare commits
4 commits
025575a488
...
35376827d1
Author | SHA1 | Date | |
---|---|---|---|
|
35376827d1 | ||
|
0a3c553512 | ||
|
72797decb0 | ||
|
775167b4e9 |
|
@ -2,15 +2,25 @@
|
||||||
|
|
||||||
// (c) Simon Brooke 2025; CC-BY-SA
|
// (c) Simon Brooke 2025; CC-BY-SA
|
||||||
|
|
||||||
|
include <BOSL2/std.scad>
|
||||||
include <NACAAirfoils/files/Naca4.scad>
|
include <NACAAirfoils/files/Naca4.scad>
|
||||||
include <library/skew.scad>
|
include <library/skew.scad>
|
||||||
|
include <lowerknuckle.scad>
|
||||||
include <wheel.scad>
|
include <wheel.scad>
|
||||||
|
|
||||||
module fourbar_leg(length=1000, chord=100, long_skew=30, lat_skew=30) {
|
$fn=64;
|
||||||
|
|
||||||
|
// Wherever you see unexplained numbers in this file, they are
|
||||||
|
// fudge because I don't yet properly understand the coordinate
|
||||||
|
// transforms and can't remember enough of the trigonometry I
|
||||||
|
// learned 60 years ago. There REALLY should not be any unexplained
|
||||||
|
// numbers.
|
||||||
|
|
||||||
|
module fourbar_leg(length=1000, chord=100, lat_skew=35, long_skew=30) {
|
||||||
h = length * cos(lat_skew) * cos( long_skew);
|
h = length * cos(lat_skew) * cos( long_skew);
|
||||||
w = length * sin( lat_skew);
|
w = length * sin( lat_skew);
|
||||||
d = length * sin( long_skew);
|
d = length * sin( long_skew);
|
||||||
|
pivot_radius = 12;
|
||||||
|
|
||||||
translate([0, 0-w, 0]) {
|
translate([0, 0-w, 0]) {
|
||||||
// upper pivot needs a complex trig transformation!
|
// upper pivot needs a complex trig transformation!
|
||||||
|
@ -23,7 +33,12 @@ module fourbar_leg(length=1000, chord=100, long_skew=30, lat_skew=30) {
|
||||||
translate([0 - chord, 0, (chord/2 * sin(long_skew))])
|
translate([0 - chord, 0, (chord/2 * sin(long_skew))])
|
||||||
rotate([0, 90+long_skew, 0])
|
rotate([0, 90+long_skew, 0])
|
||||||
color("black")
|
color("black")
|
||||||
cylinder(h=chord, r=12);
|
difference() {
|
||||||
|
cylinder(h=chord, r=12);
|
||||||
|
// through hole for pivot axle
|
||||||
|
translate([0, -1, 0])
|
||||||
|
cylinder(h=chord+2, r=pivot_radius/3);
|
||||||
|
}
|
||||||
|
|
||||||
// aerofoil section
|
// aerofoil section
|
||||||
sskew([0, long_skew, 0, 0, 0, 0])
|
sskew([0, long_skew, 0, 0, 0, 0])
|
||||||
|
@ -34,72 +49,55 @@ module fourbar_leg(length=1000, chord=100, long_skew=30, lat_skew=30) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
module lower_knuckle(chord=100, pivot_radius=12) {
|
module fourbar_axle_half( length=1000, chord=100, lat_skew=35, long_skew=30, shoulder=650) {
|
||||||
difference() {
|
|
||||||
cube([chord * 1.5, pivot_radius * 3, chord*.66]);
|
|
||||||
translate([ chord*0.25, -1, pivot_radius * 2])
|
|
||||||
cube([chord, pivot_radius * 4, pivot_radius * 4]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module fourbar_axle_half( length, chord, long_skew) {
|
|
||||||
shoulder=650;
|
|
||||||
lat_skew=30;
|
|
||||||
rise=8;
|
rise=8;
|
||||||
|
|
||||||
// I've got something wrong in computing the half-lower-bar
|
// I've got something wrong in computing the half-lower-bar
|
||||||
// length, and I don't know what.
|
// length, and I don't know what. It scales with lat_skew, but
|
||||||
|
// (unsurprisingly) not liniarly. Fudge of 23 works for lat_skew of 30; 34 works for lat_skew of 35
|
||||||
fudge=0;
|
fudge=0;
|
||||||
|
|
||||||
w = ((length * sin(lat_skew) ) + ( shoulder / 2));
|
w = ((length * cos(lat_skew) ));
|
||||||
l_hlb= w * (1/cos(rise)) + fudge;
|
l_hlb= w * (1/cos(rise)) + fudge;
|
||||||
v_offset=l_hlb * sin(rise);
|
v_offset=(l_hlb * sin(rise)) + 38;
|
||||||
|
|
||||||
echo("long_skew", long_skew);
|
translate([-15, 0, 0 - v_offset])
|
||||||
|
|
||||||
translate([0, 0, 0 - v_offset])
|
|
||||||
rotate([90-rise, 0, 180])
|
rotate([90-rise, 0, 180])
|
||||||
color("black")
|
color("black")
|
||||||
airfoil(h=l_hlb, L=chord);
|
airfoil(h=l_hlb, L=chord);
|
||||||
|
|
||||||
// lower knuckle
|
// lower knuckle
|
||||||
translate([(0 - (chord*1.25)), l_hlb * cos(rise), 30])
|
rotate([0, long_skew, 0])
|
||||||
rotate([0, long_skew, 0])
|
translate([(0 - (chord*1.25)), (l_hlb * cos(rise) + 72), -62])
|
||||||
color("black")
|
lower_bar_end_knuckle(chord, 12, rise, lat_skew);
|
||||||
lower_knuckle(chord, 12);
|
|
||||||
|
|
||||||
// wheel
|
rotate([0, long_skew, 0])
|
||||||
translate([-50, l_hlb + 72, -40])
|
translate([(0 - (chord*1.25)), (l_hlb * cos(rise) + 155), -62])
|
||||||
rotate([270, 0, 0])
|
wheel();
|
||||||
wheel(iso=451);
|
rotate([0, long_skew, 0])
|
||||||
|
translate([(0 - (chord*1.25)), (l_hlb * cos(rise) + 115), -62])
|
||||||
|
rotate([90, 0, 0])
|
||||||
|
color("silver")
|
||||||
|
cylinder( h=1.5, r=75);
|
||||||
|
|
||||||
// brake disk
|
|
||||||
translate([-50, l_hlb + 35, -40])
|
|
||||||
color("silver")
|
|
||||||
rotate([90, 0, 0])
|
|
||||||
cylinder(h=1.5, r=75);
|
|
||||||
// brake caliper
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module fourbar(length=1000, chord=100, long_skew=30, lat_skew=30, shoulder=650) {
|
module fourbar(length=1000, chord=100, lat_skew=30, long_skew=30, shoulder=650) {
|
||||||
w = (length * sin( lat_skew)) + ( shoulder / 2);
|
|
||||||
|
|
||||||
|
|
||||||
translate([0, 0-(shoulder/2), 0])
|
translate([0, 0-(shoulder/2), 0])
|
||||||
fourbar_leg( length, chord, long_skew, lat_skew);
|
fourbar_leg( length, chord, lat_skew, long_skew);
|
||||||
|
|
||||||
translate([0, (shoulder/2), 0])
|
translate([0, (shoulder/2), 0])
|
||||||
mirror([0, 1, 0])
|
mirror([0, 1, 0])
|
||||||
fourbar_leg(length, chord, long_skew, lat_skew);
|
fourbar_leg(length, chord, lat_skew, long_skew);
|
||||||
|
|
||||||
fourbar_axle_half(w, chord, long_skew);
|
fourbar_axle_half(length, chord, lat_skew, long_skew, shoulder);
|
||||||
|
|
||||||
mirror([0, 1, 0])
|
mirror([0, 1, 0])
|
||||||
fourbar_axle_half(w, chord, long_skew);
|
fourbar_axle_half(length, chord, lat_skew, long_skew, shoulder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// lower_knuckle();
|
|
||||||
// fourbar();
|
// fourbar(length=1000, chord=100, long_skew=30, lat_skew=35, shoulder=650);
|
||||||
// fourbar_axle_half(1000,100, 30);
|
// fourbar_axle_half();
|
144
model/lowerknuckle.scad
Normal file
144
model/lowerknuckle.scad
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
// lowerknuckle.scad
|
||||||
|
|
||||||
|
// (c) Simon Brooke 2025; CC-BY-SA
|
||||||
|
|
||||||
|
include <BOSL2/std.scad>
|
||||||
|
include <NACAAirfoils/files/Naca4.scad>
|
||||||
|
include <library/skew.scad>
|
||||||
|
include <wheel.scad>
|
||||||
|
|
||||||
|
$fn=64;
|
||||||
|
|
||||||
|
|
||||||
|
module lower_bar_end_knuckle_old(chord=100, pivot_radius=12, rise=8,lat_skew=30) {
|
||||||
|
l_body=chord * 1.5;
|
||||||
|
w_body=pivot_radius * 2.5;
|
||||||
|
h_axis=pivot_radius * 2.75;
|
||||||
|
|
||||||
|
difference() {
|
||||||
|
union () {
|
||||||
|
translate([l_body/2, w_body/2, h_axis])
|
||||||
|
rotate([0, 90, 0])
|
||||||
|
cyl(h=l_body, r=w_body/2, rounding=5);
|
||||||
|
|
||||||
|
// 'except=TOP' in phrase introduces the spurious hulls
|
||||||
|
translate([l_body/2, w_body/2, h_axis*.75])
|
||||||
|
cuboid([l_body, w_body, h_axis * .75], rounding=5);
|
||||||
|
// bulge for wheel axle; the fork insertion end of
|
||||||
|
// a lefty axle is 25mm diameter
|
||||||
|
translate([chord * 0.25, w_body/2, 0])
|
||||||
|
rotate([90, 0, 0])
|
||||||
|
cyl(h=w_body, r=25, rounding=5);
|
||||||
|
// fairing for this
|
||||||
|
translate([chord * 0.25, w_body/2, -3])
|
||||||
|
rotate([80, 0, 90])
|
||||||
|
prismoid([w_body, 45], [w_body, 10], rounding=5, h=l_body * .75);
|
||||||
|
|
||||||
|
}
|
||||||
|
translate([ chord*0.25, -1, pivot_radius * 3])
|
||||||
|
cube([chord, pivot_radius * 4, pivot_radius * 4]);
|
||||||
|
// scoop for leg-bottom knuckle to rotate within
|
||||||
|
translate([ chord*0.25, w_body/2, h_axis])
|
||||||
|
rotate([0, 90, 0])
|
||||||
|
cylinder(h=chord, r=pivot_radius * 1.3);
|
||||||
|
// through hole for pivot axle
|
||||||
|
translate([-1, w_body/2, h_axis])
|
||||||
|
rotate([0, 90, 0])
|
||||||
|
cylinder(h=l_body+2, r=pivot_radius/3);
|
||||||
|
// through hole for wheel axle
|
||||||
|
translate([ chord * 0.25, w_body +1, 0])
|
||||||
|
rotate([90, 0, 0])
|
||||||
|
cylinder(h=w_body-5, r=12.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// airfoil stub to be epoxied into the lower bar of
|
||||||
|
// the linkage
|
||||||
|
translate([chord*1.25, 1, 30])
|
||||||
|
rotate([90 + rise, 360 - lat_skew, 0])
|
||||||
|
airfoil(h=chord, L=2 - chord);
|
||||||
|
|
||||||
|
// // brake disk
|
||||||
|
// translate([(0 - (chord*1.25)), (l_hlb * cos(rise)), 1])
|
||||||
|
// rotate([90, 0, 0])
|
||||||
|
// color("silver")
|
||||||
|
// cylinder( h=1.5, r=75);
|
||||||
|
// // wheel (obviously)
|
||||||
|
// translate([(0 - (chord*1.25)), (l_hlb * cos(rise)), -10])
|
||||||
|
// wheel();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module lower_bar_end_knuckle(chord=100, pivot_radius=12, rise=8,lat_skew=30, colour="blue") {
|
||||||
|
l_body=chord * 2;
|
||||||
|
w_body=pivot_radius * 2.5;
|
||||||
|
h_axis=pivot_radius * 2.75;
|
||||||
|
|
||||||
|
difference() {
|
||||||
|
union () {
|
||||||
|
// (more streamlined) body
|
||||||
|
translate([160, w_body/2, -22])
|
||||||
|
rotate([0,0,180])
|
||||||
|
scale([1, 2, 1])
|
||||||
|
color( colour)
|
||||||
|
airfoil(h=70, L=l_body);
|
||||||
|
// boss for wheel axle
|
||||||
|
translate([ chord * 0.25, w_body * 0.9, 0])
|
||||||
|
rotate([90, 0, 0])
|
||||||
|
color( colour)
|
||||||
|
cyl(h=w_body * 1.25, r=20, rounding=5);
|
||||||
|
|
||||||
|
}
|
||||||
|
// scoop for leg-bottom knuckle to rotate within
|
||||||
|
translate([ chord*0.25, w_body/2, h_axis])
|
||||||
|
rotate([0, 90, 0])
|
||||||
|
cylinder(h=chord, r=pivot_radius * 1.3);
|
||||||
|
// space for the airfoil leg to emerge
|
||||||
|
translate([ chord*0.25, w_body*.75, pivot_radius * 2.25])
|
||||||
|
rotate([lat_skew + 45, 0, 0])
|
||||||
|
cube([chord, pivot_radius * 4, pivot_radius * 4]);
|
||||||
|
// through hole for pivot axle
|
||||||
|
translate([-1, w_body/2, h_axis])
|
||||||
|
rotate([0, 90, 0])
|
||||||
|
cylinder(h=250, r=pivot_radius/3);
|
||||||
|
// through hole for wheel axle
|
||||||
|
translate([ chord * 0.25, w_body *1.5, 0])
|
||||||
|
rotate([90, 0, 0])
|
||||||
|
cylinder(h=w_body * 1.4, r=12.5);
|
||||||
|
// slice off the front bottom
|
||||||
|
translate([chord * 1.25, w_body/2, 0 - w_body])
|
||||||
|
rotate([270-lat_skew, 0, 90])
|
||||||
|
color( colour)
|
||||||
|
cuboid([2* w_body, 2*w_body, l_body *.75]);
|
||||||
|
// slice off the upper back
|
||||||
|
translate([0, w_body/2, w_body * 2.5])
|
||||||
|
rotate([270-lat_skew, 0, 90])
|
||||||
|
color( colour)
|
||||||
|
cuboid([2* w_body, 2*w_body, l_body *.75]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// airfoil stub to be epoxied into the lower bar of
|
||||||
|
// the linkage
|
||||||
|
translate([chord*1.25, 1, 30])
|
||||||
|
rotate([90 + rise, 360 - lat_skew, 0])
|
||||||
|
color( colour)
|
||||||
|
airfoil(h=chord, L=2 - chord);
|
||||||
|
|
||||||
|
// // brake disk
|
||||||
|
// translate([(0 - (chord*1.25)), (l_hlb * cos(rise)), 1])
|
||||||
|
// rotate([90, 0, 0])
|
||||||
|
// color("silver")
|
||||||
|
// cylinder( h=1.5, r=75);
|
||||||
|
// // wheel (obviously)
|
||||||
|
// translate([(0 - (chord*1.25)), (l_hlb * cos(rise)), -10])
|
||||||
|
// wheel();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//translate([-125, 0, 0])
|
||||||
|
// lower_bar_end_knuckle();
|
||||||
|
//translate([-125, 0, 125])
|
||||||
|
// color("blue")
|
||||||
|
// lower_bar_end_knuckle();
|
||||||
|
//translate([-100, 74, 0])
|
||||||
|
// wheel();
|
||||||
|
|
|
@ -11,7 +11,7 @@ include <epicyclic.scad>
|
||||||
module subframe_cycleparts(rim=451, chainring_teeth=82, crank=140) {
|
module subframe_cycleparts(rim=451, chainring_teeth=82, crank=140) {
|
||||||
// wheel
|
// wheel
|
||||||
translate([0, 382, 93])
|
translate([0, 382, 93])
|
||||||
rotate([0, 90, 0])
|
rotate([0, 0, 90])
|
||||||
wheel(iso=rim);
|
wheel(iso=rim);
|
||||||
|
|
||||||
translate([-42, 382, 93])
|
translate([-42, 382, 93])
|
||||||
|
|
|
@ -11,8 +11,8 @@ include <hull.scad>
|
||||||
rotate([0, 0, 270])
|
rotate([0, 0, 270])
|
||||||
translate([0, 1300, 180])
|
translate([0, 1300, 180])
|
||||||
subframe(structure="carbon");
|
subframe(structure="carbon");
|
||||||
translate([0, 0, 320])
|
translate([0, 0, 250])
|
||||||
fourbar(700, 100, 30, 35, 650);
|
fourbar(length=1000, chord=100, long_skew=30, lat_skew=35, shoulder=650);
|
||||||
|
|
||||||
translate([800, 0, 120])
|
translate([800, 0, 120])
|
||||||
rotate([0, 4, 0])
|
rotate([0, 4, 0])
|
||||||
|
|
|
@ -20,42 +20,43 @@
|
||||||
module wheel (iso=451) {
|
module wheel (iso=451) {
|
||||||
radius=(iso/2)+7;
|
radius=(iso/2)+7;
|
||||||
|
|
||||||
// rim
|
rotate([270, 0, 0]) {
|
||||||
color("grey")
|
// rim
|
||||||
difference() {
|
color("grey")
|
||||||
cylinder(h=22, r=radius, center=true);
|
difference() {
|
||||||
translate([0,0, -11])
|
cylinder(h=22, r=radius, center=true);
|
||||||
cylinder(h=26, r=(radius-10));
|
translate([0,0, -11])
|
||||||
|
cylinder(h=26, r=(radius-10));
|
||||||
|
}
|
||||||
|
|
||||||
|
// carbon cones covering the spokes
|
||||||
|
color("black")
|
||||||
|
translate([0,0, 4])
|
||||||
|
cylinder(h=26.6, r1=radius, r2=22.5);
|
||||||
|
color("black")
|
||||||
|
mirror([0, 0, -1])
|
||||||
|
translate([0,0, 4])
|
||||||
|
cylinder(h=14.4, r1=radius, r2=29);
|
||||||
|
|
||||||
|
// tyre
|
||||||
|
color("black")
|
||||||
|
rotate_extrude(convexity = 10)
|
||||||
|
translate([radius +10, 0, 0])
|
||||||
|
circle(r = 12, $fn = 100);
|
||||||
|
|
||||||
|
// hub
|
||||||
|
color("grey")
|
||||||
|
translate([0, 0, -40])
|
||||||
|
cylinder(h=65, r=22.5);
|
||||||
|
|
||||||
|
// axle
|
||||||
|
color("silver") {
|
||||||
|
translate([0, 0, -45])
|
||||||
|
cylinder(h=70, r1=12.5, r2=7.5);
|
||||||
|
translate([0, 0, -60])
|
||||||
|
cylinder(h=25, r=12.5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// carbon cones covering the spokes
|
|
||||||
color("black")
|
|
||||||
translate([0,0, 4])
|
|
||||||
cylinder(h=26.6, r1=radius, r2=22.5);
|
|
||||||
color("black")
|
|
||||||
mirror([0, 0, -1])
|
|
||||||
translate([0,0, 4])
|
|
||||||
cylinder(h=14.4, r1=radius, r2=29);
|
|
||||||
|
|
||||||
// tyre
|
|
||||||
color("black")
|
|
||||||
rotate_extrude(convexity = 10)
|
|
||||||
translate([radius +10, 0, 0])
|
|
||||||
circle(r = 12, $fn = 100);
|
|
||||||
|
|
||||||
// hub
|
|
||||||
color("grey")
|
|
||||||
translate([0, 0, -40])
|
|
||||||
cylinder(h=65, r=22.5);
|
|
||||||
|
|
||||||
// axle
|
|
||||||
color("silver") {
|
|
||||||
translate([0, 0, -45])
|
|
||||||
cylinder(h=70, r1=12.5, r2=7.5);
|
|
||||||
translate([0, 0, -85])
|
|
||||||
cylinder(h=40, r=12.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// wheel();
|
// wheel();
|
Loading…
Reference in a new issue