// fourbar.scad // (c) Simon Brooke 2025; CC-BY-SA include include include module fourbar_leg(length=1000, chord=100, long_skew=30, lat_skew=30) { h = length * cos(lat_skew) * cos( long_skew); w = length * sin( lat_skew); d = length * sin( long_skew); translate([0, 0-w, 0]) { // upper pivot needs a complex trig transformation! translate([d - (chord/2), w, h + chord]) rotate([0, 90+long_skew, 0]) color("black") cylinder(h=chord, r=12); // lower pivot: translate([0 - chord, 0, (chord/2 * sin(long_skew))]) rotate([0, 90+long_skew, 0]) color("black") cylinder(h=chord, r=12); // aerofoil section skew([0, long_skew, 0, 0, 0, 0]) rotate([lat_skew, 0, 180]) color("black") airfoil(h=length, L=chord); } } module fourbar_axle_half( length, chord) { translate([0, 0, -120]) rotate([82, 0, 180]) color("black") airfoil(h=length, L=chord); // lower knuckle translate([-chord, length, -60]) color("black") cube([chord, chord/4, chord/2]); // wheel translate([0, length + 50, -50]) // Pierre Rouzeau's wheel is beautifully modelled and parameterised, but it doesn't seem to be scaled as I'd expect... wheel(rim=451, spoke_nbr=32); } module fourbar(length=1000, chord=100, long_skew=30, lat_skew=30, shoulder=650) { w = (length * sin( lat_skew)) + ( shoulder / 2); translate([0, 0-(shoulder/2), 0]) fourbar_leg( length, chord, long_skew, lat_skew); translate([0, (shoulder/2), 0]) mirror([0, 1, 0]) fourbar_leg(length, chord, long_skew, lat_skew); fourbar_axle_half(w, chord); mirror([0, 1, 0]) fourbar_axle_half(w, chord); }