vibe-openscad

tier-3-butt-hinge / claude-opus-4-5-20251101

7 run / 累計 125.0s / 累計 $0.2917

claude opus 4.5 2025-11-01 bare

bare (provider default effort)

run detail →
render
bare render of tier-3-butt-hinge
loading STL…
success 20.5s · 707/1392t · $0.0383
SCAD (129 lines)
// Butt Hinge - Furniture Small Size
// Three parts: Left leaf, Right leaf, Pin

// Parameters
leaf_length = 30;      // Y direction (along hinge axis)
leaf_width = 25;       // X direction (opening direction)
leaf_thickness = 2;    // Z direction

pin_diameter = 4;
pin_length = 32;
pin_clearance = 0.3;

knuckle_outer_diameter = 8;
knuckle_inner_diameter = pin_diameter + pin_clearance;
knuckle_height = 6;    // 30mm / 5 = 6mm each
knuckle_count = 5;

// Countersunk hole parameters
hole_diameter = 3.2;
countersink_diameter = 6;
countersink_depth = 1;
hole_spacing = 8;
hole_offset_from_knuckle = 12.5;  // Center of holes from knuckle edge

$fn = 64;

// Module for countersunk hole
module countersunk_hole() {
    union() {
        // Through hole
        cylinder(h = leaf_thickness + 1, d = hole_diameter, center = true);
        // Countersink (on top surface, z = leaf_thickness/2)
        translate([0, 0, leaf_thickness/2 - countersink_depth/2 + 0.01])
            cylinder(h = countersink_depth, d1 = hole_diameter, d2 = countersink_diameter, center = true);
    }
}

// Module for knuckle (half cylinder attached to leaf)
module knuckle(is_left) {
    difference() {
        // Outer cylinder
        rotate([-90, 0, 0])
            cylinder(h = knuckle_height, d = knuckle_outer_diameter, center = false);
        // Inner hole for pin
        rotate([-90, 0, 0])
            translate([0, 0, -0.1])
                cylinder(h = knuckle_height + 0.2, d = knuckle_inner_diameter, center = false);
    }
}

// Module for leaf plate (without knuckles)
module leaf_plate() {
    // Plate positioned so that the edge at x=0 aligns with knuckle center
    // and extends in -x direction for left leaf (will be mirrored for right)
    translate([-leaf_width, 0, -leaf_thickness/2])
        cube([leaf_width, leaf_length, leaf_thickness]);
}

// Module for left leaf (3 knuckles: positions 0, 2, 4 - i.e., outer two + center)
module left_leaf() {
    knuckle_radius = knuckle_outer_diameter / 2;
    
    difference() {
        union() {
            // Main plate - extends in -X direction
            // Plate top surface at z = knuckle center height - leaf_thickness/2 + knuckle_radius
            // For 180° open, both plates should be on same plane
            // Knuckle center is at z=0, so plate surface should be at z = leaf_thickness/2
            // But we want flat surfaces coplanar, so plate from z=0 to z=-leaf_thickness
            translate([-leaf_width, 0, -leaf_thickness])
                cube([leaf_width, leaf_length, leaf_thickness]);
            
            // Knuckles at positions 0, 2, 4 (left leaf gets 1st, 3rd, 5th)
            for (i = [0, 2, 4]) {
                translate([0, i * knuckle_height, 0])
                    knuckle(true);
            }
        }
        
        // Countersunk holes (3 holes along Y axis)
        for (i = [-1, 0, 1]) {
            translate([-hole_offset_from_knuckle, leaf_length/2 + i * hole_spacing, -leaf_thickness/2])
                countersunk_hole();
        }
    }
}

// Module for right leaf (2 knuckles: positions 1, 3 - middle two)
module right_leaf() {
    difference() {
        union() {
            // Main plate - extends in +X direction (mirrored)
            translate([0, 0, -leaf_thickness])
                cube([leaf_width, leaf_length, leaf_thickness]);
            
            // Knuckles at positions 1, 3 (right leaf gets 2nd, 4th)
            for (i = [1, 3]) {
                translate([0, i * knuckle_height, 0])
                    knuckle(false);
            }
        }
        
        // Countersunk holes (3 holes along Y axis)
        for (i = [-1, 0, 1]) {
            translate([hole_offset_from_knuckle, leaf_length/2 + i * hole_spacing, -leaf_thickness/2])
                countersunk_hole();
        }
    }
}

// Module for pin
module pin() {
    rotate([-90, 0, 0])
        translate([0, 0, -1])  // Start 1mm before knuckles
            cylinder(h = pin_length, d = pin_diameter, center = false);
}

// Assembly - 180° open position
// Left leaf (red)
color("DarkGray")
    left_leaf();

// Right leaf (blue)  
color("Gray")
    right_leaf();

// Pin (silver)
color("Silver")
    pin();
パラメータ (14)
スライダを動かすと openscad-wasm で再レンダリング

prompt

OpenSCAD で、家具用の小型バット蝶番(butt hinge)を作ってください。
3 つのパーツ(左板、右板、ピン軸)が組み合わさって動作する完成品を、
「開いた状態(180°)」で 1 つの SCAD ファイルに配置して出力します。

寸法と配置:
- 板(leaf)2 枚: 30mm × 25mm × 厚さ 2mm の鉄板形状
  - 縦 30mm の辺がピン軸に沿う(ヒンジ軸方向)
  - 横 25mm の辺が回転で開く方向に伸びる
- ピン軸: 直径 4mm の円柱、長さ 32mm(両端 1mm ずつ knuckle から飛び出す)
- knuckle(筒部): 縦 30mm を 5 等分(各 6mm)に区切り、左板に 3 個・右板に 2 個を
  互い違いに配置(左板は外側 2 個 + 中央 1 個、右板は中間 2 個)
- knuckle 外径 8mm、内径はピン軸 + 0.3mm クリアランス(= 4.6mm 穴)
- 左板と右板はピン軸を共有して回転可能。180° 開いた状態で、両板の
  平らな面が同一平面に来るように配置する
- 各板の knuckle から離れた側に、M3 用の皿穴を 3 個ずつ
  (穴ピッチは板の縦方向に 8mm 間隔、皿穴は表面から見て直径 6mm × 深さ 1mm
  のテーパ + 直径 3.2mm の貫通穴)

座標系:
- ピン軸の中心線を Y 軸に重ねる(ピン軸は +Y 方向)
- 板の平らな面は Z 軸に直交し、左板が x<0 側、右板が x>0 側に伸びる(180° 開)
- knuckle は X=0 を中心とし、Y 方向に 6mm ずつ並ぶ

完成したコード全体を ```openscad ... ``` のフェンスで囲んで出力してください。
コードのみで、追加の説明は不要です。

variant: effort

low success
low
9.9s · 808/686t · $0.0212
SCAD (74 lines)
// Butt Hinge - 180° open position

// Parameters
leaf_width = 25;
leaf_height = 30;
leaf_thickness = 2;

pin_diameter = 4;
pin_length = 32;
pin_clearance = 0.3;

knuckle_od = 8;
knuckle_id = pin_diameter + pin_clearance;
knuckle_height = 6;

hole_diameter = 3.2;
countersink_diameter = 6;
countersink_depth = 1;
hole_spacing = 8;

// Countersunk hole module
module countersunk_hole() {
    union() {
        cylinder(d=hole_diameter, h=leaf_thickness+1, $fn=32);
        translate([0, 0, leaf_thickness - countersink_depth])
            cylinder(d1=hole_diameter, d2=countersink_diameter, h=countersink_depth+0.01, $fn=32);
    }
}

// Leaf with knuckles
module leaf(knuckle_positions) {
    difference() {
        union() {
            // Plate
            translate([0, 0, -leaf_thickness/2])
                cube([leaf_width, leaf_height, leaf_thickness]);
            // Knuckles
            for (i = knuckle_positions) {
                translate([0, i * knuckle_height, 0])
                    rotate([-90, 0, 0])
                        difference() {
                            cylinder(d=knuckle_od, h=knuckle_height, $fn=48);
                            translate([0, 0, -0.5])
                                cylinder(d=knuckle_id, h=knuckle_height+1, $fn=48);
                        }
            }
        }
        // Countersunk holes
        hole_x = leaf_width - 8;
        for (j = [0:2]) {
            translate([hole_x, 3 + j * hole_spacing, -leaf_thickness/2 - 0.5])
                countersunk_hole();
        }
    }
}

// Pin
module pin() {
    translate([0, -1, 0])
        rotate([-90, 0, 0])
            cylinder(d=pin_diameter, h=pin_length, $fn=48);
}

// Assembly
// Left leaf (knuckles at positions 0, 2, 4)
translate([0, 0, 0])
    rotate([0, 0, 180])
        leaf([0, 2, 4]);

// Right leaf (knuckles at positions 1, 3)
leaf([1, 3]);

// Pin
color("silver") pin();
mediumnot run
high (default) success
high
20.5s · 707/1392t · $0.0383
SCAD (129 lines)
// Butt Hinge - Furniture Small Size
// Three parts: Left leaf, Right leaf, Pin

// Parameters
leaf_length = 30;      // Y direction (along hinge axis)
leaf_width = 25;       // X direction (opening direction)
leaf_thickness = 2;    // Z direction

pin_diameter = 4;
pin_length = 32;
pin_clearance = 0.3;

knuckle_outer_diameter = 8;
knuckle_inner_diameter = pin_diameter + pin_clearance;
knuckle_height = 6;    // 30mm / 5 = 6mm each
knuckle_count = 5;

// Countersunk hole parameters
hole_diameter = 3.2;
countersink_diameter = 6;
countersink_depth = 1;
hole_spacing = 8;
hole_offset_from_knuckle = 12.5;  // Center of holes from knuckle edge

$fn = 64;

// Module for countersunk hole
module countersunk_hole() {
    union() {
        // Through hole
        cylinder(h = leaf_thickness + 1, d = hole_diameter, center = true);
        // Countersink (on top surface, z = leaf_thickness/2)
        translate([0, 0, leaf_thickness/2 - countersink_depth/2 + 0.01])
            cylinder(h = countersink_depth, d1 = hole_diameter, d2 = countersink_diameter, center = true);
    }
}

// Module for knuckle (half cylinder attached to leaf)
module knuckle(is_left) {
    difference() {
        // Outer cylinder
        rotate([-90, 0, 0])
            cylinder(h = knuckle_height, d = knuckle_outer_diameter, center = false);
        // Inner hole for pin
        rotate([-90, 0, 0])
            translate([0, 0, -0.1])
                cylinder(h = knuckle_height + 0.2, d = knuckle_inner_diameter, center = false);
    }
}

// Module for leaf plate (without knuckles)
module leaf_plate() {
    // Plate positioned so that the edge at x=0 aligns with knuckle center
    // and extends in -x direction for left leaf (will be mirrored for right)
    translate([-leaf_width, 0, -leaf_thickness/2])
        cube([leaf_width, leaf_length, leaf_thickness]);
}

// Module for left leaf (3 knuckles: positions 0, 2, 4 - i.e., outer two + center)
module left_leaf() {
    knuckle_radius = knuckle_outer_diameter / 2;
    
    difference() {
        union() {
            // Main plate - extends in -X direction
            // Plate top surface at z = knuckle center height - leaf_thickness/2 + knuckle_radius
            // For 180° open, both plates should be on same plane
            // Knuckle center is at z=0, so plate surface should be at z = leaf_thickness/2
            // But we want flat surfaces coplanar, so plate from z=0 to z=-leaf_thickness
            translate([-leaf_width, 0, -leaf_thickness])
                cube([leaf_width, leaf_length, leaf_thickness]);
            
            // Knuckles at positions 0, 2, 4 (left leaf gets 1st, 3rd, 5th)
            for (i = [0, 2, 4]) {
                translate([0, i * knuckle_height, 0])
                    knuckle(true);
            }
        }
        
        // Countersunk holes (3 holes along Y axis)
        for (i = [-1, 0, 1]) {
            translate([-hole_offset_from_knuckle, leaf_length/2 + i * hole_spacing, -leaf_thickness/2])
                countersunk_hole();
        }
    }
}

// Module for right leaf (2 knuckles: positions 1, 3 - middle two)
module right_leaf() {
    difference() {
        union() {
            // Main plate - extends in +X direction (mirrored)
            translate([0, 0, -leaf_thickness])
                cube([leaf_width, leaf_length, leaf_thickness]);
            
            // Knuckles at positions 1, 3 (right leaf gets 2nd, 4th)
            for (i = [1, 3]) {
                translate([0, i * knuckle_height, 0])
                    knuckle(false);
            }
        }
        
        // Countersunk holes (3 holes along Y axis)
        for (i = [-1, 0, 1]) {
            translate([hole_offset_from_knuckle, leaf_length/2 + i * hole_spacing, -leaf_thickness/2])
                countersunk_hole();
        }
    }
}

// Module for pin
module pin() {
    rotate([-90, 0, 0])
        translate([0, 0, -1])  // Start 1mm before knuckles
            cylinder(h = pin_length, d = pin_diameter, center = false);
}

// Assembly - 180° open position
// Left leaf (red)
color("DarkGray")
    left_leaf();

// Right leaf (blue)  
color("Gray")
    right_leaf();

// Pin (silver)
color("Silver")
    pin();
maxnot run
xhighnot run

variant: thinking

off (default) success
off
9.9s · 808/686t · $0.0212
SCAD (74 lines)
// Butt Hinge - 180° open position

// Parameters
leaf_width = 25;
leaf_height = 30;
leaf_thickness = 2;

pin_diameter = 4;
pin_length = 32;
pin_clearance = 0.3;

knuckle_od = 8;
knuckle_id = pin_diameter + pin_clearance;
knuckle_height = 6;

hole_diameter = 3.2;
countersink_diameter = 6;
countersink_depth = 1;
hole_spacing = 8;

// Countersunk hole module
module countersunk_hole() {
    union() {
        cylinder(d=hole_diameter, h=leaf_thickness+1, $fn=32);
        translate([0, 0, leaf_thickness - countersink_depth])
            cylinder(d1=hole_diameter, d2=countersink_diameter, h=countersink_depth+0.01, $fn=32);
    }
}

// Leaf with knuckles
module leaf(knuckle_positions) {
    difference() {
        union() {
            // Plate
            translate([0, 0, -leaf_thickness/2])
                cube([leaf_width, leaf_height, leaf_thickness]);
            // Knuckles
            for (i = knuckle_positions) {
                translate([0, i * knuckle_height, 0])
                    rotate([-90, 0, 0])
                        difference() {
                            cylinder(d=knuckle_od, h=knuckle_height, $fn=48);
                            translate([0, 0, -0.5])
                                cylinder(d=knuckle_id, h=knuckle_height+1, $fn=48);
                        }
            }
        }
        // Countersunk holes
        hole_x = leaf_width - 8;
        for (j = [0:2]) {
            translate([hole_x, 3 + j * hole_spacing, -leaf_thickness/2 - 0.5])
                countersunk_hole();
        }
    }
}

// Pin
module pin() {
    translate([0, -1, 0])
        rotate([-90, 0, 0])
            cylinder(d=pin_diameter, h=pin_length, $fn=48);
}

// Assembly
// Left leaf (knuckles at positions 0, 2, 4)
translate([0, 0, 0])
    rotate([0, 0, 180])
        leaf([0, 2, 4]);

// Right leaf (knuckles at positions 1, 3)
leaf([1, 3]);

// Pin
color("silver") pin();
adaptivenot run
dynamicnot run

iteration: iter-png

i1 success
iter 1
25.1s · 2855/1780t · $0.0588
diff vs bare: +65/-51
  // Butt Hinge - Furniture Small Size
  // Three parts: Left leaf, Right leaf, Pin
  
  // Parameters
  leaf_length = 30;      // Y direction (along hinge axis)
  leaf_width = 25;       // X direction (opening direction)
  leaf_thickness = 2;    // Z direction
  
  pin_diameter = 4;
  pin_length = 32;
  pin_clearance = 0.3;
  
  knuckle_outer_diameter = 8;
  knuckle_inner_diameter = pin_diameter + pin_clearance;
+ knuckle_radius = knuckle_outer_diameter / 2;
  knuckle_height = 6;    // 30mm / 5 = 6mm each
- knuckle_count = 5;
  
  // Countersunk hole parameters
  hole_diameter = 3.2;
  countersink_diameter = 6;
  countersink_depth = 1;
  hole_spacing = 8;
- hole_offset_from_knuckle = 12.5;  // Center of holes from knuckle edge
+ hole_offset_from_edge = 12.5;  // Center of holes from outer edge of leaf
  
  $fn = 64;
  
- // Module for countersunk hole
+ // Module for countersunk hole (countersink on top, hole goes through)
  module countersunk_hole() {
-     union() {
-         // Through hole
-         cylinder(h = leaf_thickness + 1, d = hole_diameter, center = true);
-         // Countersink (on top surface, z = leaf_thickness/2)
-         translate([0, 0, leaf_thickness/2 - countersink_depth/2 + 0.01])
-             cylinder(h = countersink_depth, d1 = hole_diameter, d2 = countersink_diameter, center = true);
-     }
+     // Countersink from top surface
+     translate([0, 0, leaf_thickness - countersink_depth])
+         cylinder(h = countersink_depth + 0.01, d1 = hole_diameter, d2 = countersink_diameter);
+     // Through hole
+     translate([0, 0, -0.01])
+         cylinder(h = leaf_thickness + 0.02, d = hole_diameter);
  }
  
- // Module for knuckle (half cylinder attached to leaf)
- module knuckle(is_left) {
+ // Module for knuckle cylinder
+ module knuckle_cylinder(height) {
      difference() {
          // Outer cylinder
-         rotate([-90, 0, 0])
-             cylinder(h = knuckle_height, d = knuckle_outer_diameter, center = false);
+         cylinder(h = height, d = knuckle_outer_diameter);
          // Inner hole for pin
-         rotate([-90, 0, 0])
-             translate([0, 0, -0.1])
-                 cylinder(h = knuckle_height + 0.2, d = knuckle_inner_diameter, center = false);
+         translate([0, 0, -0.01])
+             cylinder(h = height + 0.02, d = knuckle_inner_diameter);
      }
  }
  
- // Module for leaf plate (without knuckles)
- module leaf_plate() {
-     // Plate positioned so that the edge at x=0 aligns with knuckle center
-     // and extends in -x direction for left leaf (will be mirrored for right)
-     translate([-leaf_width, 0, -leaf_thickness/2])
-         cube([leaf_width, leaf_length, leaf_thickness]);
- }
- 
- // Module for left leaf (3 knuckles: positions 0, 2, 4 - i.e., outer two + center)
+ // Module for left leaf (3 knuckles: positions 0, 2, 4)
  module left_leaf() {
-     knuckle_radius = knuckle_outer_diameter / 2;
-     
      difference() {
          union() {
-             // Main plate - extends in -X direction
-             // Plate top surface at z = knuckle center height - leaf_thickness/2 + knuckle_radius
-             // For 180° open, both plates should be on same plane
-             // Knuckle center is at z=0, so plate surface should be at z = leaf_thickness/2
-             // But we want flat surfaces coplanar, so plate from z=0 to z=-leaf_thickness
-             translate([-leaf_width, 0, -leaf_thickness])
-                 cube([leaf_width, leaf_length, leaf_thickness]);
+             // Main plate - extends in -X direction from knuckle center
+             // Plate top surface at z = leaf_thickness, bottom at z = 0
+             // Knuckle center (pin axis) is at z = -knuckle_radius (below plate bottom)
+             translate([-leaf_width + knuckle_radius, 0, 0])
+                 cube([leaf_width - knuckle_radius, leaf_length, leaf_thickness]);
              
+             // Transition piece connecting plate to knuckle
+             translate([0, 0, 0])
+                 difference() {
+                     translate([-knuckle_radius, 0, -knuckle_radius])
+                         cube([knuckle_radius, leaf_length, knuckle_radius + leaf_thickness]);
+                     // Cut out the cylinder space
+                     translate([0, -0.01, -knuckle_radius])
+                         rotate([-90, 0, 0])
+                             cylinder(h = leaf_length + 0.02, d = knuckle_outer_diameter);
+                 }
+             
              // Knuckles at positions 0, 2, 4 (left leaf gets 1st, 3rd, 5th)
              for (i = [0, 2, 4]) {
-                 translate([0, i * knuckle_height, 0])
-                     knuckle(true);
+                 translate([0, i * knuckle_height, -knuckle_radius])
+                     rotate([-90, 0, 0])
+                         knuckle_cylinder(knuckle_height);
              }
          }
          
          // Countersunk holes (3 holes along Y axis)
+         // Positioned toward the outer edge of the leaf
          for (i = [-1, 0, 1]) {
-             translate([-hole_offset_from_knuckle, leaf_length/2 + i * hole_spacing, -leaf_thickness/2])
+             translate([-leaf_width + knuckle_radius + hole_offset_from_edge, 
+                        leaf_length/2 + i * hole_spacing, 0])
                  countersunk_hole();
          }
      }
  }
  
- // Module for right leaf (2 knuckles: positions 1, 3 - middle two)
+ // Module for right leaf (2 knuckles: positions 1, 3)
  module right_leaf() {
      difference() {
          union() {
-             // Main plate - extends in +X direction (mirrored)
-             translate([0, 0, -leaf_thickness])
-                 cube([leaf_width, leaf_length, leaf_thickness]);
+             // Main plate - extends in +X direction from knuckle center
+             translate([0, 0, 0])
+                 cube([leaf_width - knuckle_radius, leaf_length, leaf_thickness]);
              
+             // Transition piece connecting plate to knuckle
+             difference() {
+                 translate([0, 0, -knuckle_radius])
+                     cube([knuckle_radius, leaf_length, knuckle_radius + leaf_thickness]);
+                 // Cut out the cylinder space
+                 translate([0, -0.01, -knuckle_radius])
+                     rotate([-90, 0, 0])
+                         cylinder(h = leaf_length + 0.02, d = knuckle_outer_diameter);
+             }
+             
              // Knuckles at positions 1, 3 (right leaf gets 2nd, 4th)
              for (i = [1, 3]) {
-                 translate([0, i * knuckle_height, 0])
-                     knuckle(false);
+                 translate([0, i * knuckle_height, -knuckle_radius])
+                     rotate([-90, 0, 0])
+                         knuckle_cylinder(knuckle_height);
              }
          }
          
          // Countersunk holes (3 holes along Y axis)
          for (i = [-1, 0, 1]) {
-             translate([hole_offset_from_knuckle, leaf_length/2 + i * hole_spacing, -leaf_thickness/2])
+             translate([leaf_width - knuckle_radius - hole_offset_from_edge, 
+                        leaf_length/2 + i * hole_spacing, 0])
                  countersunk_hole();
          }
      }
  }
  
  // Module for pin
  module pin() {
-     rotate([-90, 0, 0])
-         translate([0, 0, -1])  // Start 1mm before knuckles
-             cylinder(h = pin_length, d = pin_diameter, center = false);
+     translate([0, -1, -knuckle_radius])
+         rotate([-90, 0, 0])
+             cylinder(h = pin_length, d = pin_diameter);
  }
  
  // Assembly - 180° open position
- // Left leaf (red)
+ // Both plates lie flat with top surfaces coplanar (z = leaf_thickness)
+ // Pin axis along Y at x=0, z=-knuckle_radius
+ 
+ // Left leaf
  color("DarkGray")
      left_leaf();
  
- // Right leaf (blue)  
+ // Right leaf
  color("Gray")
      right_leaf();
  
- // Pin (silver)
+ // Pin
  color("Silver")
      pin();
SCAD (143 lines)
// Butt Hinge - Furniture Small Size
// Three parts: Left leaf, Right leaf, Pin

// Parameters
leaf_length = 30;      // Y direction (along hinge axis)
leaf_width = 25;       // X direction (opening direction)
leaf_thickness = 2;    // Z direction

pin_diameter = 4;
pin_length = 32;
pin_clearance = 0.3;

knuckle_outer_diameter = 8;
knuckle_inner_diameter = pin_diameter + pin_clearance;
knuckle_radius = knuckle_outer_diameter / 2;
knuckle_height = 6;    // 30mm / 5 = 6mm each

// Countersunk hole parameters
hole_diameter = 3.2;
countersink_diameter = 6;
countersink_depth = 1;
hole_spacing = 8;
hole_offset_from_edge = 12.5;  // Center of holes from outer edge of leaf

$fn = 64;

// Module for countersunk hole (countersink on top, hole goes through)
module countersunk_hole() {
    // Countersink from top surface
    translate([0, 0, leaf_thickness - countersink_depth])
        cylinder(h = countersink_depth + 0.01, d1 = hole_diameter, d2 = countersink_diameter);
    // Through hole
    translate([0, 0, -0.01])
        cylinder(h = leaf_thickness + 0.02, d = hole_diameter);
}

// Module for knuckle cylinder
module knuckle_cylinder(height) {
    difference() {
        // Outer cylinder
        cylinder(h = height, d = knuckle_outer_diameter);
        // Inner hole for pin
        translate([0, 0, -0.01])
            cylinder(h = height + 0.02, d = knuckle_inner_diameter);
    }
}

// Module for left leaf (3 knuckles: positions 0, 2, 4)
module left_leaf() {
    difference() {
        union() {
            // Main plate - extends in -X direction from knuckle center
            // Plate top surface at z = leaf_thickness, bottom at z = 0
            // Knuckle center (pin axis) is at z = -knuckle_radius (below plate bottom)
            translate([-leaf_width + knuckle_radius, 0, 0])
                cube([leaf_width - knuckle_radius, leaf_length, leaf_thickness]);
            
            // Transition piece connecting plate to knuckle
            translate([0, 0, 0])
                difference() {
                    translate([-knuckle_radius, 0, -knuckle_radius])
                        cube([knuckle_radius, leaf_length, knuckle_radius + leaf_thickness]);
                    // Cut out the cylinder space
                    translate([0, -0.01, -knuckle_radius])
                        rotate([-90, 0, 0])
                            cylinder(h = leaf_length + 0.02, d = knuckle_outer_diameter);
                }
            
            // Knuckles at positions 0, 2, 4 (left leaf gets 1st, 3rd, 5th)
            for (i = [0, 2, 4]) {
                translate([0, i * knuckle_height, -knuckle_radius])
                    rotate([-90, 0, 0])
                        knuckle_cylinder(knuckle_height);
            }
        }
        
        // Countersunk holes (3 holes along Y axis)
        // Positioned toward the outer edge of the leaf
        for (i = [-1, 0, 1]) {
            translate([-leaf_width + knuckle_radius + hole_offset_from_edge, 
                       leaf_length/2 + i * hole_spacing, 0])
                countersunk_hole();
        }
    }
}

// Module for right leaf (2 knuckles: positions 1, 3)
module right_leaf() {
    difference() {
        union() {
            // Main plate - extends in +X direction from knuckle center
            translate([0, 0, 0])
                cube([leaf_width - knuckle_radius, leaf_length, leaf_thickness]);
            
            // Transition piece connecting plate to knuckle
            difference() {
                translate([0, 0, -knuckle_radius])
                    cube([knuckle_radius, leaf_length, knuckle_radius + leaf_thickness]);
                // Cut out the cylinder space
                translate([0, -0.01, -knuckle_radius])
                    rotate([-90, 0, 0])
                        cylinder(h = leaf_length + 0.02, d = knuckle_outer_diameter);
            }
            
            // Knuckles at positions 1, 3 (right leaf gets 2nd, 4th)
            for (i = [1, 3]) {
                translate([0, i * knuckle_height, -knuckle_radius])
                    rotate([-90, 0, 0])
                        knuckle_cylinder(knuckle_height);
            }
        }
        
        // Countersunk holes (3 holes along Y axis)
        for (i = [-1, 0, 1]) {
            translate([leaf_width - knuckle_radius - hole_offset_from_edge, 
                       leaf_length/2 + i * hole_spacing, 0])
                countersunk_hole();
        }
    }
}

// Module for pin
module pin() {
    translate([0, -1, -knuckle_radius])
        rotate([-90, 0, 0])
            cylinder(h = pin_length, d = pin_diameter);
}

// Assembly - 180° open position
// Both plates lie flat with top surfaces coplanar (z = leaf_thickness)
// Pin axis along Y at x=0, z=-knuckle_radius

// Left leaf
color("DarkGray")
    left_leaf();

// Right leaf
color("Gray")
    right_leaf();

// Pin
color("Silver")
    pin();
i2 success
iter 2
22.0s · 3015/1709t · $0.0578
diff vs i1: +65/-65
  // Butt Hinge - Furniture Small Size
  // Three parts: Left leaf, Right leaf, Pin
  
  // Parameters
  leaf_length = 30;      // Y direction (along hinge axis)
  leaf_width = 25;       // X direction (opening direction)
  leaf_thickness = 2;    // Z direction
  
  pin_diameter = 4;
  pin_length = 32;
  pin_clearance = 0.3;
  
  knuckle_outer_diameter = 8;
  knuckle_inner_diameter = pin_diameter + pin_clearance;
  knuckle_radius = knuckle_outer_diameter / 2;
  knuckle_height = 6;    // 30mm / 5 = 6mm each
+ knuckle_gap = 0.1;     // Small gap between knuckles
  
  // Countersunk hole parameters
  hole_diameter = 3.2;
  countersink_diameter = 6;
  countersink_depth = 1;
  hole_spacing = 8;
- hole_offset_from_edge = 12.5;  // Center of holes from outer edge of leaf
  
  $fn = 64;
  
- // Module for countersunk hole (countersink on top, hole goes through)
+ // Module for countersunk hole
  module countersunk_hole() {
      // Countersink from top surface
      translate([0, 0, leaf_thickness - countersink_depth])
          cylinder(h = countersink_depth + 0.01, d1 = hole_diameter, d2 = countersink_diameter);
      // Through hole
      translate([0, 0, -0.01])
          cylinder(h = leaf_thickness + 0.02, d = hole_diameter);
  }
  
- // Module for knuckle cylinder
+ // Module for single knuckle cylinder
  module knuckle_cylinder(height) {
      difference() {
-         // Outer cylinder
          cylinder(h = height, d = knuckle_outer_diameter);
-         // Inner hole for pin
          translate([0, 0, -0.01])
              cylinder(h = height + 0.02, d = knuckle_inner_diameter);
      }
  }
  
- // Module for left leaf (3 knuckles: positions 0, 2, 4)
+ // Module for left leaf (3 knuckles at positions 0, 2, 4)
  module left_leaf() {
-     difference() {
-         union() {
-             // Main plate - extends in -X direction from knuckle center
-             // Plate top surface at z = leaf_thickness, bottom at z = 0
-             // Knuckle center (pin axis) is at z = -knuckle_radius (below plate bottom)
-             translate([-leaf_width + knuckle_radius, 0, 0])
-                 cube([leaf_width - knuckle_radius, leaf_length, leaf_thickness]);
+     union() {
+         difference() {
+             union() {
+                 // Main plate extending in -X direction
+                 // Plate is positioned so its top surface is at z=0 plane
+                 // and knuckle axis is at z = -knuckle_radius - leaf_thickness/2
+                 translate([-leaf_width + knuckle_radius, 0, 0])
+                     cube([leaf_width, leaf_length, leaf_thickness]);
+             }
              
-             // Transition piece connecting plate to knuckle
-             translate([0, 0, 0])
-                 difference() {
-                     translate([-knuckle_radius, 0, -knuckle_radius])
-                         cube([knuckle_radius, leaf_length, knuckle_radius + leaf_thickness]);
-                     // Cut out the cylinder space
-                     translate([0, -0.01, -knuckle_radius])
-                         rotate([-90, 0, 0])
-                             cylinder(h = leaf_length + 0.02, d = knuckle_outer_diameter);
-                 }
+             // Cut cylinder channel for knuckle area
+             translate([0, -0.01, -knuckle_radius])
+                 rotate([-90, 0, 0])
+                     cylinder(h = leaf_length + 0.02, d = knuckle_outer_diameter);
              
-             // Knuckles at positions 0, 2, 4 (left leaf gets 1st, 3rd, 5th)
-             for (i = [0, 2, 4]) {
-                 translate([0, i * knuckle_height, -knuckle_radius])
-                     rotate([-90, 0, 0])
-                         knuckle_cylinder(knuckle_height);
+             // Countersunk holes - 3 holes centered on the plate away from knuckle
+             for (i = [-1, 0, 1]) {
+                 translate([-leaf_width/2 + knuckle_radius/2, leaf_length/2 + i * hole_spacing, 0])
+                     countersunk_hole();
              }
          }
          
-         // Countersunk holes (3 holes along Y axis)
-         // Positioned toward the outer edge of the leaf
-         for (i = [-1, 0, 1]) {
-             translate([-leaf_width + knuckle_radius + hole_offset_from_edge, 
-                        leaf_length/2 + i * hole_spacing, 0])
-                 countersunk_hole();
-         }
+         // Add knuckles at positions 0, 2, 4 (Y = 0, 12, 24)
+         translate([0, 0, -knuckle_radius])
+             rotate([-90, 0, 0]) {
+                 // Knuckle 0
+                 translate([0, 0, 0])
+                     knuckle_cylinder(knuckle_height - knuckle_gap/2);
+                 // Knuckle 2
+                 translate([0, 0, 2 * knuckle_height + knuckle_gap/2])
+                     knuckle_cylinder(knuckle_height - knuckle_gap);
+                 // Knuckle 4
+                 translate([0, 0, 4 * knuckle_height + knuckle_gap/2])
+                     knuckle_cylinder(knuckle_height - knuckle_gap/2);
+             }
      }
  }
  
- // Module for right leaf (2 knuckles: positions 1, 3)
+ // Module for right leaf (2 knuckles at positions 1, 3)
  module right_leaf() {
-     difference() {
-         union() {
-             // Main plate - extends in +X direction from knuckle center
-             translate([0, 0, 0])
-                 cube([leaf_width - knuckle_radius, leaf_length, leaf_thickness]);
-             
-             // Transition piece connecting plate to knuckle
-             difference() {
-                 translate([0, 0, -knuckle_radius])
-                     cube([knuckle_radius, leaf_length, knuckle_radius + leaf_thickness]);
-                 // Cut out the cylinder space
-                 translate([0, -0.01, -knuckle_radius])
-                     rotate([-90, 0, 0])
-                         cylinder(h = leaf_length + 0.02, d = knuckle_outer_diameter);
+     union() {
+         difference() {
+             union() {
+                 // Main plate extending in +X direction
+                 translate([0, 0, 0])
+                     cube([leaf_width, leaf_length, leaf_thickness]);
              }
              
-             // Knuckles at positions 1, 3 (right leaf gets 2nd, 4th)
-             for (i = [1, 3]) {
-                 translate([0, i * knuckle_height, -knuckle_radius])
-                     rotate([-90, 0, 0])
-                         knuckle_cylinder(knuckle_height);
+             // Cut cylinder channel for knuckle area
+             translate([0, -0.01, -knuckle_radius])
+                 rotate([-90, 0, 0])
+                     cylinder(h = leaf_length + 0.02, d = knuckle_outer_diameter);
+             
+             // Countersunk holes
+             for (i = [-1, 0, 1]) {
+                 translate([leaf_width/2 + knuckle_radius/2, leaf_length/2 + i * hole_spacing, 0])
+                     countersunk_hole();
              }
          }
          
-         // Countersunk holes (3 holes along Y axis)
-         for (i = [-1, 0, 1]) {
-             translate([leaf_width - knuckle_radius - hole_offset_from_edge, 
-                        leaf_length/2 + i * hole_spacing, 0])
-                 countersunk_hole();
-         }
+         // Add knuckles at positions 1, 3 (Y = 6, 18)
+         translate([0, 0, -knuckle_radius])
+             rotate([-90, 0, 0]) {
+                 // Knuckle 1
+                 translate([0, 0, knuckle_height + knuckle_gap/2])
+                     knuckle_cylinder(knuckle_height - knuckle_gap);
+                 // Knuckle 3
+                 translate([0, 0, 3 * knuckle_height + knuckle_gap/2])
+                     knuckle_cylinder(knuckle_height - knuckle_gap);
+             }
      }
  }
  
  // Module for pin
  module pin() {
+     // Pin extends from Y = -1 to Y = 31 (32mm total, 1mm overhang each end)
      translate([0, -1, -knuckle_radius])
          rotate([-90, 0, 0])
              cylinder(h = pin_length, d = pin_diameter);
  }
  
  // Assembly - 180° open position
- // Both plates lie flat with top surfaces coplanar (z = leaf_thickness)
  // Pin axis along Y at x=0, z=-knuckle_radius
+ // Both plates have top surface at z = leaf_thickness
  
- // Left leaf
- color("DarkGray")
+ // Left leaf (extends in -X direction)
+ color("DimGray")
      left_leaf();
  
- // Right leaf
+ // Right leaf (extends in +X direction)  
  color("Gray")
      right_leaf();
  
  // Pin
  color("Silver")
      pin();
SCAD (143 lines)
// Butt Hinge - Furniture Small Size
// Three parts: Left leaf, Right leaf, Pin

// Parameters
leaf_length = 30;      // Y direction (along hinge axis)
leaf_width = 25;       // X direction (opening direction)
leaf_thickness = 2;    // Z direction

pin_diameter = 4;
pin_length = 32;
pin_clearance = 0.3;

knuckle_outer_diameter = 8;
knuckle_inner_diameter = pin_diameter + pin_clearance;
knuckle_radius = knuckle_outer_diameter / 2;
knuckle_height = 6;    // 30mm / 5 = 6mm each
knuckle_gap = 0.1;     // Small gap between knuckles

// Countersunk hole parameters
hole_diameter = 3.2;
countersink_diameter = 6;
countersink_depth = 1;
hole_spacing = 8;

$fn = 64;

// Module for countersunk hole
module countersunk_hole() {
    // Countersink from top surface
    translate([0, 0, leaf_thickness - countersink_depth])
        cylinder(h = countersink_depth + 0.01, d1 = hole_diameter, d2 = countersink_diameter);
    // Through hole
    translate([0, 0, -0.01])
        cylinder(h = leaf_thickness + 0.02, d = hole_diameter);
}

// Module for single knuckle cylinder
module knuckle_cylinder(height) {
    difference() {
        cylinder(h = height, d = knuckle_outer_diameter);
        translate([0, 0, -0.01])
            cylinder(h = height + 0.02, d = knuckle_inner_diameter);
    }
}

// Module for left leaf (3 knuckles at positions 0, 2, 4)
module left_leaf() {
    union() {
        difference() {
            union() {
                // Main plate extending in -X direction
                // Plate is positioned so its top surface is at z=0 plane
                // and knuckle axis is at z = -knuckle_radius - leaf_thickness/2
                translate([-leaf_width + knuckle_radius, 0, 0])
                    cube([leaf_width, leaf_length, leaf_thickness]);
            }
            
            // Cut cylinder channel for knuckle area
            translate([0, -0.01, -knuckle_radius])
                rotate([-90, 0, 0])
                    cylinder(h = leaf_length + 0.02, d = knuckle_outer_diameter);
            
            // Countersunk holes - 3 holes centered on the plate away from knuckle
            for (i = [-1, 0, 1]) {
                translate([-leaf_width/2 + knuckle_radius/2, leaf_length/2 + i * hole_spacing, 0])
                    countersunk_hole();
            }
        }
        
        // Add knuckles at positions 0, 2, 4 (Y = 0, 12, 24)
        translate([0, 0, -knuckle_radius])
            rotate([-90, 0, 0]) {
                // Knuckle 0
                translate([0, 0, 0])
                    knuckle_cylinder(knuckle_height - knuckle_gap/2);
                // Knuckle 2
                translate([0, 0, 2 * knuckle_height + knuckle_gap/2])
                    knuckle_cylinder(knuckle_height - knuckle_gap);
                // Knuckle 4
                translate([0, 0, 4 * knuckle_height + knuckle_gap/2])
                    knuckle_cylinder(knuckle_height - knuckle_gap/2);
            }
    }
}

// Module for right leaf (2 knuckles at positions 1, 3)
module right_leaf() {
    union() {
        difference() {
            union() {
                // Main plate extending in +X direction
                translate([0, 0, 0])
                    cube([leaf_width, leaf_length, leaf_thickness]);
            }
            
            // Cut cylinder channel for knuckle area
            translate([0, -0.01, -knuckle_radius])
                rotate([-90, 0, 0])
                    cylinder(h = leaf_length + 0.02, d = knuckle_outer_diameter);
            
            // Countersunk holes
            for (i = [-1, 0, 1]) {
                translate([leaf_width/2 + knuckle_radius/2, leaf_length/2 + i * hole_spacing, 0])
                    countersunk_hole();
            }
        }
        
        // Add knuckles at positions 1, 3 (Y = 6, 18)
        translate([0, 0, -knuckle_radius])
            rotate([-90, 0, 0]) {
                // Knuckle 1
                translate([0, 0, knuckle_height + knuckle_gap/2])
                    knuckle_cylinder(knuckle_height - knuckle_gap);
                // Knuckle 3
                translate([0, 0, 3 * knuckle_height + knuckle_gap/2])
                    knuckle_cylinder(knuckle_height - knuckle_gap);
            }
    }
}

// Module for pin
module pin() {
    // Pin extends from Y = -1 to Y = 31 (32mm total, 1mm overhang each end)
    translate([0, -1, -knuckle_radius])
        rotate([-90, 0, 0])
            cylinder(h = pin_length, d = pin_diameter);
}

// Assembly - 180° open position
// Pin axis along Y at x=0, z=-knuckle_radius
// Both plates have top surface at z = leaf_thickness

// Left leaf (extends in -X direction)
color("DimGray")
    left_leaf();

// Right leaf (extends in +X direction)  
color("Gray")
    right_leaf();

// Pin
color("Silver")
    pin();
i3 success
iter 3
17.1s · 3047/1635t · $0.0561
diff vs i2: +58/-71
  // Butt Hinge - Furniture Small Size
  // Three parts: Left leaf, Right leaf, Pin
  
  // Parameters
  leaf_length = 30;      // Y direction (along hinge axis)
  leaf_width = 25;       // X direction (opening direction)
  leaf_thickness = 2;    // Z direction
  
  pin_diameter = 4;
  pin_length = 32;
  pin_clearance = 0.3;
  
  knuckle_outer_diameter = 8;
  knuckle_inner_diameter = pin_diameter + pin_clearance;
  knuckle_radius = knuckle_outer_diameter / 2;
  knuckle_height = 6;    // 30mm / 5 = 6mm each
  knuckle_gap = 0.1;     // Small gap between knuckles
  
  // Countersunk hole parameters
  hole_diameter = 3.2;
  countersink_diameter = 6;
  countersink_depth = 1;
  hole_spacing = 8;
  
  $fn = 64;
  
- // Module for countersunk hole
+ // Module for countersunk hole (drilled from top, z+ direction)
  module countersunk_hole() {
-     // Countersink from top surface
-     translate([0, 0, leaf_thickness - countersink_depth])
-         cylinder(h = countersink_depth + 0.01, d1 = hole_diameter, d2 = countersink_diameter);
      // Through hole
      translate([0, 0, -0.01])
          cylinder(h = leaf_thickness + 0.02, d = hole_diameter);
+     // Countersink from top surface
+     translate([0, 0, leaf_thickness - countersink_depth])
+         cylinder(h = countersink_depth + 0.01, d1 = hole_diameter, d2 = countersink_diameter);
  }
  
- // Module for single knuckle cylinder
- module knuckle_cylinder(height) {
-     difference() {
-         cylinder(h = height, d = knuckle_outer_diameter);
-         translate([0, 0, -0.01])
-             cylinder(h = height + 0.02, d = knuckle_inner_diameter);
-     }
+ // Module for single knuckle cylinder (along Y axis)
+ module knuckle_cylinder(y_start, height) {
+     translate([0, y_start, 0])
+         rotate([-90, 0, 0])
+             difference() {
+                 cylinder(h = height, d = knuckle_outer_diameter);
+                 translate([0, 0, -0.01])
+                     cylinder(h = height + 0.02, d = knuckle_inner_diameter);
+             }
  }
  
  // Module for left leaf (3 knuckles at positions 0, 2, 4)
  module left_leaf() {
-     union() {
-         difference() {
-             union() {
-                 // Main plate extending in -X direction
-                 // Plate is positioned so its top surface is at z=0 plane
-                 // and knuckle axis is at z = -knuckle_radius - leaf_thickness/2
-                 translate([-leaf_width + knuckle_radius, 0, 0])
-                     cube([leaf_width, leaf_length, leaf_thickness]);
-             }
+     // In 180° open position, left plate extends in -X direction
+     // Plate flat surface is on Z=0 plane (bottom) to Z=leaf_thickness (top)
+     // Knuckle center axis is at Z = knuckle_radius
+     
+     difference() {
+         union() {
+             // Main plate - extends from x = -leaf_width to x = 0
+             // But knuckle takes some space, so plate edge meets knuckle
+             translate([-leaf_width, 0, 0])
+                 cube([leaf_width, leaf_length, leaf_thickness]);
              
-             // Cut cylinder channel for knuckle area
-             translate([0, -0.01, -knuckle_radius])
-                 rotate([-90, 0, 0])
-                     cylinder(h = leaf_length + 0.02, d = knuckle_outer_diameter);
-             
-             // Countersunk holes - 3 holes centered on the plate away from knuckle
-             for (i = [-1, 0, 1]) {
-                 translate([-leaf_width/2 + knuckle_radius/2, leaf_length/2 + i * hole_spacing, 0])
-                     countersunk_hole();
+             // Knuckles at positions 0, 2, 4 (first, third, fifth)
+             // Y positions: 0-6, 12-18, 24-30
+             translate([0, 0, knuckle_radius])
+             {
+                 knuckle_cylinder(0, knuckle_height - knuckle_gap/2);
+                 knuckle_cylinder(2 * knuckle_height + knuckle_gap/2, knuckle_height - knuckle_gap);
+                 knuckle_cylinder(4 * knuckle_height + knuckle_gap/2, knuckle_height - knuckle_gap/2);
              }
          }
          
-         // Add knuckles at positions 0, 2, 4 (Y = 0, 12, 24)
-         translate([0, 0, -knuckle_radius])
-             rotate([-90, 0, 0]) {
-                 // Knuckle 0
-                 translate([0, 0, 0])
-                     knuckle_cylinder(knuckle_height - knuckle_gap/2);
-                 // Knuckle 2
-                 translate([0, 0, 2 * knuckle_height + knuckle_gap/2])
-                     knuckle_cylinder(knuckle_height - knuckle_gap);
-                 // Knuckle 4
-                 translate([0, 0, 4 * knuckle_height + knuckle_gap/2])
-                     knuckle_cylinder(knuckle_height - knuckle_gap/2);
-             }
+         // Countersunk holes - 3 holes on the plate away from knuckle
+         // Centered horizontally on plate, spaced 8mm vertically
+         for (i = [-1, 0, 1]) {
+             translate([-leaf_width/2, leaf_length/2 + i * hole_spacing, 0])
+                 countersunk_hole();
+         }
      }
  }
  
  // Module for right leaf (2 knuckles at positions 1, 3)
  module right_leaf() {
-     union() {
-         difference() {
-             union() {
-                 // Main plate extending in +X direction
-                 translate([0, 0, 0])
-                     cube([leaf_width, leaf_length, leaf_thickness]);
-             }
+     // In 180° open position, right plate extends in +X direction
+     
+     difference() {
+         union() {
+             // Main plate - extends from x = 0 to x = leaf_width
+             translate([0, 0, 0])
+                 cube([leaf_width, leaf_length, leaf_thickness]);
              
-             // Cut cylinder channel for knuckle area
-             translate([0, -0.01, -knuckle_radius])
-                 rotate([-90, 0, 0])
-                     cylinder(h = leaf_length + 0.02, d = knuckle_outer_diameter);
-             
-             // Countersunk holes
-             for (i = [-1, 0, 1]) {
-                 translate([leaf_width/2 + knuckle_radius/2, leaf_length/2 + i * hole_spacing, 0])
-                     countersunk_hole();
+             // Knuckles at positions 1, 3 (second, fourth)
+             // Y positions: 6-12, 18-24
+             translate([0, 0, knuckle_radius])
+             {
+                 knuckle_cylinder(knuckle_height + knuckle_gap/2, knuckle_height - knuckle_gap);
+                 knuckle_cylinder(3 * knuckle_height + knuckle_gap/2, knuckle_height - knuckle_gap);
              }
          }
          
-         // Add knuckles at positions 1, 3 (Y = 6, 18)
-         translate([0, 0, -knuckle_radius])
-             rotate([-90, 0, 0]) {
-                 // Knuckle 1
-                 translate([0, 0, knuckle_height + knuckle_gap/2])
-                     knuckle_cylinder(knuckle_height - knuckle_gap);
-                 // Knuckle 3
-                 translate([0, 0, 3 * knuckle_height + knuckle_gap/2])
-                     knuckle_cylinder(knuckle_height - knuckle_gap);
-             }
+         // Countersunk holes
+         for (i = [-1, 0, 1]) {
+             translate([leaf_width/2, leaf_length/2 + i * hole_spacing, 0])
+                 countersunk_hole();
+         }
      }
  }
  
  // Module for pin
  module pin() {
+     // Pin axis along Y at X=0, Z=knuckle_radius
      // Pin extends from Y = -1 to Y = 31 (32mm total, 1mm overhang each end)
-     translate([0, -1, -knuckle_radius])
+     translate([0, -1, knuckle_radius])
          rotate([-90, 0, 0])
              cylinder(h = pin_length, d = pin_diameter);
  }
  
  // Assembly - 180° open position
- // Pin axis along Y at x=0, z=-knuckle_radius
- // Both plates have top surface at z = leaf_thickness
+ // Pin axis along Y at X=0, Z=knuckle_radius
+ // Both plates have flat surface at Z=0 to Z=leaf_thickness
  
  // Left leaf (extends in -X direction)
  color("DimGray")
      left_leaf();
  
  // Right leaf (extends in +X direction)  
  color("Gray")
      right_leaf();
  
  // Pin
  color("Silver")
      pin();
SCAD (130 lines)
// Butt Hinge - Furniture Small Size
// Three parts: Left leaf, Right leaf, Pin

// Parameters
leaf_length = 30;      // Y direction (along hinge axis)
leaf_width = 25;       // X direction (opening direction)
leaf_thickness = 2;    // Z direction

pin_diameter = 4;
pin_length = 32;
pin_clearance = 0.3;

knuckle_outer_diameter = 8;
knuckle_inner_diameter = pin_diameter + pin_clearance;
knuckle_radius = knuckle_outer_diameter / 2;
knuckle_height = 6;    // 30mm / 5 = 6mm each
knuckle_gap = 0.1;     // Small gap between knuckles

// Countersunk hole parameters
hole_diameter = 3.2;
countersink_diameter = 6;
countersink_depth = 1;
hole_spacing = 8;

$fn = 64;

// Module for countersunk hole (drilled from top, z+ direction)
module countersunk_hole() {
    // Through hole
    translate([0, 0, -0.01])
        cylinder(h = leaf_thickness + 0.02, d = hole_diameter);
    // Countersink from top surface
    translate([0, 0, leaf_thickness - countersink_depth])
        cylinder(h = countersink_depth + 0.01, d1 = hole_diameter, d2 = countersink_diameter);
}

// Module for single knuckle cylinder (along Y axis)
module knuckle_cylinder(y_start, height) {
    translate([0, y_start, 0])
        rotate([-90, 0, 0])
            difference() {
                cylinder(h = height, d = knuckle_outer_diameter);
                translate([0, 0, -0.01])
                    cylinder(h = height + 0.02, d = knuckle_inner_diameter);
            }
}

// Module for left leaf (3 knuckles at positions 0, 2, 4)
module left_leaf() {
    // In 180° open position, left plate extends in -X direction
    // Plate flat surface is on Z=0 plane (bottom) to Z=leaf_thickness (top)
    // Knuckle center axis is at Z = knuckle_radius
    
    difference() {
        union() {
            // Main plate - extends from x = -leaf_width to x = 0
            // But knuckle takes some space, so plate edge meets knuckle
            translate([-leaf_width, 0, 0])
                cube([leaf_width, leaf_length, leaf_thickness]);
            
            // Knuckles at positions 0, 2, 4 (first, third, fifth)
            // Y positions: 0-6, 12-18, 24-30
            translate([0, 0, knuckle_radius])
            {
                knuckle_cylinder(0, knuckle_height - knuckle_gap/2);
                knuckle_cylinder(2 * knuckle_height + knuckle_gap/2, knuckle_height - knuckle_gap);
                knuckle_cylinder(4 * knuckle_height + knuckle_gap/2, knuckle_height - knuckle_gap/2);
            }
        }
        
        // Countersunk holes - 3 holes on the plate away from knuckle
        // Centered horizontally on plate, spaced 8mm vertically
        for (i = [-1, 0, 1]) {
            translate([-leaf_width/2, leaf_length/2 + i * hole_spacing, 0])
                countersunk_hole();
        }
    }
}

// Module for right leaf (2 knuckles at positions 1, 3)
module right_leaf() {
    // In 180° open position, right plate extends in +X direction
    
    difference() {
        union() {
            // Main plate - extends from x = 0 to x = leaf_width
            translate([0, 0, 0])
                cube([leaf_width, leaf_length, leaf_thickness]);
            
            // Knuckles at positions 1, 3 (second, fourth)
            // Y positions: 6-12, 18-24
            translate([0, 0, knuckle_radius])
            {
                knuckle_cylinder(knuckle_height + knuckle_gap/2, knuckle_height - knuckle_gap);
                knuckle_cylinder(3 * knuckle_height + knuckle_gap/2, knuckle_height - knuckle_gap);
            }
        }
        
        // Countersunk holes
        for (i = [-1, 0, 1]) {
            translate([leaf_width/2, leaf_length/2 + i * hole_spacing, 0])
                countersunk_hole();
        }
    }
}

// Module for pin
module pin() {
    // Pin axis along Y at X=0, Z=knuckle_radius
    // Pin extends from Y = -1 to Y = 31 (32mm total, 1mm overhang each end)
    translate([0, -1, knuckle_radius])
        rotate([-90, 0, 0])
            cylinder(h = pin_length, d = pin_diameter);
}

// Assembly - 180° open position
// Pin axis along Y at X=0, Z=knuckle_radius
// Both plates have flat surface at Z=0 to Z=leaf_thickness

// Left leaf (extends in -X direction)
color("DimGray")
    left_leaf();

// Right leaf (extends in +X direction)  
color("Gray")
    right_leaf();

// Pin
color("Silver")
    pin();