/* [General] */

// Minimum angle
$fa = 1; //[0:0.01:5]

// Minimum size
$fs = 0.25; //[0:0.01:5]

// Minimum Thickness of any
min_thickness = 3; //[0:0.1:50]

// Tolerance, e. g. additional clearance to add between faces
tol = 0.05; //[0:0.01:1]

// Kerf
kerf = 0.1;

/* [Base] */

// Total height of the mount
height = 30; // .1

// Diameter of the foot/rod
rod_d = 20; // .1

// Diameter of the mount
mount_d = 45; // .1

// Diameter of the ring intersecting all screw hole's centers
screw_ring_d = 37; // .1

// Number of screws for attachment
n_screws = 5;

// Diameter of a screw thread
screw_thread_d = 4; // .1

// Diameter of a screw head
screw_head_d = 7.7; // .1

// Screw Head Elevation
screw_head_z_offset = 7.5; // .1

// Minimum Thickness of mount surrounding rod
rim_thickness = 5; // .1

// Height at which the diameter reduction starts
reduction_z_offset = 10; // .1

// Diameter of chamfering
chamfer_d = 3; // .1

module foot_mount($fa = $fa, $fs = $fs, height = height, d_inner = rod_d,
                  outer_d = mount_d, rim_thickness = rim_thickness,
                  n_screws = n_screws, screw_thread_d = screw_thread_d,
                  screw_head_d = screw_head_d, screw_ring_d = screw_ring_d,
                  screw_head_elevation = screw_head_z_offset,
                  reduction_z_offset = reduction_z_offset,
                  chamfer_d = chamfer_d) {

  // Assertions
  assert(rod_d + 2 * screw_thread_d < mount_d); // the part ends up as one body
  assert(rod_d < mount_d); // the rod is actually sorrounded by the mount
  assert(screw_head_d >= screw_thread_d); // the screw head must be at least the
                                          // size of the screw thread
  assert(screw_ring_d >=
         rod_d + screw_head_d); // screws must not intersect the rod
  assert(screw_head_d + screw_ring_d <=
         mount_d);                   // screw heads must not exceed mount_d
  assert(chamfer_d <= rim_thickness) // required for the chamfer to be feasible

      difference() {
    rotate_extrude() {
      difference() {
        union() {
          translate([ d_inner / 2 + kerf, 0 ])
              let(width = (outer_d - d_inner) / 2,
                  chamfer_y_offset = height - chamfer_d / 2) {
            square([ width - kerf, height - chamfer_d / 2 ]);
            hull() {
              translate([ chamfer_d / 2, chamfer_y_offset ])
                  circle(d = chamfer_d);
              translate([ rim_thickness - chamfer_d / 2, chamfer_y_offset ])
                  circle(d = chamfer_d);
            }
          }
        }

        let(x_offset = outer_d / 2,
            x_size = outer_d - d_inner - 2 * rim_thickness) {
          translate([ outer_d / 2, reduction_z_offset + x_size / 2 ]) {
            circle(d = x_size);
            translate([ -x_size / 2, 0 ])
                square([ x_size, height - reduction_z_offset ]);
          }
        }
      }
    }

    // screws
    for (angle = [0:360 / n_screws:360]) {
      rotate([ 0, 0, angle ]) translate([ screw_ring_d / 2, 0 ]) {
        cylinder(d = screw_thread_d + 2 * kerf, h = height);
        translate([ 0, 0, screw_head_elevation ])
            cylinder(d = screw_head_d + 2 * kerf, h = height);
      }
    }
  }
}

module copy_mirror(vec = [ 1, 0, 0 ]) {
  children();
  mirror(vec) children();
}

module cylinder_hull(d, distance, h) {
  hull() {
    cylinder(d = d, h = h);
    translate([ distance, 0, 0 ]) cylinder(d = d, h = h);
  }
}

module linkage_clamp($fs = $fs, $fa = $fa, lower_d = 29, upper_d = 30.5,
                     plate_thickness = 20, allowed_height = 5,
                     hole_distance = 150, screw_shim_d = 20,
                     screw_thread_d = screw_thread_d) {
  difference() {
    union() {
      linear_extrude(height = 20, scale = 0.8, convexity = 100)
          translate([ 10, 0 ]) circle(d = 25);

      // lower body
      translate([ 10, 0, -10 ]) cylinder_hull(d = 25, h = 10, distance = 110);
    }

    // screw shim cutout
    translate([ 30, 0, -10 ])
        cylinder_hull(d = screw_shim_d, h = 5, distance = 90);

    // screw cutout
    translate([ 30, 0, -5 ])
        cylinder_hull(d = screw_thread_d, h = 5, distance = 90);
  }
}

linkage_clamp();