|
// Tour Easy rear fender clip |
|
// Ed Nisley KE4ZNU February 2017 |
|
|
|
Layout = "Build"; // Build Profile Tab Clip |
|
|
|
//- Extrusion parameters must match reality! |
|
|
|
ThreadThick = 0.25; |
|
ThreadWidth = 0.40; |
|
|
|
HoleWindage = 0.2; |
|
|
|
Protrusion = 0.1; // make holes end cleanly |
|
|
|
inch = 25.4; |
|
|
|
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit); |
|
|
|
//———————- |
|
// Dimensions |
|
|
|
// special case: fender is exactly half a circle! |
|
|
|
FenderC = 47.0; // fender outside width = chord |
|
FenderM = 18.5; // height of chord |
|
|
|
FenderR = (pow(FenderM,2) + pow(FenderC,2)/4) / (2 * FenderM); // radius |
|
echo(str("Fender radius: ", FenderR)); |
|
FenderD = 2*FenderR; |
|
|
|
FenderA = 2 * asin(FenderC / (2*FenderR)); |
|
echo(str(" … arc: ",FenderA," deg")); |
|
|
|
FenderThick = 2.5; // fender thickness, assume dia of edge |
|
|
|
ClipHeight = 18.0; // top to bottom, ignoring rakish tilt |
|
ClipThick = 3.0; // thickness of clip around fender |
|
ClipD = FenderD; // ID of clip against |
|
ClipSides = 4 * 8; // polygon sides around clip circle |
|
|
|
BendReliefD = 2.5; // bend arch diameter |
|
BendReliefA = 2/3 * FenderA/2; // … angle from dead ahead |
|
BendReliefCut = 1.0; // factor to thin outside of bend |
|
|
|
TabAngle = -20; // angle from perpendicular to fender |
|
TabThick = 2.0; |
|
TabWidth = 15.0; |
|
|
|
ScrewOffset = 15.0; // screw center to fender along perpendicular |
|
ScrewD = 5.0; |
|
|
|
ScrewSlotLength = 2*ScrewD; |
|
|
|
//———————- |
|
// Useful routines |
|
|
|
module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes |
|
|
|
Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2); |
|
|
|
FixDia = Dia / cos(180/Sides); |
|
|
|
cylinder(r=(FixDia + HoleWindage)/2, |
|
h=Height, |
|
$fn=Sides); |
|
} |
|
|
|
//———————- |
|
// Clip profile around fender |
|
// Centered on fender arc |
|
|
|
module Profile(HeightScale = 1) { |
|
|
|
linear_extrude(height=HeightScale*ClipHeight,convexity=5) { |
|
difference() { |
|
offset(r=ClipThick) // outside of clip |
|
union() { |
|
circle(d=ClipD,$fn=ClipSides); |
|
for (i=[-1,1]) |
|
rotate(i*BendReliefA) { |
|
translate([ClipD/2 + BendReliefD/2,0,0]) |
|
circle(d=BendReliefD,$fn=6); |
|
} |
|
} |
|
union() { // inside of clip |
|
circle(d=ClipD,$fn=ClipSides); |
|
for (i=[-1,1]) |
|
rotate(i*BendReliefA) { |
|
translate([ClipD/2 + BendReliefCut*BendReliefD/2,0,0]) |
|
circle(d=BendReliefD/cos(180/6),$fn=6); |
|
translate([ClipD/2,0,0]) |
|
square([BendReliefCut*BendReliefD,BendReliefD],center=true); |
|
} |
|
} |
|
translate([(FenderR – FenderM – FenderD/2),0]) // trim ends |
|
square([FenderD,2*FenderD],center=true); |
|
} |
|
|
|
for (a=[-1,1]) // hooks around fender |
|
rotate(a*(FenderA/2)) |
|
translate([FenderR – FenderThick/2,0]) { |
|
difference() { |
|
rotate(1*180/12) |
|
circle(d=FenderThick + 2*ClipThick,$fn=12); |
|
rotate(1*180/8) |
|
circle(d=FenderThick,$fn=8); |
|
rotate(a * -90) |
|
translate([0,-2*FenderThick,0]) |
|
square(4*FenderThick,center=false); |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
//———————- |
|
// Mounting tab |
|
|
|
module Tab() { |
|
|
|
linear_extrude(height=TabThick,convexity=3) |
|
difference() { |
|
hull() { |
|
circle(d=TabWidth,$fn=ClipSides); |
|
translate([(ScrewSlotLength – ScrewD)/2 + (FenderR + ScrewOffset),0,0]) |
|
circle(d=TabWidth,$fn=ClipSides); |
|
} |
|
circle(d=ClipD,$fn=ClipSides); // remove fender arc |
|
hull() // screw slot |
|
for (i=[-1,1]) |
|
translate([i*(ScrewSlotLength – ScrewD)/2 + (FenderR + ScrewOffset),0,0]) |
|
rotate(180/8) |
|
circle(d=ScrewD/cos(180/8),$fn=8); |
|
} |
|
} |
|
|
|
//———————- |
|
// Combine at mounting angle |
|
|
|
module Clip() { |
|
|
|
difference() { |
|
union() { |
|
translate([-FenderR,0,0]) |
|
Tab(); |
|
rotate([0,TabAngle,0]) |
|
translate([-FenderR,0,0]) |
|
Profile(2); // scale upward for trimming |
|
} |
|
translate([0,0,-ClipHeight]) // trim bottom |
|
cube(2*[FenderD,FenderD,ClipHeight],center=true); |
|
translate([0,0,ClipHeight*cos(TabAngle)+ClipHeight]) // trim top |
|
cube(2*[FenderD,FenderD,ClipHeight],center=true); |
|
} |
|
} |
|
|
|
//———————- |
|
// Build it |
|
|
|
|
|
if (Layout == "Profile") { |
|
Profile(); |
|
} |
|
|
|
if (Layout == "Tab") { |
|
Tab(); |
|
} |
|
|
|
if (Layout == "Clip") { |
|
Clip(); |
|
} |
|
|
|
if (Layout == "Build") { |
|
Clip(); |
|
} |