do away with all that stuff, simple z-axis screw connector

MATERIAL_THICKNESS = 3;

//MOTOR_D = 41.81;
//MOTOR_D = 43;
MOTOR_D = 44.5;
MOTOR_R = MOTOR_D/2;
ZAXIS_OUTER_W = 59;
ZAXIS_W = 63.97;
ZAXIS_DEPTH = 50.63;
ZAXIS_H = 35.38;

BT_OVERHANG_EDGE = 25;
BT_OVERHANG_FRONT = 60;

FINGER_W = 14;
FINGER_H = MATERIAL_THICKNESS;

ZLIMIT_W = 28;
ZLIMIT_H = 16;

z_limit_w  = 20;
z_limit_h = 9.75;
z_limit_d = 6;

//BACK_PLATE_W = ZAXIS_W + 2*ZLIMIT_W + 2*8;
BACK_PLATE_W = ZAXIS_W + 2*8;
BACK_PLATE_H = 35;

zbp_depth = 20;
zbp_height = 12;
z_plate_overhang = 30;
zbp_finger_0 = 6;
zbp_finger_1 = 6;

zbp_support_len = 10;
zbp_side_len = zbp_depth + 4 + z_limit_w;

 module regular_polygon(order, r=1){
 	angles=[ for (i = [0:order-1]) i*(360/order) ];
 	coords=[ for (th=angles) [r*cos(th), r*sin(th)] ];
 	polygon(coords);
}

module z_top_cross_support() {
  w = ZAXIS_OUTER_W;
  oh_w = z_plate_overhang;
  th = MATERIAL_THICKNESS;

  dx = 2*zbp_support_len - th + zbp_finger_0;
  dy = zbp_height;

  /*
  translate([-90,-30])
  union() {
    square([ dx, 2]);
    translate([dx - 2, 0]) square([2, dy]);
    polygon([[0,2], [dx-2,dy], [dx, 2]]);

    color([1,0,0]) translate([dx/2, -th/2]) square([zbp_finger_1, th], center=true);
    color([0,1,0]) translate([dx + th/2, dy/2]) square([th,zbp_finger_1], center=true);
  }
  */

  b = 20;
  s = 20;
  union() {

    // center cross brace
    //
    square([w, s], center=true);

    // side portion
    //
    difference() {
      translate([-w/2 - oh_w/2, -s/2-b/2]) square([b,b], center=true);

      // tab holes
      //
      translate([-w/2 - oh_w/3, -s/2-b + dy/2]) square([th, zbp_finger_1], center=true);
      translate([-w/2 - 2*oh_w/3, -s/2-b + dy/2]) square([th, zbp_finger_1], center=true);
    }

    difference() {
      translate([ w/2 + oh_w/2, -s/2-b/2]) square([b,b], center=true);

      // tab holes
      //
      translate([ w/2 + oh_w/3, -s/2-b + dy/2]) square([th, zbp_finger_1], center=true);
      translate([ w/2 + 2*oh_w/3, -s/2-b + dy/2]) square([th, zbp_finger_1], center=true);
    }

    // tab
    //
    translate([-w/2 - oh_w/2, -s/2-b - th/2]) square([zbp_finger_1, th], center=true);
    translate([ w/2 + oh_w/2, -s/2-b - th/2]) square([zbp_finger_1, th], center=true);

    //triangle connector
    //
    polygon([ [-w/2, s/2], [-w/2 - oh_w/2 - b/2, -s/2], [-w/2 - oh_w/2 + b/2, -s/2], [-w/2, -s/2]]);
    polygon([ [ w/2, s/2], [ w/2 + oh_w/2 + b/2, -s/2], [ w/2 + oh_w/2 - b/2, -s/2], [ w/2, -s/2]]);
  }
}

// debug
//translate([50,-60])z_top_cross_support();

module z_top_plate() {
  th = MATERIAL_THICKNESS;
  w1 = ZAXIS_OUTER_W/2 + th;

  sl = zbp_support_len;
  w = ZAXIS_OUTER_W;
  h0 = 20;
  h1 = 30;

  ox = 10;
  oy = 25;

  oh_w = z_plate_overhang;
  oh_l = 30;

  h2 = 10;

  ohs_w = z_plate_overhang - 3;

  h3 = 40;
  h4 = 20;

  zspacer_nut_r = (36.30 - 24.5)/4;
  zspacer_nut_x = 24.5/2 + zspacer_nut_r;

  dx = 2*zbp_support_len - th + zbp_finger_0;
  dy = zbp_height;
  oh_w = z_plate_overhang;

  overhang_w = ZAXIS_OUTER_W;
  //DEBUG
  /*
  dx = 2*zbp_support_len - th + zbp_finger_0;
  dy = zbp_height;

  translate([-70,   -h0 - oy - oh_l - 2*h2])
  rotate(90, [0,0,1])
  union() {
    square([ dx, 2]);
    translate([dx - 2, 0]) square([2, dy]);
    polygon([[0,2], [dx-2,dy], [dx, 2]]);

    color([1,0,0]) translate([dx/2, -th/2]) square([zbp_finger_1, th], center=true);
    color([0,1,0]) translate([dx + th/2, dy/2]) square([th,zbp_finger_1], center=true);
  }
  */
  //DEBUG

  difference() {

    union() {

      // back
      //
      square([w, h0], center=true);

      // back to be cut out
      //
      translate([0,-h0/2]) square([w, h1], center=true);

      // side connector
      //
      translate([-w/2 - ox, -h0/2 -oy]) polygon([[0,0], [ox,oy],[ox,0]]);
      translate([ w/2, -h0/2]) polygon([[0,0], [ox,-oy],[0,-oy]]);

      // nut connector plate
      //
      translate([-w/2 - oh_w/2, -h0/2 - oy - oh_l/2]) square([oh_w, oh_l], center=true);
      translate([ w/2 + oh_w/2, -h0/2 - oy - oh_l/2]) square([oh_w, oh_l], center=true);

      // brace connector
      //
      translate([-w/2 - oh_w/2 - 3/2, -h0/2 - oy - oh_l - h2/2]) square([oh_l - 3, h2], center=true);
      translate([ w/2 + oh_w/2 + 3/2, -h0/2 - oy - oh_l - h2/2]) square([oh_l - 3, h2], center=true);

      // side connector (still?)
      //
      polygon([ [-w/2, -h0/2], [-(zspacer_nut_x+zspacer_nut_r), -h0/2], [-w/2,-(h0+h1/2)] ]);
      polygon([ [ w/2, -h0/2], [ (zspacer_nut_x+zspacer_nut_r), -h0/2], [ w/2,-(h0+h1/2)] ]);

      // brace support connector
      //
      translate([-w/2 - oh_w/2 - 3/2, -h0/2 - oy - oh_l - h2 - h3/2]) square([oh_l - 3, h3], center=true);
      translate([ w/2 + oh_w/2 + 3/2, -h0/2 - oy - oh_l - h2 - h3/2]) square([oh_l - 3, h3], center=true);

      // front connection
      //
      translate([0,-h0/2 - oy - oh_l - h2 - h3- h4/2]) square([w + oh_w*2,h4], center=true);

    }

    // left hole tabs
    //
    translate([-w/2 - th - 2,-h0-oy-5]) {

      translate([-0, 0]) square([th,zbp_finger_0],center=true);
      translate([-0 - sl - th, zbp_depth/2 - 3]) square([zbp_finger_1, th], center=true);
      translate([-0 - sl - th, -(zbp_depth/2 - 3)]) square([zbp_finger_1, th], center=true);
    }

    // right hole tabs
    //
    translate([ w/2 + th + 2, -h0-oy-5]) {

      translate([(0), 0]) square([th,zbp_finger_0],center=true);
      translate([(0 + sl + th), zbp_depth/2 - 3]) square([zbp_finger_1, th], center=true);
      translate([(0 + sl + th), -(zbp_depth/2 - 3)]) square([zbp_finger_1, th], center=true);

    }

    // cross brace hole tabs
    //
    translate([-w/2 - oh_w/2, -h0/2 - oy - oh_l - h2/2]) square([zbp_finger_1, th], center=true);
    translate([ w/2 + oh_w/2, -h0/2 - oy - oh_l - h2/2]) square([zbp_finger_1, th], center=true);

    // cross brace support hole tabs (left)
    //
    translate([-overhang_w/2 - 2*oh_w/3, -h0/2 - oy - oh_l - h2 - 3 - dy/2])
      square([th, zbp_finger_1], center=true);
    translate([-overhang_w/2 - oh_w/3, -h0/2 - oy - oh_l - h2 - 3 - dy/2])
      square([th, zbp_finger_1], center=true);

    // cross brace support hole tabs (right)
    //
    translate([ overhang_w/2 + 2*oh_w/3, -h0/2 - oy - oh_l - h2 - 3 - dy/2])
      square([th, zbp_finger_1], center=true);
    translate([ overhang_w/2 + oh_w/3, -h0/2 - oy - oh_l - h2 - 3 - dy/2])
      square([th, zbp_finger_1], center=true);

    // circle cutouts
    //
    hull() {
      translate([zspacer_nut_x, -h0]) circle(zspacer_nut_r);
      translate([zspacer_nut_x, -h0-h1-zspacer_nut_r]) circle(zspacer_nut_r);
    }
    hull() {
      translate([-zspacer_nut_x, -h0]) circle(zspacer_nut_r);
      translate([-zspacer_nut_x, -h0-h1-zspacer_nut_r]) circle(zspacer_nut_r);
    }

    hull() {
      translate([0,-h0-3]) circle(9);
      translate([0, -h0-h1-5]) circle(9);

    }

  }

}

module z_top_all() {
  translate([-50,10]) rotate(90, [0,0,1]) z_top_plate();

  translate([0,30]) z_side();
  translate([24,13]) rotate(180, [0,0,1]) z_side();

  translate([-25,-6]) z_support();
  translate([15,-7]) rotate(180, [0,0,1]) z_support();

  translate([8,-3]) rotate(-10, [0,0,1]) z_support();
  translate([47,-9]) rotate(180, [0,0,1]) z_support();

  translate([102,-00]) rotate(90, [0,0,1]) z_support();
  translate([90,-00]) rotate(-90, [0,0,1]) z_support();

  translate([-16,5]) rotate(80, [0,0,1]) z_support();
  translate([64,30]) mirror([1,0,0]) z_support();

  translate([41,20]) z_guide_housing();
  translate([54,20]) z_guide_housing();

  translate([41,8]) z_nut_housing();
  translate([54,8]) z_nut_housing();

  translate([120,5]) rotate(-90, [0,0,1]) z_top_cross_support();

}

//z_side();

//translate([60,50]) z_top_all();
//z_top_plate();

module z_bottom_plate() {
  bottom_plate_width = ZAXIS_OUTER_W + 2*z_plate_overhang;
  th = MATERIAL_THICKNESS;
  w = ZAXIS_OUTER_W/2 + th;
  sl = zbp_support_len;
  difference() {
    square([bottom_plate_width, zbp_depth], center=true);

    translate([w, 0]) square([th,zbp_finger_0],center=true);
    translate([w + sl + th, zbp_depth/2 - 3]) square([zbp_finger_1, th], center=true);
    translate([w + sl + th, -(zbp_depth/2 - 3)]) square([zbp_finger_1, th], center=true);

    translate([-(w), 0]) square([th,zbp_finger_0],center=true);
    translate([-(w + sl + th), zbp_depth/2 - 3]) square([zbp_finger_1, th], center=true);
    translate([-(w + sl + th), -(zbp_depth/2 - 3)]) square([zbp_finger_1, th], center=true);
  }
}

module z_support() {
  th = MATERIAL_THICKNESS;
  dx = 2*zbp_support_len - th + zbp_finger_0;
  dy = zbp_height;
  union() {
    square([ dx, 2]);
    translate([dx - 2, 0]) square([2, dy]);
    polygon([[0,2], [dx-2,dy], [dx, 2]]);

    translate([dx/2, -th/2]) square([zbp_finger_1, th], center=true);
    translate([dx + th/2, dy/2]) square([th,zbp_finger_1], center=true);
  }
}

module z_side_x() {

  qq = zbp_depth/2 - 3;
  th = MATERIAL_THICKNESS;
  m2_ds = (2*(zbp_depth/2 - 3) - th)/2 - 2;
  difference() {

    union() {
      translate([zbp_side_len/2 - zbp_depth/2, 0]) square([zbp_side_len, zbp_height], center=true);
      //translate([0,-zbp_height/2 - th/2]) square([zbp_finger_0, th], center=true);
    };

    //translate([m2_ds, m2_ds]) circle(1, $fn=16);
    //translate([-m2_ds,-m2_ds]) circle(1, $fn=16);

    //translate([qq,0]) square([th, zbp_finger_1], center=true);
    //translate([-qq,0]) square([th, zbp_finger_1], center=true);
    //circle(2.5, $fn=16);

    translate([zbp_depth + th,0]) switch_holes2();
    translate([th*0,0]) switch_holes2();
  }
}

z_side_x();

module z_side() {

  qq = zbp_depth/2 - 3;
  th = MATERIAL_THICKNESS;
  m2_ds = (2*(zbp_depth/2 - 3) - th)/2 - 2;
  difference() {
    union() {
      translate([zbp_side_len/2 - zbp_depth/2, 0]) square([zbp_side_len, zbp_height], center=true);
      translate([0,-zbp_height/2 - th/2]) square([zbp_finger_0, th], center=true);
    };

    translate([m2_ds, m2_ds]) circle(1, $fn=16);
    translate([-m2_ds,-m2_ds]) circle(1, $fn=16);

    translate([qq,0]) square([th, zbp_finger_1], center=true);
    translate([-qq,0]) square([th, zbp_finger_1], center=true);
    circle(2.5, $fn=16);

    translate([zbp_depth + th,0]) switch_holes2();
  }
}

module z_nut_housing() {
  th = MATERIAL_THICKNESS;
  dx = 2*(zbp_depth/2 - 3) - th;
  dy = dx;

  m2_x = dx/2 - 2;
  m2_y = dx/2 - 2;
  difference() {
    square([dx,dy], center=true);
    translate([ m2_x, m2_y]) circle(1, $fn=16);
    translate([-m2_x,-m2_y]) circle(1, $fn=16);

    regular_polygon(6, r=9/2);

  }
}

module z_guide_housing() {
  th = MATERIAL_THICKNESS;
  dx = 2*(zbp_depth/2 - 3) - th;
  dy = dx;

  m2_x = dx/2 - 2;
  m2_y = dx/2 - 2;
  difference() {
    square([dx,dy], center=true);
    translate([-m2_x, m2_y]) circle(1, $fn=16);
    translate([ m2_x,-m2_y]) circle(1, $fn=16);
    circle(2.5, $fn=16);

  }

}

module z_bottom_all() {
  z_bottom_plate();

  translate([57,15]) mirror([1,0,0]) z_support();
  translate([30,30])  z_support();
  translate([-50,15])  z_support();
  translate([-50,30])  z_support();

  translate([-10,21]) z_side();
  translate([70,0]) rotate(90, [0,0,1]) z_side();
  //translate([85,20]) rotate(90, [0,0,1]) z_bottom_side();
  //translate([0,51]) z_bottom_side();

  translate([-10,35]) z_nut_housing();
  translate([5,35]) z_nut_housing();

  translate([20, 35]) z_guide_housing();
  translate([85, 0]) z_guide_housing();
}

//translate([60,10]) z_bottom_all();

module side_holder_bottom() {
  w = 20;
  s = 40;
  t = FINGER_H;

  xx = 10;
  d=5;

  difference() {
    union() {
      square([s,w], center=true);
      translate([ (s/2 - FINGER_H/2) + t, w/3]) square([FINGER_H,w/3], center=true);
      translate([ (s/2 - FINGER_H/2) + t,-w/3]) square([FINGER_H,w/3], center=true);
    };
    translate([-(5*s/12 - d/2),0]) circle(d/2, $fn=16);
    translate([-(1*s/12 - d/2),0]) circle(d/2, $fn=16);
    translate([ (s/2 - FINGER_W), (w/2 - FINGER_H/2)]) square([FINGER_W, FINGER_H], center=true);
    translate([ (s/2 - FINGER_W),-(w/2 - FINGER_H/2)]) square([FINGER_W, FINGER_H], center=true);
    translate([ (s/2 - FINGER_H/2) + t, 0]) square([FINGER_H, w/3], center=true);
  }

}

module side_holder_up() {
  w = 20;
  s = 40;
  d=5;
  t = FINGER_H;
  difference() {
    union() {
      square([s,w], center=true);
      translate([ (s/2 + FINGER_H/2), 0]) square([FINGER_H, w/3], center=true);
    };
    translate([-7*s/24,0]) switch_holes2();
    translate([ (s/2 - FINGER_W), (w/2 - FINGER_H/2)]) square([FINGER_W, FINGER_H], center=true);
    translate([ (s/2 - FINGER_W),-(w/2 - FINGER_H/2)]) square([FINGER_W, FINGER_H], center=true);

  }

}

module side_holder_connect(h=0) {
  s = 3*FINGER_W/2;
  t = MATERIAL_THICKNESS;
  union() {
    polygon([[0,0],[s,s],[s,0]]);
    //polygon([[0,0],[s,s],[s,t], [s-FINGER_W/2,t], [s-FINGER_W/2,0],[s,0]]);
    translate([0,-FINGER_H-h]) square([FINGER_W,FINGER_H]);
    translate([s,FINGER_W/2-h]) square([FINGER_H, FINGER_W]);
  }
}

module top_holder() {
  w = 40;
  s = 20;
  ofx = -0;
  ofy = -10;

  difference() {
    union() {
      //square([30,10]);
      square([w,s]);
      //translate([-10,-20,0]) square([10,20]);
      translate([ofx-s/2,ofy-w/2,0]) square([10,20]);
      //polygon( points=[[0,w/2],[-s/2,0],[0,-s/8],[w/8,0]], paths=[[0,1,2,3,0]]);
      polygon( points=[[0,w/2],[ofx-s/2,ofy],[ofx,ofy-s/8],[w/8,0]], paths=[[0,1,2,3,0]]);
    }
    translate([w/3,s/2]) circle(2.5,$fn=16);
    translate([3*w/4,s/2]) circle(2.5, $fn=16);
    //translate([-4,-12]) rotate(90, [0,0,1]) switch_holes2();
    translate([ofx-4,ofy-12]) rotate(90, [0,0,1]) switch_holes2();
  }
}

module side_plate() {
  cable_slot_w = 4.75;
  cable_slot_h = 2;

  ofst = 50;

  w = ZAXIS_W - ofst;
  h = ZAXIS_H + 3*cable_slot_h;

  difference() {
    // main body
    //
    //square([ZAXIS_W, ZAXIS_H], center=true);
    union() {
      //square([ZAXIS_W, ZAXIS_H], center=true);
      square([ZAXIS_W, h], center=true);
      //translate([ZAXIS_W/2 + ZAXIS_W/4,0]) square([ZAXIS_W/2, ZAXIS_H], center=true);
      translate([ZAXIS_W/2 + ZAXIS_W/4,0]) square([ZAXIS_W, h], center=true);
    }

    translate([ZAXIS_W/2 + 6,h/2]) square([ZAXIS_W, 4*cable_slot_h], center=true);
    translate([ZAXIS_W/2 + 6,-h/2]) square([ZAXIS_W, 4*cable_slot_h], center=true);

    // platform slots
    //
    translate([-(FINGER_W-ofst), ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);
    translate([-(FINGER_W-ofst),-ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);
    translate([ (FINGER_W+ofst), ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);
    translate([ (FINGER_W+ofst),-ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);

    // cable tile slots
    //
    /*
    translate([-(ZAXIS_W/2 - 2*cable_slot_h), (ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([-(ZAXIS_W/2 - 2*cable_slot_h),-(ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h), (ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h),-(ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0, (ZAXIS_H/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0,-(ZAXIS_H/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);
    */
    translate([-(ZAXIS_W/2 - 2*cable_slot_h), (h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([-(ZAXIS_W/2 - 2*cable_slot_h),-(h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h), (h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h),-(h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0, (h/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0,-(h/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);

    // center access
    //
    square([ZAXIS_W/2, 4], center=true);
    circle(cable_slot_h*3, $fn=16);

    translate([ofst,0]) square([ZAXIS_W/2, 4], center=true);
    translate([ofst,0]) circle(cable_slot_h*3, $fn=16);

    // center cable tie
    //
    translate([-(ZAXIS_W/2 - 1.5*cable_slot_h), 0]) square([3*cable_slot_h, cable_slot_w], center=true);
    translate([ (ZAXIS_W/2 - 1.5*cable_slot_h), 0]) square([3*cable_slot_h, cable_slot_w], center=true);
  }
}

module side_plate_bottom() {
  cable_slot_w = 4.75;
  cable_slot_h = 2;

  //ofst = 33;
  ofst = 28;

  w = ZAXIS_W - ofst;
  h = ZAXIS_H + 3*cable_slot_h;

  difference() {
    // main body
    //
    //square([ZAXIS_W, ZAXIS_H], center=true);
    union() {
      //square([ZAXIS_W, ZAXIS_H], center=true);
      square([ZAXIS_W, h], center=true);
      //translate([ZAXIS_W/2 + ZAXIS_W/4,0]) square([ZAXIS_W/2, ZAXIS_H], center=true);
      translate([ZAXIS_W/2 + ZAXIS_W/4,0]) square([ZAXIS_W, h], center=true);
    }

    translate([ZAXIS_W/2 + 6,h/2]) square([ZAXIS_W, 4*cable_slot_h], center=true);
    translate([ZAXIS_W/2 + 6,-h/2]) square([ZAXIS_W, 4*cable_slot_h], center=true);

    translate([-ZAXIS_W/4 + 2, h/2]) square([ZAXIS_W/4, 4*cable_slot_h], center=true);
    translate([-ZAXIS_W/4 + 2, -h/2]) square([ZAXIS_W/4, 4*cable_slot_h], center=true);

    // platform slots
    //
    translate([-(FINGER_W-ofst), ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);
    translate([-(FINGER_W-ofst),-ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);
    translate([ (FINGER_W+ofst), ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);
    translate([ (FINGER_W+ofst),-ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);

    // cable tile slots
    //
    /*
    translate([-(ZAXIS_W/2 - 2*cable_slot_h), (ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([-(ZAXIS_W/2 - 2*cable_slot_h),-(ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h), (ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h),-(ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0, (ZAXIS_H/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0,-(ZAXIS_H/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);
    */
    translate([-(ZAXIS_W/2 - 2*cable_slot_h), (h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([-(ZAXIS_W/2 - 2*cable_slot_h),-(h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h), (h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h),-(h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0, (h/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0,-(h/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);

    // center access
    //
    translate([ofst,0]) square([ZAXIS_W/2, 4], center=true);
    translate([ofst,0]) circle(cable_slot_h*3, $fn=16);

    //translate([ofst,0]) square([ZAXIS_W/2, 4], center=true);
    //translate([ofst,0]) circle(cable_slot_h*3, $fn=16);

    // center cable tie
    //
    translate([-(ZAXIS_W/2 - 1.5*cable_slot_h), 0]) square([3*cable_slot_h, cable_slot_w], center=true);
    translate([ (ZAXIS_W/2 - 1.5*cable_slot_h), 0]) square([3*cable_slot_h, cable_slot_w], center=true);
  }
}

// 15 , 5
module platform() {
  platform_w = ZAXIS_W-18;
  platform_h = ZAXIS_H;
  difference() {

    //main body
    //
    square([platform_w, platform_h], center=true);

    translate([-platform_w/2,0]) circle(2.5);
    translate([ platform_w/2,0]) circle(2.5);

    //support slots
    //
    translate([-FINGER_W, platform_h/4]) square([FINGER_W, FINGER_H], center=true);
    translate([-FINGER_W,-platform_h/4]) square([FINGER_W, FINGER_H], center=true);
    translate([ FINGER_W, platform_h/4]) square([FINGER_W, FINGER_H], center=true);
    translate([ FINGER_W,-platform_h/4]) square([FINGER_W, FINGER_H], center=true);

    // limit switch holes
    //
    //translate([-5, (platform_h/2 - ZLIMIT_H/2)]) mirror([1,0,0]) switch_holes();
    //translate([-5,-(platform_h/2 - ZLIMIT_H/2)])switch_holes();

    translate([ 0, (platform_h/2 - ZLIMIT_H/2)])
      mirror([1,0,0]) switch_holes();
    translate([ 0,-(platform_h/2 - ZLIMIT_H/2)])
      switch_holes();

    translate([-(platform_w/2 - ZLIMIT_W/2), (platform_h/2 - ZLIMIT_H/2)])
      mirror([1,0,0]) switch_holes();
    translate([-(platform_w/2 - ZLIMIT_W/2),-(platform_h/2 - ZLIMIT_H/2)])
      switch_holes();
    translate([ (platform_w/2 - ZLIMIT_W/2),-(platform_h/2 - ZLIMIT_H/2)])
      switch_holes();
    translate([ (platform_w/2 - ZLIMIT_W/2), (platform_h/2 - ZLIMIT_H/2)])
      mirror([1,0,0]) switch_holes();
  }
}

module platform_support(support_base_h=2) {
  //a=90/4;
  a=90/2;
  support_base_w = 3*FINGER_W;
  //support_base_h = 10;
  //support_base_h = 2;
  C0=30;
  C1=15;

  xh = sin(a) * support_base_w;
  difference() {
    union() {

      // bottom half with fingers
      //
      square([support_base_w, support_base_h], center=true);
      translate([-FINGER_W, -(support_base_h/2 + FINGER_H/2)]) square([FINGER_W, FINGER_H], center=true);
      translate([ FINGER_W, -(support_base_h/2 + FINGER_H/2)]) square([FINGER_W, FINGER_H], center=true);

      // triangular upper half
      //
      translate([-support_base_w/2, support_base_h/2])
      intersection() {
        rotate(a, [0,0,1]) mirror([0,1,0]) square([2*support_base_w, C0*support_base_h]);
        //color([1,0,0]) square([support_base_w, C1*support_base_h]);
        square([support_base_w, xh]);
      };

      // fingers for triangular upper half
      //
      translate([-(support_base_w/2), support_base_h/2])
        rotate(a, [0,0,1])
        square([FINGER_W, FINGER_H]);

      translate([-3*FINGER_W/2,support_base_h/2])
        rotate(a, [0,0,1])
        translate([2*FINGER_W,0])
        square([FINGER_W, FINGER_H]);
    }

    translate([0,-support_base_h/2]) circle(FINGER_W/3);
  }
}

module switch_holes() {
  diam = 3.2;
  w = ZLIMIT_W;
  h = ZLIMIT_H;
  topl_offset = 1.45;
  topu_offset = 1.53;

  rightr_offset = 1.45;
  rightb_offset = 1.3;

  translate([-w/2+topl_offset+diam/2, h/2 - topu_offset - diam/2]) circle(diam/2, $fn=16);
  translate([ w/2-rightr_offset-diam/2, -h/2 + rightb_offset + diam/2]) circle(diam/2, $fn=16);
}

module switch_holes2() {
  // w=20, h=10
  // top hole to top = 5.78
  // bot hole to bot = 1.78
  // side hole to side = 4
  // inside hole to inside hole = 7
  // hole diam = 2.5
  diam = 2.5;
  w = 20;
  h = 10;
  x_from_cent = 7/2+diam/2;
  y_from_cent = 5.75-(h/2)+diam/2;

  translate([x_from_cent,y_from_cent]) circle(diam/2, $fn=16);
  translate([-x_from_cent, y_from_cent]) circle(diam/2, $fn=16);

}

module switch_spacer2() {
  // w=20, h=10
  // top hole to top = 5.78
  // bot hole to bot = 1.78
  // side hole to side = 4
  // inside hole to inside hole = 7
  // hole diam = 2.5
  diam = 2.5;
  w = 20;
  h = 10;
  x_from_cent = 7/2+diam/2;
  y_from_cent = 5.75-(h/2)+diam/2;

  difference() {
    square([w,h], center=true);
    translate([x_from_cent,y_from_cent]) circle(diam/2, $fn=16);
    translate([-x_from_cent, y_from_cent]) circle(diam/2, $fn=16);
  }

}

module all() {
  side_plate();
  translate([0,40]) side_plate();

  //translate([65,0]) platform();
  //translate([65,40]) platform();

  translate([245,0]) platform();
  translate([245,40]) platform();

  translate([-8,65]) platform_support();
  translate([40,65]) platform_support();

  translate([87,65]) platform_support();

  translate([100,2]) rotate(-90, [0,0,1])  platform_support();

  translate([135,10]) rotate(45,[0,0,1]) top_holder();
  translate([175,30]) rotate(-135, [0,0,1]) top_holder();

  translate([162,70]) rotate(90, [0,0,1]) switch_spacer2();
  translate([165,90]) switch_spacer2();

  translate([131,68]) side_holder_bottom();
  translate([190,0]) rotate(45, [0,0,1]) side_holder_bottom();

  translate([130,90]) side_holder_up();
  translate([195,50]) rotate(90,[0,0,1]) side_holder_up();

  translate([98,50]) rotate(-90, [0,0,1]) side_holder_connect();
  translate([115,35]) rotate(90, [0,0,1]) side_holder_connect();
  translate([145,53]) rotate(180, [0,0,1]) side_holder_connect();
  translate([193,80]) rotate(180,[0,0,1]) side_holder_connect();
}

module platforms() {
  dx= 120;
  dy = 45;
  side_plate();
  translate([0,dy]) side_plate_bottom();

  translate([0.95*dx,0]) platform();
  translate([0.95*dx,dy]) platform();

  translate([-8,1.8*dy]) platform_support(10);
  translate([0.95*dy,1.6*dy]) platform_support(10);

  translate([dx,1.6*dy]) platform_support();
  translate([2*dy,2.2*dy]) rotate(-180, [0,0,1])  platform_support();

  //translate([1.3*dx,70]) switch_spacer2();
  //translate([1.3*dx,50]) switch_spacer2();

}

module platform_side_bottom_only() {
  dx= 120;
  dy = 30;
  translate([0,0]) side_plate_bottom();

  translate([-7,dy]) platform_support(10);
  translate([48,dy]) platform_support(10);

}

module all() {

  dx= 120;
  dy = 30;
  translate([0,0]) side_plate_bottom();

  translate([-7,dy]) platform_support(10);
  translate([48,dy]) platform_support(10);

  translate([dx,0]) side_plate();
  translate([dx,dy]) platform_support();
  translate([dx + 50,dy]) platform_support();

  translate([0,4*dy]) rotate(45,[0,0,1]) top_holder();
  translate([45,4*dy]) rotate(-135, [0,0,1]) top_holder();

  translate([162,170]) rotate(90, [0,0,1]) switch_spacer2();
  translate([165,190]) switch_spacer2();

  translate([101,108]) side_holder_bottom();
  translate([150,100]) rotate(45, [0,0,1]) side_holder_bottom();

  translate([130,190]) side_holder_up();
  translate([195,150]) rotate(90,[0,0,1]) side_holder_up();

  translate([98,150]) rotate(-90, [0,0,1]) side_holder_connect();
  translate([115,135]) rotate(90, [0,0,1]) side_holder_connect();
  translate([145,153]) rotate(180, [0,0,1]) side_holder_connect();
  translate([193,180]) rotate(180,[0,0,1]) side_holder_connect();

}

//translate([60,40]) all();
//translate([60,40]) platforms();
//translate([36,25]) platform_side_bottom_only();

//all();

MATERIAL_THICKNESS = 3;

//MOTOR_D = 41.81;
//MOTOR_D = 43;
MOTOR_D = 44.5;
MOTOR_R = MOTOR_D/2;
ZAXIS_OUTER_W = 59;
ZAXIS_W = 63.97;
ZAXIS_DEPTH = 50.63;
ZAXIS_H = 35.38;

BT_OVERHANG_EDGE = 25;
BT_OVERHANG_FRONT = 60;

FINGER_W = 14;
FINGER_H = MATERIAL_THICKNESS;

ZLIMIT_W = 28;
ZLIMIT_H = 16;

z_limit_w  = 20;
z_limit_h = 9.75;
z_limit_d = 6;

//BACK_PLATE_W = ZAXIS_W + 2*ZLIMIT_W + 2*8;
BACK_PLATE_W = ZAXIS_W + 2*8;
BACK_PLATE_H = 35;

zbp_depth = 20;
zbp_height = 12;
z_plate_overhang = 30;
zbp_finger_0 = 6;
zbp_finger_1 = 6;

zbp_support_len = 10;
zbp_side_len = zbp_depth + 4 + z_limit_w;

 module regular_polygon(order, r=1){
 	angles=[ for (i = [0:order-1]) i*(360/order) ];
 	coords=[ for (th=angles) [r*cos(th), r*sin(th)] ];
 	polygon(coords);
}

module z_top_cross_support() {
  w = ZAXIS_OUTER_W;
  oh_w = z_plate_overhang;
  th = MATERIAL_THICKNESS;

  dx = 2*zbp_support_len - th + zbp_finger_0;
  dy = zbp_height;

  /*
  translate([-90,-30])
  union() {
    square([ dx, 2]);
    translate([dx - 2, 0]) square([2, dy]);
    polygon([[0,2], [dx-2,dy], [dx, 2]]);

    color([1,0,0]) translate([dx/2, -th/2]) square([zbp_finger_1, th], center=true);
    color([0,1,0]) translate([dx + th/2, dy/2]) square([th,zbp_finger_1], center=true);
  }
  */

  b = 20;
  s = 20;
  union() {

    // center cross brace
    //
    square([w, s], center=true);

    // side portion
    //
    difference() {
      translate([-w/2 - oh_w/2, -s/2-b/2]) square([b,b], center=true);

      // tab holes
      //
      translate([-w/2 - oh_w/3, -s/2-b + dy/2]) square([th, zbp_finger_1], center=true);
      translate([-w/2 - 2*oh_w/3, -s/2-b + dy/2]) square([th, zbp_finger_1], center=true);
    }

    difference() {
      translate([ w/2 + oh_w/2, -s/2-b/2]) square([b,b], center=true);

      // tab holes
      //
      translate([ w/2 + oh_w/3, -s/2-b + dy/2]) square([th, zbp_finger_1], center=true);
      translate([ w/2 + 2*oh_w/3, -s/2-b + dy/2]) square([th, zbp_finger_1], center=true);
    }

    // tab
    //
    translate([-w/2 - oh_w/2, -s/2-b - th/2]) square([zbp_finger_1, th], center=true);
    translate([ w/2 + oh_w/2, -s/2-b - th/2]) square([zbp_finger_1, th], center=true);

    //triangle connector
    //
    polygon([ [-w/2, s/2], [-w/2 - oh_w/2 - b/2, -s/2], [-w/2 - oh_w/2 + b/2, -s/2], [-w/2, -s/2]]);
    polygon([ [ w/2, s/2], [ w/2 + oh_w/2 + b/2, -s/2], [ w/2 + oh_w/2 - b/2, -s/2], [ w/2, -s/2]]);
  }
}

// debug
//translate([50,-60])z_top_cross_support();

module z_top_plate() {
  th = MATERIAL_THICKNESS;
  w1 = ZAXIS_OUTER_W/2 + th;

  sl = zbp_support_len;
  w = ZAXIS_OUTER_W;
  h0 = 20;
  h1 = 30;

  ox = 10;
  oy = 25;

  oh_w = z_plate_overhang;
  oh_l = 30;

  h2 = 10;

  ohs_w = z_plate_overhang - 3;

  h3 = 40;
  h4 = 20;

  zspacer_nut_r = (36.30 - 24.5)/4;
  zspacer_nut_x = 24.5/2 + zspacer_nut_r;

  dx = 2*zbp_support_len - th + zbp_finger_0;
  dy = zbp_height;
  oh_w = z_plate_overhang;

  overhang_w = ZAXIS_OUTER_W;
  //DEBUG
  /*
  dx = 2*zbp_support_len - th + zbp_finger_0;
  dy = zbp_height;

  translate([-70,   -h0 - oy - oh_l - 2*h2])
  rotate(90, [0,0,1])
  union() {
    square([ dx, 2]);
    translate([dx - 2, 0]) square([2, dy]);
    polygon([[0,2], [dx-2,dy], [dx, 2]]);

    color([1,0,0]) translate([dx/2, -th/2]) square([zbp_finger_1, th], center=true);
    color([0,1,0]) translate([dx + th/2, dy/2]) square([th,zbp_finger_1], center=true);
  }
  */
  //DEBUG

  difference() {

    union() {

      // back
      //
      square([w, h0], center=true);

      // back to be cut out
      //
      translate([0,-h0/2]) square([w, h1], center=true);

      // side connector
      //
      translate([-w/2 - ox, -h0/2 -oy]) polygon([[0,0], [ox,oy],[ox,0]]);
      translate([ w/2, -h0/2]) polygon([[0,0], [ox,-oy],[0,-oy]]);

      // nut connector plate
      //
      translate([-w/2 - oh_w/2, -h0/2 - oy - oh_l/2]) square([oh_w, oh_l], center=true);
      translate([ w/2 + oh_w/2, -h0/2 - oy - oh_l/2]) square([oh_w, oh_l], center=true);

      // brace connector
      //
      translate([-w/2 - oh_w/2 - 3/2, -h0/2 - oy - oh_l - h2/2]) square([oh_l - 3, h2], center=true);
      translate([ w/2 + oh_w/2 + 3/2, -h0/2 - oy - oh_l - h2/2]) square([oh_l - 3, h2], center=true);

      // side connector (still?)
      //
      polygon([ [-w/2, -h0/2], [-(zspacer_nut_x+zspacer_nut_r), -h0/2], [-w/2,-(h0+h1/2)] ]);
      polygon([ [ w/2, -h0/2], [ (zspacer_nut_x+zspacer_nut_r), -h0/2], [ w/2,-(h0+h1/2)] ]);

      // brace support connector
      //
      translate([-w/2 - oh_w/2 - 3/2, -h0/2 - oy - oh_l - h2 - h3/2]) square([oh_l - 3, h3], center=true);
      translate([ w/2 + oh_w/2 + 3/2, -h0/2 - oy - oh_l - h2 - h3/2]) square([oh_l - 3, h3], center=true);

      // front connection
      //
      translate([0,-h0/2 - oy - oh_l - h2 - h3- h4/2]) square([w + oh_w*2,h4], center=true);

    }

    // left hole tabs
    //
    translate([-w/2 - th - 2,-h0-oy-5]) {

      translate([-0, 0]) square([th,zbp_finger_0],center=true);
      translate([-0 - sl - th, zbp_depth/2 - 3]) square([zbp_finger_1, th], center=true);
      translate([-0 - sl - th, -(zbp_depth/2 - 3)]) square([zbp_finger_1, th], center=true);
    }

    // right hole tabs
    //
    translate([ w/2 + th + 2, -h0-oy-5]) {

      translate([(0), 0]) square([th,zbp_finger_0],center=true);
      translate([(0 + sl + th), zbp_depth/2 - 3]) square([zbp_finger_1, th], center=true);
      translate([(0 + sl + th), -(zbp_depth/2 - 3)]) square([zbp_finger_1, th], center=true);

    }

    // cross brace hole tabs
    //
    translate([-w/2 - oh_w/2, -h0/2 - oy - oh_l - h2/2]) square([zbp_finger_1, th], center=true);
    translate([ w/2 + oh_w/2, -h0/2 - oy - oh_l - h2/2]) square([zbp_finger_1, th], center=true);

    // cross brace support hole tabs (left)
    //
    translate([-overhang_w/2 - 2*oh_w/3, -h0/2 - oy - oh_l - h2 - 3 - dy/2])
      square([th, zbp_finger_1], center=true);
    translate([-overhang_w/2 - oh_w/3, -h0/2 - oy - oh_l - h2 - 3 - dy/2])
      square([th, zbp_finger_1], center=true);

    // cross brace support hole tabs (right)
    //
    translate([ overhang_w/2 + 2*oh_w/3, -h0/2 - oy - oh_l - h2 - 3 - dy/2])
      square([th, zbp_finger_1], center=true);
    translate([ overhang_w/2 + oh_w/3, -h0/2 - oy - oh_l - h2 - 3 - dy/2])
      square([th, zbp_finger_1], center=true);

    // circle cutouts
    //
    hull() {
      translate([zspacer_nut_x, -h0]) circle(zspacer_nut_r);
      translate([zspacer_nut_x, -h0-h1-zspacer_nut_r]) circle(zspacer_nut_r);
    }
    hull() {
      translate([-zspacer_nut_x, -h0]) circle(zspacer_nut_r);
      translate([-zspacer_nut_x, -h0-h1-zspacer_nut_r]) circle(zspacer_nut_r);
    }

    hull() {
      translate([0,-h0-3]) circle(9);
      translate([0, -h0-h1-5]) circle(9);

    }

  }

}

module z_top_all() {
  translate([-50,10]) rotate(90, [0,0,1]) z_top_plate();

  translate([0,30]) z_side();
  translate([24,13]) rotate(180, [0,0,1]) z_side();

  translate([-25,-6]) z_support();
  translate([15,-7]) rotate(180, [0,0,1]) z_support();

  translate([8,-3]) rotate(-10, [0,0,1]) z_support();
  translate([47,-9]) rotate(180, [0,0,1]) z_support();

  translate([102,-00]) rotate(90, [0,0,1]) z_support();
  translate([90,-00]) rotate(-90, [0,0,1]) z_support();

  translate([-16,5]) rotate(80, [0,0,1]) z_support();
  translate([64,30]) mirror([1,0,0]) z_support();

  translate([41,20]) z_guide_housing();
  translate([54,20]) z_guide_housing();

  translate([41,8]) z_nut_housing();
  translate([54,8]) z_nut_housing();

  translate([120,5]) rotate(-90, [0,0,1]) z_top_cross_support();

}

translate([60,50]) z_top_all();
//z_top_plate();

module z_bottom_plate() {
  bottom_plate_width = ZAXIS_OUTER_W + 2*z_plate_overhang;
  th = MATERIAL_THICKNESS;
  w = ZAXIS_OUTER_W/2 + th;
  sl = zbp_support_len;
  difference() {
    square([bottom_plate_width, zbp_depth], center=true);

    translate([w, 0]) square([th,zbp_finger_0],center=true);
    translate([w + sl + th, zbp_depth/2 - 3]) square([zbp_finger_1, th], center=true);
    translate([w + sl + th, -(zbp_depth/2 - 3)]) square([zbp_finger_1, th], center=true);

    translate([-(w), 0]) square([th,zbp_finger_0],center=true);
    translate([-(w + sl + th), zbp_depth/2 - 3]) square([zbp_finger_1, th], center=true);
    translate([-(w + sl + th), -(zbp_depth/2 - 3)]) square([zbp_finger_1, th], center=true);
  }
}

module z_support() {
  th = MATERIAL_THICKNESS;
  dx = 2*zbp_support_len - th + zbp_finger_0;
  dy = zbp_height;
  union() {
    square([ dx, 2]);
    translate([dx - 2, 0]) square([2, dy]);
    polygon([[0,2], [dx-2,dy], [dx, 2]]);

    translate([dx/2, -th/2]) square([zbp_finger_1, th], center=true);
    translate([dx + th/2, dy/2]) square([th,zbp_finger_1], center=true);
  }
}

module z_side() {

  qq = zbp_depth/2 - 3;
  th = MATERIAL_THICKNESS;
  m2_ds = (2*(zbp_depth/2 - 3) - th)/2 - 2;
  difference() {
    union() {
      translate([zbp_side_len/2 - zbp_depth/2, 0]) square([zbp_side_len, zbp_height], center=true);
      translate([0,-zbp_height/2 - th/2]) square([zbp_finger_0, th], center=true);
    };

    translate([m2_ds, m2_ds]) circle(1, $fn=16);
    translate([-m2_ds,-m2_ds]) circle(1, $fn=16);

    translate([qq,0]) square([th, zbp_finger_1], center=true);
    translate([-qq,0]) square([th, zbp_finger_1], center=true);
    circle(2.5, $fn=16);

    translate([zbp_depth + th,0]) switch_holes2();
  }
}

module z_nut_housing() {
  th = MATERIAL_THICKNESS;
  dx = 2*(zbp_depth/2 - 3) - th;
  dy = dx;

  m2_x = dx/2 - 2;
  m2_y = dx/2 - 2;
  difference() {
    square([dx,dy], center=true);
    translate([ m2_x, m2_y]) circle(1, $fn=16);
    translate([-m2_x,-m2_y]) circle(1, $fn=16);

    regular_polygon(6, r=9/2);

  }
}

module z_guide_housing() {
  th = MATERIAL_THICKNESS;
  dx = 2*(zbp_depth/2 - 3) - th;
  dy = dx;

  m2_x = dx/2 - 2;
  m2_y = dx/2 - 2;
  difference() {
    square([dx,dy], center=true);
    translate([-m2_x, m2_y]) circle(1, $fn=16);
    translate([ m2_x,-m2_y]) circle(1, $fn=16);
    circle(2.5, $fn=16);

  }

}

module z_bottom_all() {
  z_bottom_plate();

  translate([57,15]) mirror([1,0,0]) z_support();
  translate([30,30])  z_support();
  translate([-50,15])  z_support();
  translate([-50,30])  z_support();

  translate([-10,21]) z_side();
  translate([70,0]) rotate(90, [0,0,1]) z_side();
  //translate([85,20]) rotate(90, [0,0,1]) z_bottom_side();
  //translate([0,51]) z_bottom_side();

  translate([-10,35]) z_nut_housing();
  translate([5,35]) z_nut_housing();

  translate([20, 35]) z_guide_housing();
  translate([85, 0]) z_guide_housing();
}

//translate([60,10]) z_bottom_all();

module side_holder_bottom() {
  w = 20;
  s = 40;
  t = FINGER_H;

  xx = 10;
  d=5;

  difference() {
    union() {
      square([s,w], center=true);
      translate([ (s/2 - FINGER_H/2) + t, w/3]) square([FINGER_H,w/3], center=true);
      translate([ (s/2 - FINGER_H/2) + t,-w/3]) square([FINGER_H,w/3], center=true);
    };
    translate([-(5*s/12 - d/2),0]) circle(d/2, $fn=16);
    translate([-(1*s/12 - d/2),0]) circle(d/2, $fn=16);
    translate([ (s/2 - FINGER_W), (w/2 - FINGER_H/2)]) square([FINGER_W, FINGER_H], center=true);
    translate([ (s/2 - FINGER_W),-(w/2 - FINGER_H/2)]) square([FINGER_W, FINGER_H], center=true);
    translate([ (s/2 - FINGER_H/2) + t, 0]) square([FINGER_H, w/3], center=true);
  }

}

module side_holder_up() {
  w = 20;
  s = 40;
  d=5;
  t = FINGER_H;
  difference() {
    union() {
      square([s,w], center=true);
      translate([ (s/2 + FINGER_H/2), 0]) square([FINGER_H, w/3], center=true);
    };
    translate([-7*s/24,0]) switch_holes2();
    translate([ (s/2 - FINGER_W), (w/2 - FINGER_H/2)]) square([FINGER_W, FINGER_H], center=true);
    translate([ (s/2 - FINGER_W),-(w/2 - FINGER_H/2)]) square([FINGER_W, FINGER_H], center=true);

  }

}

module side_holder_connect(h=0) {
  s = 3*FINGER_W/2;
  t = MATERIAL_THICKNESS;
  union() {
    polygon([[0,0],[s,s],[s,0]]);
    //polygon([[0,0],[s,s],[s,t], [s-FINGER_W/2,t], [s-FINGER_W/2,0],[s,0]]);
    translate([0,-FINGER_H-h]) square([FINGER_W,FINGER_H]);
    translate([s,FINGER_W/2-h]) square([FINGER_H, FINGER_W]);
  }
}

module top_holder() {
  w = 40;
  s = 20;
  ofx = -0;
  ofy = -10;

  difference() {
    union() {
      //square([30,10]);
      square([w,s]);
      //translate([-10,-20,0]) square([10,20]);
      translate([ofx-s/2,ofy-w/2,0]) square([10,20]);
      //polygon( points=[[0,w/2],[-s/2,0],[0,-s/8],[w/8,0]], paths=[[0,1,2,3,0]]);
      polygon( points=[[0,w/2],[ofx-s/2,ofy],[ofx,ofy-s/8],[w/8,0]], paths=[[0,1,2,3,0]]);
    }
    translate([w/3,s/2]) circle(2.5,$fn=16);
    translate([3*w/4,s/2]) circle(2.5, $fn=16);
    //translate([-4,-12]) rotate(90, [0,0,1]) switch_holes2();
    translate([ofx-4,ofy-12]) rotate(90, [0,0,1]) switch_holes2();
  }
}

module side_plate() {
  cable_slot_w = 4.75;
  cable_slot_h = 2;

  ofst = 50;

  w = ZAXIS_W - ofst;
  h = ZAXIS_H + 3*cable_slot_h;

  difference() {
    // main body
    //
    //square([ZAXIS_W, ZAXIS_H], center=true);
    union() {
      //square([ZAXIS_W, ZAXIS_H], center=true);
      square([ZAXIS_W, h], center=true);
      //translate([ZAXIS_W/2 + ZAXIS_W/4,0]) square([ZAXIS_W/2, ZAXIS_H], center=true);
      translate([ZAXIS_W/2 + ZAXIS_W/4,0]) square([ZAXIS_W, h], center=true);
    }

    translate([ZAXIS_W/2 + 6,h/2]) square([ZAXIS_W, 4*cable_slot_h], center=true);
    translate([ZAXIS_W/2 + 6,-h/2]) square([ZAXIS_W, 4*cable_slot_h], center=true);

    // platform slots
    //
    translate([-(FINGER_W-ofst), ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);
    translate([-(FINGER_W-ofst),-ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);
    translate([ (FINGER_W+ofst), ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);
    translate([ (FINGER_W+ofst),-ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);

    // cable tile slots
    //
    /*
    translate([-(ZAXIS_W/2 - 2*cable_slot_h), (ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([-(ZAXIS_W/2 - 2*cable_slot_h),-(ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h), (ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h),-(ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0, (ZAXIS_H/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0,-(ZAXIS_H/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);
    */
    translate([-(ZAXIS_W/2 - 2*cable_slot_h), (h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([-(ZAXIS_W/2 - 2*cable_slot_h),-(h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h), (h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h),-(h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0, (h/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0,-(h/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);

    // center access
    //
    square([ZAXIS_W/2, 4], center=true);
    circle(cable_slot_h*3, $fn=16);

    translate([ofst,0]) square([ZAXIS_W/2, 4], center=true);
    translate([ofst,0]) circle(cable_slot_h*3, $fn=16);

    // center cable tie
    //
    translate([-(ZAXIS_W/2 - 1.5*cable_slot_h), 0]) square([3*cable_slot_h, cable_slot_w], center=true);
    translate([ (ZAXIS_W/2 - 1.5*cable_slot_h), 0]) square([3*cable_slot_h, cable_slot_w], center=true);
  }
}

module side_plate_bottom() {
  cable_slot_w = 4.75;
  cable_slot_h = 2;

  //ofst = 33;
  ofst = 28;

  w = ZAXIS_W - ofst;
  h = ZAXIS_H + 3*cable_slot_h;

  difference() {
    // main body
    //
    //square([ZAXIS_W, ZAXIS_H], center=true);
    union() {
      //square([ZAXIS_W, ZAXIS_H], center=true);
      square([ZAXIS_W, h], center=true);
      //translate([ZAXIS_W/2 + ZAXIS_W/4,0]) square([ZAXIS_W/2, ZAXIS_H], center=true);
      translate([ZAXIS_W/2 + ZAXIS_W/4,0]) square([ZAXIS_W, h], center=true);
    }

    translate([ZAXIS_W/2 + 6,h/2]) square([ZAXIS_W, 4*cable_slot_h], center=true);
    translate([ZAXIS_W/2 + 6,-h/2]) square([ZAXIS_W, 4*cable_slot_h], center=true);

    translate([-ZAXIS_W/4 + 2, h/2]) square([ZAXIS_W/4, 4*cable_slot_h], center=true);
    translate([-ZAXIS_W/4 + 2, -h/2]) square([ZAXIS_W/4, 4*cable_slot_h], center=true);

    // platform slots
    //
    translate([-(FINGER_W-ofst), ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);
    translate([-(FINGER_W-ofst),-ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);
    translate([ (FINGER_W+ofst), ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);
    translate([ (FINGER_W+ofst),-ZAXIS_H/4]) square( [FINGER_W, FINGER_H], center=true);

    // cable tile slots
    //
    /*
    translate([-(ZAXIS_W/2 - 2*cable_slot_h), (ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([-(ZAXIS_W/2 - 2*cable_slot_h),-(ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h), (ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h),-(ZAXIS_H/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0, (ZAXIS_H/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0,-(ZAXIS_H/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);
    */
    translate([-(ZAXIS_W/2 - 2*cable_slot_h), (h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([-(ZAXIS_W/2 - 2*cable_slot_h),-(h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h), (h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ (ZAXIS_W/2 - 2*cable_slot_h),-(h/2 - 1.5*cable_slot_h)])
      square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0, (h/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);
    translate([ 0,-(h/2 - 1.5*cable_slot_h)]) square([cable_slot_w, cable_slot_h], center=true);

    // center access
    //
    translate([ofst,0]) square([ZAXIS_W/2, 4], center=true);
    translate([ofst,0]) circle(cable_slot_h*3, $fn=16);

    //translate([ofst,0]) square([ZAXIS_W/2, 4], center=true);
    //translate([ofst,0]) circle(cable_slot_h*3, $fn=16);

    // center cable tie
    //
    translate([-(ZAXIS_W/2 - 1.5*cable_slot_h), 0]) square([3*cable_slot_h, cable_slot_w], center=true);
    translate([ (ZAXIS_W/2 - 1.5*cable_slot_h), 0]) square([3*cable_slot_h, cable_slot_w], center=true);
  }
}

// 15 , 5
module platform() {
  platform_w = ZAXIS_W-18;
  platform_h = ZAXIS_H;
  difference() {

    //main body
    //
    square([platform_w, platform_h], center=true);

    translate([-platform_w/2,0]) circle(2.5);
    translate([ platform_w/2,0]) circle(2.5);

    //support slots
    //
    translate([-FINGER_W, platform_h/4]) square([FINGER_W, FINGER_H], center=true);
    translate([-FINGER_W,-platform_h/4]) square([FINGER_W, FINGER_H], center=true);
    translate([ FINGER_W, platform_h/4]) square([FINGER_W, FINGER_H], center=true);
    translate([ FINGER_W,-platform_h/4]) square([FINGER_W, FINGER_H], center=true);

    // limit switch holes
    //
    //translate([-5, (platform_h/2 - ZLIMIT_H/2)]) mirror([1,0,0]) switch_holes();
    //translate([-5,-(platform_h/2 - ZLIMIT_H/2)])switch_holes();

    translate([ 0, (platform_h/2 - ZLIMIT_H/2)])
      mirror([1,0,0]) switch_holes();
    translate([ 0,-(platform_h/2 - ZLIMIT_H/2)])
      switch_holes();

    translate([-(platform_w/2 - ZLIMIT_W/2), (platform_h/2 - ZLIMIT_H/2)])
      mirror([1,0,0]) switch_holes();
    translate([-(platform_w/2 - ZLIMIT_W/2),-(platform_h/2 - ZLIMIT_H/2)])
      switch_holes();
    translate([ (platform_w/2 - ZLIMIT_W/2),-(platform_h/2 - ZLIMIT_H/2)])
      switch_holes();
    translate([ (platform_w/2 - ZLIMIT_W/2), (platform_h/2 - ZLIMIT_H/2)])
      mirror([1,0,0]) switch_holes();
  }
}

module platform_support(support_base_h=2) {
  //a=90/4;
  a=90/2;
  support_base_w = 3*FINGER_W;
  //support_base_h = 10;
  //support_base_h = 2;
  C0=30;
  C1=15;

  xh = sin(a) * support_base_w;
  difference() {
    union() {

      // bottom half with fingers
      //
      square([support_base_w, support_base_h], center=true);
      translate([-FINGER_W, -(support_base_h/2 + FINGER_H/2)]) square([FINGER_W, FINGER_H], center=true);
      translate([ FINGER_W, -(support_base_h/2 + FINGER_H/2)]) square([FINGER_W, FINGER_H], center=true);

      // triangular upper half
      //
      translate([-support_base_w/2, support_base_h/2])
      intersection() {
        rotate(a, [0,0,1]) mirror([0,1,0]) square([2*support_base_w, C0*support_base_h]);
        //color([1,0,0]) square([support_base_w, C1*support_base_h]);
        square([support_base_w, xh]);
      };

      // fingers for triangular upper half
      //
      translate([-(support_base_w/2), support_base_h/2])
        rotate(a, [0,0,1])
        square([FINGER_W, FINGER_H]);

      translate([-3*FINGER_W/2,support_base_h/2])
        rotate(a, [0,0,1])
        translate([2*FINGER_W,0])
        square([FINGER_W, FINGER_H]);
    }

    translate([0,-support_base_h/2]) circle(FINGER_W/3);
  }
}

module switch_holes() {
  diam = 3.2;
  w = ZLIMIT_W;
  h = ZLIMIT_H;
  topl_offset = 1.45;
  topu_offset = 1.53;

  rightr_offset = 1.45;
  rightb_offset = 1.3;

  translate([-w/2+topl_offset+diam/2, h/2 - topu_offset - diam/2]) circle(diam/2, $fn=16);
  translate([ w/2-rightr_offset-diam/2, -h/2 + rightb_offset + diam/2]) circle(diam/2, $fn=16);
}

module switch_holes2() {
  // w=20, h=10
  // top hole to top = 5.78
  // bot hole to bot = 1.78
  // side hole to side = 4
  // inside hole to inside hole = 7
  // hole diam = 2.5
  diam = 2.5;
  w = 20;
  h = 10;
  x_from_cent = 7/2+diam/2;
  y_from_cent = 5.75-(h/2)+diam/2;

  translate([x_from_cent,y_from_cent]) circle(diam/2, $fn=16);
  translate([-x_from_cent, y_from_cent]) circle(diam/2, $fn=16);

}

module switch_spacer2() {
  // w=20, h=10
  // top hole to top = 5.78
  // bot hole to bot = 1.78
  // side hole to side = 4
  // inside hole to inside hole = 7
  // hole diam = 2.5
  diam = 2.5;
  w = 20;
  h = 10;
  x_from_cent = 7/2+diam/2;
  y_from_cent = 5.75-(h/2)+diam/2;

  difference() {
    square([w,h], center=true);
    translate([x_from_cent,y_from_cent]) circle(diam/2, $fn=16);
    translate([-x_from_cent, y_from_cent]) circle(diam/2, $fn=16);
  }

}

module all() {
  side_plate();
  translate([0,40]) side_plate();

  //translate([65,0]) platform();
  //translate([65,40]) platform();

  translate([245,0]) platform();
  translate([245,40]) platform();

  translate([-8,65]) platform_support();
  translate([40,65]) platform_support();

  translate([87,65]) platform_support();

  translate([100,2]) rotate(-90, [0,0,1])  platform_support();

  translate([135,10]) rotate(45,[0,0,1]) top_holder();
  translate([175,30]) rotate(-135, [0,0,1]) top_holder();

  translate([162,70]) rotate(90, [0,0,1]) switch_spacer2();
  translate([165,90]) switch_spacer2();

  translate([131,68]) side_holder_bottom();
  translate([190,0]) rotate(45, [0,0,1]) side_holder_bottom();

  translate([130,90]) side_holder_up();
  translate([195,50]) rotate(90,[0,0,1]) side_holder_up();

  translate([98,50]) rotate(-90, [0,0,1]) side_holder_connect();
  translate([115,35]) rotate(90, [0,0,1]) side_holder_connect();
  translate([145,53]) rotate(180, [0,0,1]) side_holder_connect();
  translate([193,80]) rotate(180,[0,0,1]) side_holder_connect();
}

module platforms() {
  dx= 120;
  dy = 45;
  side_plate();
  translate([0,dy]) side_plate_bottom();

  translate([0.95*dx,0]) platform();
  translate([0.95*dx,dy]) platform();

  translate([-8,1.8*dy]) platform_support(10);
  translate([0.95*dy,1.6*dy]) platform_support(10);

  translate([dx,1.6*dy]) platform_support();
  translate([2*dy,2.2*dy]) rotate(-180, [0,0,1])  platform_support();

  //translate([1.3*dx,70]) switch_spacer2();
  //translate([1.3*dx,50]) switch_spacer2();

}

module platform_side_bottom_only() {
  dx= 120;
  dy = 30;
  translate([0,0]) side_plate_bottom();

  translate([-7,dy]) platform_support(10);
  translate([48,dy]) platform_support(10);

}

module all() {

  dx= 120;
  dy = 30;
  translate([0,0]) side_plate_bottom();

  translate([-7,dy]) platform_support(10);
  translate([48,dy]) platform_support(10);

  translate([dx,0]) side_plate();
  translate([dx,dy]) platform_support();
  translate([dx + 50,dy]) platform_support();

  translate([0,4*dy]) rotate(45,[0,0,1]) top_holder();
  translate([45,4*dy]) rotate(-135, [0,0,1]) top_holder();

  translate([162,170]) rotate(90, [0,0,1]) switch_spacer2();
  translate([165,190]) switch_spacer2();

  translate([101,108]) side_holder_bottom();
  translate([150,100]) rotate(45, [0,0,1]) side_holder_bottom();

  translate([130,190]) side_holder_up();
  translate([195,150]) rotate(90,[0,0,1]) side_holder_up();

  translate([98,150]) rotate(-90, [0,0,1]) side_holder_connect();
  translate([115,135]) rotate(90, [0,0,1]) side_holder_connect();
  translate([145,153]) rotate(180, [0,0,1]) side_holder_connect();
  translate([193,180]) rotate(180,[0,0,1]) side_holder_connect();

}

//translate([60,40]) all();
//translate([60,40]) platforms();
//translate([36,25]) platform_side_bottom_only();

//all();


re-design for wider knee (F) joint

re-design for wider knee (F) joint

// try to draw Jansen linkage leg assembly as it might appear in steel

// these are for configuration "E" as referenced in other drawings
AC=17.5;
Ay =  3.318; Bx = 53.833;
BD = 48.020; BE = 46.977; BH = 40.359;
CD = 59.635; CH = 71.441; DE = 66.437;
EF = 47.467; FG = 75.792;
FH = 40.843; GH = 55.790;

DEleft = (DE*DE + BD*BD - BE*BE)/(2*DE);
FGleft = (FG*FG + FH*FH - GH*GH)/(2*FG);
DEperp = sqrt(BD*BD - DEleft*DEleft);
FGperp = sqrt(FH*FH - FGleft*FGleft);

echo(str("DEleft=",DEleft,"   DEperp=",DEperp));
echo(str("FGleft=",FGleft,"   FGperp=",FGperp));

r38 = (3/8)*2.54/2;  // radius of 3/8" bolt

a=360*$t;
legAssembly(a,0);
mirror([1,0,0]) legAssembly(180-a,1.2);
//legAssembly(100);

%translate([0,-93,0]) cube([200,2,2],center=true);

// -----------------------------------------------------------------

// plot a link shadow, a different way, to check kinematic correctness
module checkLink(xa,ya,xb,yb,ab) {
  *translate([(xa+xb)/2,(ya+yb)/2,-9])
    rotate([0,0,atan2(yb-ya,xb-xa)]) cube([ab,1,1],center=true);
}

function triK1(ax,ay,ca,bx,by,cb) = (cb*cb - ca*ca + ax*ax -bx*bx +ay*ay -by*by)/(2*(ax-bx));

// ===================================================================

module legAssembly(ang=0,linkOffset=0) {

// solve kinematics for given crank angle
xC = AC*cos(ang);
yC = AC*sin(ang)+Ay;
echo("C",xC,yC);

k1=(yC*yC - Bx*Bx + BD*BD - CD*CD + xC*xC)/(2*yC);
k2=(xC+Bx)/yC;
c=k1*k1-BD*BD+Bx*Bx;
b=2*(Bx-k1*k2);
a=k2*k2+1;
sgnD=(yC<0)?1:-1;
xD=(-b+sgnD*sqrt(b*b-4*a*c))/(2*a);
yD=sqrt(BD*BD - pow(xD+Bx,2));
echo("D",xD,yD,"CD err",sqrt(pow(xC-xD,2)+pow(yC-yD,2))-CD);

hipRot = atan2(yD,Bx+xD)-atan2(DEperp,DEleft);
echo("hipRot",hipRot);
xE = cos(hipRot) * (DEleft-DE) - sin(hipRot) * DEperp - Bx;
yE = sin(hipRot) * (DEleft-DE) + cos(hipRot) * DEperp;
/*
ke1=(yD*yD + xD*xD + DE*DE + BE*BE)/(2*yD);
ke2=(xD+Bx)/yD;
ae=2+ke2*ke2;
be=2*(Bx-ke1*ke2);
ce=ke1*ke1 - BE*BE +Bx*Bx;
echo("E abc:",ae,be,ce);
xE=(-be+sqrt(be*be-4*ae*ce))/(2*ae);
yE=sqrt(BE*BE - pow(xE+Bx,2));
*/
echo("E",xE,yE);

// this initial soln. seems wrong.
//xH=(BH*BH + xC*xC - CH*CH - Bx*Bx)/(2*(xC+Bx));
//yH=-sqrt(CH*CH - xC*xC + 2*xC*xH - xH*xH);
k1h=(xC*xC + yC*yC + BH*BH - CH*CH - Bx*Bx)/(2*yC);
k2h=-(xC+Bx)/yC;
ah=k2h*k2h+1;
bh=2*(k1h*k2h + Bx);
ch=k1h*k1h + Bx*Bx - BH*BH;
sgnH=(yC>0)?1:-1;
xH=(-bh+sgnH*sqrt(bh*bh-4*ah*ch))/(2*ah);
yH=-sqrt(BH*BH - pow(xH+Bx,2));
bhRot=atan2(yH,xH+Bx);
echo("H",xH,yH,"rot",bhRot,"CH err",sqrt(pow(xH-xC,2)+pow(yH-yC,2))-CH);

/*
k1f=(FH*FH - EF*EF - yE*yE - yH*yH + xE*xE - xH*xH) / (2*(yE-yH));
k2f=(xH-xE)/(yE-yH);
af=k2f*k2f+1;
bf=2*(k1f*k2f - xH - k2f*yH);
cf=xH*xH + yH*yH - 2*k1f*yH + k1f*k1f - FH*FH;
xF=(-bf-sqrt(bf*bf - 4*af*cf))/(2*af);
yF=k1f+k2f*xF;
*/
k2f = (yE-yH)/(xE-xH);
k1f = triK1(xE,yE,EF,xH,yH,FH);
af=k2f*k2f+1;
bf=2*(k2f*xE - k1f*k2f -yE);
cf=k1f*k1f - 2*k1f*xE + xE*xE + yE*yE - EF*EF;
yF=(-bf-sqrt(bf*bf - 4*af*cf))/(2*af);
xF=k1f-k2f*yF;
echo("F",xF,yF,"EF err",sqrt(pow(xF-xE,2)+pow(yF-yE,2))-EF);
echo("FH err",sqrt(pow(xF-xH,2)+pow(yF-yH,2))-FH);

//  -------------------------- crank-arm circle reference
%translate([0,Ay,0]) difference() {
  cylinder(r=AC,h=1,$fn=48,center=true);
  cylinder(r=2,h=2,center=true);
}

// draw the hip so that the main "plane", the ED centerline plane, is at z=0
translate([-Bx,0,0]) rotate([0,0,hipRot])
    translate([DEleft-DE,DEperp,0]) hip();
//translate([-Bx,0,2.5]) rotate([0,0,12.5]) translate([-DEleft,DEperp,0]) hip();
//translate([ Bx,0,0]) rotate([0,0,-20]) translate([DE-DEleft,DEperp,0]) mirror([1,0,0])
//  hip();
checkLink(-Bx,0,xD,yD,BD);
checkLink(-Bx,0,xE,yE,BE);
checkLink(xD,yD,xE,yE,DE);

translate([-Bx,0,0]) rotate([0,0,bhRot])
   BHlinks();
checkLink(-Bx,0,xH,yH,BH);

//translate([xC,yC,2]) rotate([0,0,142])
//   CDlink();
//translate([0,0,linkOffset-.5]) CDlink(xC,yC,xD,yD);
translate([xC,yC,linkOffset-.5]) rotate([0,0,atan2(yD-yC,xD-xC)])
  mirror([0,0,(linkOffset>0)?1:0]) crankLink(CD);
checkLink(xC,yC,xD,yD,CD);

//translate([0,0,linkOffset+1.8]) CDlink(xC,yC,xH,yH);
translate([xC,yC,linkOffset+1.8]) rotate([0,0,atan2(yH-yC,xH-xC)])
  mirror([0,0,(linkOffset>0)?1:0]) crankLink(CH);
checkLink(xC,yC,xH,yH,CH);

//%EFlink1(xE,yE,xF,yF);
translate([xF,yF,0]) rotate([0,0,atan2(yE-yF,xE-xF)]) EFlink();
checkLink(xE,yE,xF,yF,EF);

footRot = atan2(yH-yF,xH-xF)-atan2(FGperp,FGleft);
translate([xF,yF,0]) rotate([0,0,footRot])
   foot();
checkLink(xF,yF,xH,yH,FH);

} // end module legAssembly()

// -----------------------------------------------------------------

module foot() difference() {
  union() {
    hull() {  // FG
      translate([4,0,0]) cube([4,2.6,2.6],center=true);
      translate([FG-1.3,0,0]) cylinder(r=1.3,h=2.6,$fn=24,center=true);
    }

    // knee braces/fork
    for (z=[-1.05,4.45]) rotate([0,0,(z>0)?25:0]) hull() {
      // This was elongated as a brace for knee
      //translate([-5,2,1.5*z])scale([3,5,1])cylinder(r=1,h=.4,$fn=64,center=true);
      // wider knee shouldn't need brace
      translate([0,0,1.5*z]) cylinder(r=2.5,h=.4,$fn=24,center=true);
      translate([9,0,1.5*z])cylinder(r=1,h=.4,center=true);
    }

    // hinge holders at H
    for (z=[-.2,5.1]) translate([FGleft,FGperp,z]) rotate([0,0,0]) {
       translate([0,-6.5,0]) cube([2.6,6,2.6],center=true);
       color([.3,.3,.4,.6])
          translate([0,-1.5,0]) cube([2.4,6,2.4],center=true);
    }

    translate([FGleft,FGperp-6,2.5]) cube([8,2.6,2.6],center=true);

/*
    // hinge holders at H on GH segment
    *for (z=[-.2,5.1]) translate([FGleft,FGperp,z]) rotate([0,0,52]) {
       translate([0,-6.5,0]) cube([2.6,6,2.6],center=true);
       color([.3,.3,.4,.6]) translate([0,-1.5,0]) cube([2.4,6,2.4],center=true);
    }

    // H side of FH link blocks.  No hinge attachment at this time
    *for (z=[0,-5]) translate([FGleft,FGperp,3.5]) rotate([0,0,-130])
        translate([3,-2.54/2,z]) cube([6,2.6,2.6]);

    translate([FGleft,FGperp-4,2.5]) cube([15,2.6,2.6],center=true);
    color([.3,.3,.4,.4]) {
      translate([FGleft,FGperp-.5, 0 ]) cube([3.5,5,2.2],center=true);
      translate([FGleft,FGperp-.5,4.8]) cube([3.5,5,2.2],center=true);
    }
*/

    // vertical brace extension at knee
    translate([3.5,0,3.9]) cube([2.6,2.6,5.1],center=true);
    hull() {  // gusset
      translate([ 4,-1,1]) cylinder(r=.3,h=5.4,$fn=12);
      translate([18, 1,0]) cylinder(r=.3,h=1  ,$fn=12);
    }

    // FH segment bracing
    for (z=[-.3,5.8]) hull() {
      translate([3,1,z])             sphere(.8);
      translate([FGleft-1,FGperp-5,z]) sphere(.8);
    }
    hull() {  // diga brace.  Could be gusset?
      translate([3,1,5.7]) sphere(.8);
      translate([13,10.5,-.3]) sphere(.8);
    }

    // GH braces
    hull() {
      translate([FG-8,0,-.3]) sphere(.8);
      translate([FGleft+1,FGperp-5,-.3]) sphere(.8);
    }
    hull() {
      translate([FG-10,0,0]) sphere(.8);
      translate([FGleft+1,FGperp-5,5.8]) sphere(.8);
    }

    hull() {    // perp brace
      translate([FGleft,FGperp-9,5.7]) sphere(.8);
      translate([FGleft,0,0]) sphere(.8);
    }
    hull() {    // perp brace
      translate([FGleft,FGperp-9,-.3]) sphere(.8);
      translate([FGleft,0,-.3]) sphere(.8);
    }

    // extra truss braces
    hull() {
      translate([48,13,2]) sphere(.8);
      translate([35, 0,0]) sphere(.8);
    }
    *hull() {
      translate([5,1,5.8]) sphere(.8);
      translate([40,0,.8]) sphere(.8);
    }
  }

  cylinder(r=.3,h=20,center=true);
  cube([4.4,3,2],center=true);
  translate([FGleft,FGperp,0]) cylinder(r=.7,h=33,center=true);
}
$fn=12;

module hip() difference() {
  /*  old style, with forks ground from square tube :
  difference() {
    translate([DE/2,0,0]) cube([DE+3,2.6,2.6],center=true);
    cylinder(r=.5,h=6,center=true);
    cube([7,3,2],center=true);

    translate([DE,0,0]) {
      cylinder(r=.25,h=8,center=true);
      cube([5,3,2],center=true);
    }
  }
  */
  union() {
    translate([DE/2,0,0]) cube([DE-5,2.5,2.5],center=true); // top tube
    translate([DE-DEleft,-DEperp,-1.2]) cylinder(r=1.4,h=7.2,$fn=36); // axle

    // top tube fork plates
    translate([DE,0,0]) mirror([1,0,0]) eFork();
                                        eFork();

    hull() {  // diag tubes
      translate([DE-DEleft,-DEperp,0]) sphere(.8);
      translate([8,0,0]) sphere(.8);
    }
    hull() {
      translate([DE-DEleft,-DEperp,0]) sphere(.8);
      translate([DE-8,0,0]) sphere(.8);
    }

    // extra bracing
    translate([DE/2,-20,0]) rotate([0,90,0]) cylinder(r=.8,h=20,center=true);
    translate([DE-DEleft,-DEperp,4]) rotate([-105,0,0]) cylinder(r=.8,h=14);
  }

  // pivot holes
  for (x=[0,DE]) translate([x,0,0]) cylinder(r=r38,h=11,center=true);
}

module eFork() for(z=[-1,1]) hull() {
  translate([0,0,1.4*z]) cylinder(r=2,h=.3,$fn=24,center=true);
  translate([6,0,1.4*z]) cube([1,2,.3],center=true);
}

module crankLink(dx=CD) {
  cylinder(r=1.4,h=.7,$fn=24,center=true);
  color([0.3,0.3,0.4,0.9]) translate([dx-1,0,.6]) difference() {
    cube([5,2.7,2.2],center=true);
    #translate([1,0,0]) cylinder(r=.64,h=11,center=true);
  }
  translate([dx/2-1,0,0]) cube([dx-3,1.3,1.3],center=true);
}

module CDlink(cx=0,cy=0,dx=CD,dy=0) {
echo("CD",cx,cy,dx,dy);
  translate([dx,dy,0]) cylinder(r=1.4,h=.7,$fn=24,center=true);
  translate([cx,cy,0]) cylinder(r=1.4,h=.7,$fn=24,center=true);
  hull() {
    translate([dx,dy,0]) cylinder(r=.65,h=1.3,$fn=24,center=true);
    translate([cx,cy,0]) cylinder(r=.65,h=1.3,$fn=24,center=true);
  }
}

module EFlink() difference() {
  union() {
    color([.4,.4,.5,.9]) {
      //translate([   1.5,0,0]) cube([6,3,2.5],center=true);
      translate([EF-1.5,0,0]) cube([6,3,2.5],center=true);
    }
    translate([EF/2-1.5,0,0]) cube([EF-2,2.6,2.6],center=true);

    translate([0,0,2*2.54/2]) cylinder(r=1.5,h=2.54*3,$fn=48,center=true);

    hull() {
      translate([0,0,2*2.54/2]) cylinder(r=.2,h=2.54*3,$fn=12,center=true);
      translate([9,1,   0    ]) cylinder(r=.2,h=1,$fn=12);
    }
  }

  translate([EF,0,0]) cylinder(r=r38,h=5,center=true);
                    //cylinder(r=r38,h=55,center=true);
  cylinder(r=1.2,h=22,$fn=36,center=true);
}

module EFlink2() difference() {
  union() {
    color([.4,.4,.5,.9]) {
      translate([   1.5,0,0]) cube([6,3,2.5],center=true);
      translate([EF-1.5,0,0]) cube([6,3,2.5],center=true);
    }
    translate([EF/2,0,0]) cube([EF-4,2.6,2.6],center=true);
  }

  translate([EF,0,0]) cylinder(r=r38,h=3,center=true);
                      cylinder(r=r38,h=5,center=true);
}

module EFlink1(ex=0,ey=0,fx=EF,fy=0) {
echo("EF",ex,ey,fx,fy);
  difference() {
     union() {
       color([.3,.3,.4,.9]) {
         translate([ex,ey,0]) cube([4,3,2],center=true);
         translate([fx,fy,0]) cube([4,3,2],center=true);
       }
       hull() {
         translate([ex,ey,0]) cylinder(r=1.3,h=2.6,center=true);
         translate([fx,fy,0]) cylinder(r=1.3,h=2.6,center=true);
       }
     }

     translate([ex,ey,0]) cylinder(r=.7,h=3,center=true);
     translate([fx,fy,0]) cylinder(r=.7,h=3,center=true);
  }
}

// this link drawn with B axle at origin, always.
module BHlinks() {
  difference() {
    translate([0,0,2.4]) cylinder(r=1.4,h=13.5,$fn=36,center=true);
    translate([0,0,2.4]) cube([4,4,7.9],center=true);
  }

  for(z=[-2.4,7.2]) {
     hull() {
       translate([BH-3,0,z]) sphere(.8);
       translate([   0,0,z]) sphere(.8);
     }
  }

  hull() {
    translate([   4,0.5,-2.4]) sphere(.8);
    translate([BH-5,1, 6  ]) sphere(.8);
  }
  hull() {
    translate([   4,-.5, 7]) sphere(.8);
    translate([BH-5, -1, -2  ]) sphere(.8);
  }

  for(z=[-1.7,6.2]) translate([BH,0,z]) difference() {
     hull() {
       cylinder(r=3,h=.33,$fn=36);
       translate([-8,0,0]) cylinder(r=1,h=.33);
     }
     cylinder(r=.7,h=2,center=true);
  }

}
module BHlinks1() {
  translate([0,0, 6.8])                 BHlink();
  translate([0,0,-2  ]) mirror([0,0,1]) BHlink();
}
module BHlink() {
  cylinder(r=1.4,h=6,$fn=24);

  //%translate([BH/2-1,0,1.3]) cube([BH-2,2.5,2.5],center=true);
  for (q=[-1,1]) hull() {
    translate([  0 ,1.5*q,1]) sphere(0.8);
    translate([BH-3,1  *q,1]) sphere(0.8);
  }
  hull() {
    translate([  0 ,0,5]) sphere(0.8);
    translate([BH-3,0,1]) sphere(0.8);
  }

  translate([BH,0,-.3]) difference() {
     hull() {
       cylinder(r=3,h=.33,$fn=36);
       translate([-8,0,0]) cylinder(r=1,h=.33);
     }
     cylinder(r=.7,h=2,center=true);
  }
}

// try to draw Jansen linkage leg assembly as it might appear in steel

// these are for configuration "E" as referenced in other drawings
AC=17.5;
Ay =  3.318; Bx = 53.833;
BD = 48.020; BE = 46.977; BH = 40.359;
CD = 59.635; CH = 71.441; DE = 66.437;
EF = 47.467; FG = 75.792;
FH = 40.843; GH = 55.790;

DEleft = (DE*DE + BD*BD - BE*BE)/(2*DE);
FGleft = (FG*FG + FH*FH - GH*GH)/(2*FG);
DEperp = sqrt(BD*BD - DEleft*DEleft);
FGperp = sqrt(FH*FH - FGleft*FGleft);

echo(str("DEleft=",DEleft,"   DEperp=",DEperp));
echo(str("FGleft=",FGleft,"   FGperp=",FGperp));

r38 = (3/8)*2.54/2;  // radius of 3/8" bolt

a=360*$t;
legAssembly(a,0);
mirror([1,0,0]) legAssembly(180-a,1.2);
//legAssembly(100);

%translate([0,-93,0]) cube([200,2,2],center=true);

// -----------------------------------------------------------------

// plot a link shadow, a different way, to check kinematic correctness
module checkLink(xa,ya,xb,yb,ab) {
  *translate([(xa+xb)/2,(ya+yb)/2,-9])
    rotate([0,0,atan2(yb-ya,xb-xa)]) cube([ab,1,1],center=true);
}

function triK1(ax,ay,ca,bx,by,cb) = (cb*cb - ca*ca + ax*ax -bx*bx +ay*ay -by*by)/(2*(ax-bx));

// ===================================================================

module legAssembly(ang=0,linkOffset=0) {

// solve kinematics for given crank angle
xC = AC*cos(ang);
yC = AC*sin(ang)+Ay;
echo("C",xC,yC);

k1=(yC*yC - Bx*Bx + BD*BD - CD*CD + xC*xC)/(2*yC);
k2=(xC+Bx)/yC;
c=k1*k1-BD*BD+Bx*Bx;
b=2*(Bx-k1*k2);
a=k2*k2+1;
sgnD=(yC<0)?1:-1;
xD=(-b+sgnD*sqrt(b*b-4*a*c))/(2*a);
yD=sqrt(BD*BD - pow(xD+Bx,2));
echo("D",xD,yD,"CD err",sqrt(pow(xC-xD,2)+pow(yC-yD,2))-CD);

hipRot = atan2(yD,Bx+xD)-atan2(DEperp,DEleft);
echo("hipRot",hipRot);
xE = cos(hipRot) * (DEleft-DE) - sin(hipRot) * DEperp - Bx;
yE = sin(hipRot) * (DEleft-DE) + cos(hipRot) * DEperp;
/*
ke1=(yD*yD + xD*xD + DE*DE + BE*BE)/(2*yD);
ke2=(xD+Bx)/yD;
ae=2+ke2*ke2;
be=2*(Bx-ke1*ke2);
ce=ke1*ke1 - BE*BE +Bx*Bx;
echo("E abc:",ae,be,ce);
xE=(-be+sqrt(be*be-4*ae*ce))/(2*ae);
yE=sqrt(BE*BE - pow(xE+Bx,2));
*/
echo("E",xE,yE);

// this initial soln. seems wrong.
//xH=(BH*BH + xC*xC - CH*CH - Bx*Bx)/(2*(xC+Bx));
//yH=-sqrt(CH*CH - xC*xC + 2*xC*xH - xH*xH);
k1h=(xC*xC + yC*yC + BH*BH - CH*CH - Bx*Bx)/(2*yC);
k2h=-(xC+Bx)/yC;
ah=k2h*k2h+1;
bh=2*(k1h*k2h + Bx);
ch=k1h*k1h + Bx*Bx - BH*BH;
sgnH=(yC>0)?1:-1;
xH=(-bh+sgnH*sqrt(bh*bh-4*ah*ch))/(2*ah);
yH=-sqrt(BH*BH - pow(xH+Bx,2));
bhRot=atan2(yH,xH+Bx);
echo("H",xH,yH,"rot",bhRot,"CH err",sqrt(pow(xH-xC,2)+pow(yH-yC,2))-CH);

/*
k1f=(FH*FH - EF*EF - yE*yE - yH*yH + xE*xE - xH*xH) / (2*(yE-yH));
k2f=(xH-xE)/(yE-yH);
af=k2f*k2f+1;
bf=2*(k1f*k2f - xH - k2f*yH);
cf=xH*xH + yH*yH - 2*k1f*yH + k1f*k1f - FH*FH;
xF=(-bf-sqrt(bf*bf - 4*af*cf))/(2*af);
yF=k1f+k2f*xF;
*/
k2f = (yE-yH)/(xE-xH);
k1f = triK1(xE,yE,EF,xH,yH,FH);
af=k2f*k2f+1;
bf=2*(k2f*xE - k1f*k2f -yE);
cf=k1f*k1f - 2*k1f*xE + xE*xE + yE*yE - EF*EF;
yF=(-bf-sqrt(bf*bf - 4*af*cf))/(2*af);
xF=k1f-k2f*yF;
echo("F",xF,yF,"EF err",sqrt(pow(xF-xE,2)+pow(yF-yE,2))-EF);
echo("FH err",sqrt(pow(xF-xH,2)+pow(yF-yH,2))-FH);

//  -------------------------- crank-arm circle reference
%translate([0,Ay,0]) difference() {
  cylinder(r=AC,h=1,$fn=48,center=true);
  cylinder(r=2,h=2,center=true);
}

// draw the hip so that the main "plane", the ED centerline plane, is at z=0
translate([-Bx,0,0]) rotate([0,0,hipRot])
    translate([DEleft-DE,DEperp,0]) hip();
//translate([-Bx,0,2.5]) rotate([0,0,12.5]) translate([-DEleft,DEperp,0]) hip();
//translate([ Bx,0,0]) rotate([0,0,-20]) translate([DE-DEleft,DEperp,0]) mirror([1,0,0])
//  hip();
checkLink(-Bx,0,xD,yD,BD);
checkLink(-Bx,0,xE,yE,BE);
checkLink(xD,yD,xE,yE,DE);

translate([-Bx,0,0]) rotate([0,0,bhRot])
   BHlinks();
checkLink(-Bx,0,xH,yH,BH);

//translate([xC,yC,2]) rotate([0,0,142])
//   CDlink();
//translate([0,0,linkOffset-.5]) CDlink(xC,yC,xD,yD);
translate([xC,yC,linkOffset-.5]) rotate([0,0,atan2(yD-yC,xD-xC)])
  mirror([0,0,(linkOffset>0)?1:0]) crankLink(CD);
checkLink(xC,yC,xD,yD,CD);

//translate([0,0,linkOffset+1.8]) CDlink(xC,yC,xH,yH);
translate([xC,yC,linkOffset+1.8]) rotate([0,0,atan2(yH-yC,xH-xC)])
  mirror([0,0,(linkOffset>0)?1:0]) crankLink(CH);
checkLink(xC,yC,xH,yH,CH);

//%EFlink1(xE,yE,xF,yF);
translate([xF,yF,0]) rotate([0,0,atan2(yE-yF,xE-xF)]) EFlink();
checkLink(xE,yE,xF,yF,EF);

footRot = atan2(yH-yF,xH-xF)-atan2(FGperp,FGleft);
translate([xF,yF,0]) rotate([0,0,footRot])
   foot();
checkLink(xF,yF,xH,yH,FH);

} // end module legAssembly()

// -----------------------------------------------------------------

module foot() difference() {
  union() {
    hull() {  // FG
      cube([4,2.6,2.6],center=true);
      translate([FG-1.3,0,0]) cylinder(r=1.3,h=2.6,$fn=24,center=true);
    }
    for (z=[-1,1]) hull() {
      translate([-5,2,1.5*z])scale([3,5,1])cylinder(r=1,h=.4,$fn=64,center=true);
      translate([ 8,0,1.5*z])cylinder(r=.3,h=.4,center=true);
    }
    translate([FGleft,FGperp-5,0]) cube([2.6,6,2.6],center=true);
    translate([FGleft,FGperp-5,4.8]) cube([2.6,6,2.6],center=true);
    translate([FGleft,FGperp-5,2.5]) cube([2.6,2.6,7],center=true);
    color([.3,.3,.4,.8]) {
      translate([FGleft,FGperp-.5, 0 ]) cube([3.5,5,2.2],center=true);
      translate([FGleft,FGperp-.5,4.8]) cube([3.5,5,2.2],center=true);
    }
    hull() {
      translate([6,0,0]) sphere(.8);
      translate([FGleft,FGperp-5,0]) sphere(.8);
    }
    hull() {
      translate([FG-6,0,0]) sphere(.8);
      translate([FGleft,FGperp-6,0]) sphere(.8);
    }
    hull() {
      translate([FGleft,FGperp-5,5]) sphere(.8);
      translate([FGleft,0,0]) sphere(.8);
    }
  }

  cylinder(r=.3,h=4,center=true);
  cube([4.4,3,2],center=true);
  translate([FGleft,FGperp,0]) cylinder(r=.7,h=33,center=true);
}
$fn=12;

module hip() difference() {
  /*  old style, with forks ground from square tube :
  difference() {
    translate([DE/2,0,0]) cube([DE+3,2.6,2.6],center=true);
    cylinder(r=.5,h=6,center=true);
    cube([7,3,2],center=true);

    translate([DE,0,0]) {
      cylinder(r=.25,h=8,center=true);
      cube([5,3,2],center=true);
    }
  }
  */
  union() {
    translate([DE/2,0,0]) cube([DE-5,2.5,2.5],center=true); // top tube
    translate([DE-DEleft,-DEperp,-1.2]) cylinder(r=1.4,h=7.2,$fn=36); // axle

    // top tube fork plates
    translate([DE,0,0]) mirror([1,0,0]) eFork();
                                        eFork();

    hull() {  // diag tubes
      translate([DE-DEleft,-DEperp,0]) sphere(.8);
      translate([8,0,0]) sphere(.8);
    }
    hull() {
      translate([DE-DEleft,-DEperp,0]) sphere(.8);
      translate([DE-8,0,0]) sphere(.8);
    }

    // extra bracing
    translate([DE/2,-20,0]) rotate([0,90,0]) cylinder(r=.8,h=20,center=true);
    translate([DE-DEleft,-DEperp,4]) rotate([-105,0,0]) cylinder(r=.8,h=14);
  }

  // pivot holes
  for (x=[0,DE]) translate([x,0,0]) cylinder(r=r38,h=11,center=true);
}

module eFork() for(z=[-1,1]) hull() {
  translate([0,0,1.4*z]) cylinder(r=2,h=.3,$fn=24,center=true);
  translate([6,0,1.4*z]) cube([1,2,.3],center=true);
}

module crankLink(dx=CD) {
  cylinder(r=1.4,h=.7,$fn=24,center=true);
  color([0.3,0.3,0.4,0.9]) translate([dx-1,0,.6]) difference() {
    cube([5,2.7,2.2],center=true);
    #translate([1,0,0]) cylinder(r=.64,h=11,center=true);
  }
  translate([dx/2-1,0,0]) cube([dx-3,1.3,1.3],center=true);
}

module CDlink(cx=0,cy=0,dx=CD,dy=0) {
echo("CD",cx,cy,dx,dy);
  translate([dx,dy,0]) cylinder(r=1.4,h=.7,$fn=24,center=true);
  translate([cx,cy,0]) cylinder(r=1.4,h=.7,$fn=24,center=true);
  hull() {
    translate([dx,dy,0]) cylinder(r=.65,h=1.3,$fn=24,center=true);
    translate([cx,cy,0]) cylinder(r=.65,h=1.3,$fn=24,center=true);
  }
}

module EFlink() difference() {
  union() {
    color([.4,.4,.5,.9]) {
      translate([   1.5,0,0]) cube([6,3,2.5],center=true);
      translate([EF-1.5,0,0]) cube([6,3,2.5],center=true);
    }
    translate([EF/2,0,0]) cube([EF-4,2.6,2.6],center=true);
  }

  translate([EF,0,0]) cylinder(r=r38,h=3,center=true);
                      cylinder(r=r38,h=5,center=true);
}

module EFlink1(ex=0,ey=0,fx=EF,fy=0) {
echo("EF",ex,ey,fx,fy);
  difference() {
     union() {
       color([.3,.3,.4,.9]) {
         translate([ex,ey,0]) cube([4,3,2],center=true);
         translate([fx,fy,0]) cube([4,3,2],center=true);
       }
       hull() {
         translate([ex,ey,0]) cylinder(r=1.3,h=2.6,center=true);
         translate([fx,fy,0]) cylinder(r=1.3,h=2.6,center=true);
       }
     }

     translate([ex,ey,0]) cylinder(r=.7,h=3,center=true);
     translate([fx,fy,0]) cylinder(r=.7,h=3,center=true);
  }
}

// this link drawn with B axle at origin, always.
module BHlinks() {
  difference() {
    translate([0,0,2.4]) cylinder(r=1.4,h=13.5,$fn=36,center=true);
    translate([0,0,2.4]) cube([4,4,7.9],center=true);
  }

  for(z=[-2.4,7.2]) {
     hull() {
       translate([BH-3,0,z]) sphere(.8);
       translate([   0,0,z]) sphere(.8);
     }
  }

  hull() {
    translate([   4,0.5,-2.4]) sphere(.8);
    translate([BH-5,1, 6  ]) sphere(.8);
  }
  hull() {
    translate([   4,-.5, 7]) sphere(.8);
    translate([BH-5, -1, -2  ]) sphere(.8);
  }

  for(z=[-1.7,6.2]) translate([BH,0,z]) difference() {
     hull() {
       cylinder(r=3,h=.33,$fn=36);
       translate([-8,0,0]) cylinder(r=1,h=.33);
     }
     cylinder(r=.7,h=2,center=true);
  }

}
module BHlinks1() {
  translate([0,0, 6.8])                 BHlink();
  translate([0,0,-2  ]) mirror([0,0,1]) BHlink();
}
module BHlink() {
  cylinder(r=1.4,h=6,$fn=24);

  //%translate([BH/2-1,0,1.3]) cube([BH-2,2.5,2.5],center=true);
  for (q=[-1,1]) hull() {
    translate([  0 ,1.5*q,1]) sphere(0.8);
    translate([BH-3,1  *q,1]) sphere(0.8);
  }
  hull() {
    translate([  0 ,0,5]) sphere(0.8);
    translate([BH-3,0,1]) sphere(0.8);
  }

  translate([BH,0,-.3]) difference() {
     hull() {
       cylinder(r=3,h=.33,$fn=36);
       translate([-8,0,0]) cylinder(r=1,h=.33);
     }
     cylinder(r=.7,h=2,center=true);
  }
}


add a TODO

add a TODO

//TODO: see the error file on the desktop

use <../../../name-tag.scad>

icons_xOffset = 30;
icons_xyScale = 0.879;
icons_yOffset = 4;

nametag(baseColor = "Blue",
	    baseHeight = 12,
        baseThickness = 2,
        baseWidth = 76,
      	bottomText = "Andrea's Fish",
        bottomTextColor = "white",
        bottomTextFont = "Bauhaus 93", // "Arial", "Wingdings",
        bottomTextOffsetX = 0,
        bottomTextOffsetY = -7,
      	bottomTextSize = 7,
        chainLoop = false,
		xIconOffset = icons_xOffset,
		yIconOffset = icons_yOffset,
		leftIconHeight = 3,
      	leftIconType = "Fish",
		leftIconXyScale = icons_xyScale,
        letterThickness = 3,
      	rightIconType = "Fish",
        rightIconHeight = 3,
		rightIconXyScale = icons_xyScale,
		rightIconOffsetY = icons_yOffset,
        roundedCorners = true,
        showBorder = "No",
        topText = "Ira",
      	topTextOffsetY = 4,
        topTextSize = 11,
        topTextColor = "white",
        topTextFont = "Bauhaus 93"); // "Bauhaus 93" "Helvetica");


rack updated 3

rack updated 3