
/* [OpenSCAD] */
$fn=60; // [30:6:180]

/* [Profil] */

// Aluprofil (quadratisch)
Raster = 20; // [20,30]
// Gewindebohrung metrisch
Schraube = 5; // [5,6,8]

/* [Verbinder] */
// Winkel der Verbindung
Winkel = 90; // [30:5:180]
// Schritte in der Unterteilung
Steps = 6; // [1:1:60]
// Ende-zu-Ende (an) oder Ende-in-Führungsnut (aus)
End2End = true;
// Fuehrungsnuten "inline" (an) oder "quer" (aus)
F_Inline = true;
// Fuehrungsnuten "T" Fuß in der Nuten
F_TFoot = false;
// Mit Bohrung zum Festschrauben?
Bohrung = false;
// Tiefe der Führung in den Nuten
Nutentiefe = 3; // [2,3,4,5]
// Modell für den Slicer auf die Seite legen
Kippen = true;

/* [Hidden] */
Toleranz = 0.2;
Fuehrung=1.5;

module plate(height=2) {
  delta=Raster/2-1;
  hull() {
    for (i=[0,90,180,270]) {
      rotate([0,0,i]) translate([delta,delta,0]) cylinder(d=2, h=height);
    }
  }
}

module endcap() {
  // Grundplatte
  plate();
  // Führungsnupsis in den Nuten (Halbkreise)
  intersection() {
    for (i=[0,90,180,270]) {
      rotate([0,0,i]) translate([Raster/2,0,-Nutentiefe/2]) cylinder( d=Schraube, h=Nutentiefe, center=true );
    }
    cube(Raster, center=true);
  }
  // Innen-Nippel D=80% von Bohrung < M5 Kernloch, doppelt so lang wie die Führungen außen
  translate([0,0,-Nutentiefe]) cylinder(d=Schraube*4/5, h=2*Nutentiefe, center=true); 
}

module nutenfuehrung() {
  if (F_TFoot==true) {
    // T Fuehrung in Nut mit 2.2mm Wandbreite des Profils.
    translate([(Raster-Schraube)/2,0,-1.1]) union() {
      cube( [Schraube,Schraube-Toleranz,2.2], center=true );
      translate([0,0,-2.2]) cube( [Schraube,Schraube-Toleranz+3,2.2], center=true );
    }
  }
  else {
    translate([(Raster-Schraube)/2,0,-Fuehrung/2]) cube( [Schraube,Schraube-Toleranz,Fuehrung], center=true );
  }
}

module nutencap() {
  plate();
  if (F_Inline==true) {
    for (i=[0,180]) {
      rotate([0,0,i]) nutenfuehrung();
    }
  }
  else {
    for (i=[90,270]) {
      rotate([0,0,i]) nutenfuehrung();
    }
  }
}

module fill_plate() {
  translate([10,0,0]) plate(0.01);
}

module fuellung(angle) {
  delta_angle = Winkel/Steps;
  hull() {
    rotate([0,-angle*delta_angle,0]) fill_plate();
    rotate([0,-(angle-1)*delta_angle,0]) fill_plate();
  }
}

// Auf die Seite legen, dann wird es beim Slicen einfacher
turn90degree=(Kippen==true)?90:0;
rotate([turn90degree,0,0]) 
difference() {
  union() {
    color("red") translate([Raster/2,0,-2]) {
      if (End2End==true) {
        endcap();
      }
      else {
        nutencap();
      }
    }
    color("orange") rotate([0,-Winkel,0]) mirror([0,0,1]) translate([Raster/2,0,-2]) endcap();
    color("green") for ( i = [1:1:Steps] ) fuellung(i);
  }
  if (Bohrung==true && End2End==false && F_TFoot==false) {
    translate([Raster/2,0,0]) {
    mirror([0,0,1]) cylinder(d=Schraube+Toleranz, h=Schraube, center=true);
    translate([0,0,Toleranz]) cylinder(d=11, h=Raster);
    }
  }
}
