vibe-openscad

tier-3-butt-hinge / qwen/qwen3.5-9b

4 run / 累計 465.7s / 累計 $0

qwen/qwen3.5-9b bare

bare (provider default effort)

run detail →
render
no render
render_error 233.1s · 557/18068t
openscad stl render failed (exit 1): ERROR: Parser error: syntax error in file ../../../../../tmp/render-B6udpI/input.scad, line 13
Can't parse file '/tmp/render-B6udpI/input.scad'!

SCAD (81 lines)
// 家具用小型バット蝶番 (180°開き)
// 3 パーツ構成:左板、右板、ピン軸

module hinge_part_left() {
    // 左板 (鉄板形状:30mm x 25mm x 2mm)
    // 縦 30mm (Y 軸) がピン軸に沿う
    // 横 25mm (X 軸) が回転で開く方向
    // 位置:X < 0 側
    difference() {
        // 本体
        union() {
            // 板
            cube([25, 30, 1], [x: -25..0, y: -15..15, z: -1..1]);
            
            // 筒部 (knuckle) 3 つ (OD 8mm, ID 4.6mm, 長さ 6mm)
            // 縦 30mm を 5 等分 (各 6mm)
            // 左板は外側 2 個 + 中央 1 個 (Y: -15..-9, -3..3, 9..15)
            for (y = [-15, -3, 9]) {
                cylinder(h = 6, r = 4, center = [x: 0, y: y + 3, z: 0]);
            }
        }
        
        // M3 皿穴 3 つ
        // 位置:X = -25mm (板の端), Y = -12, -4, 4mm
        for (y = [-12, -4, 4]) {
            // 皿穴:表面から直径 6mm x 深さ 1mm テーパ + 直径 3.2mm 貫通穴
            // Z = 0 中心,板厚 2mm
            difference() {
                // テーパ穴
                cylinder(h = 1, r1 = 3, r2 = 1.6, center = [x: -25, y: y, z: 0.5], $fn = 32);
                // 貫通穴
                cylinder(h = 2, r = 1.6, center = [x: -25, y: y, z: 0]);
            }
        }
    }
}

module hinge_part_right() {
    // 右板 (鉄板形状:30mm x 25mm x 2mm)
    // 位置:X > 0 側
    difference() {
        // 本体
        union() {
            // 板
            cube([25, 30, 1], [x: 0..25, y: -15..15, z: -1..1]);
            
            // 筒部 (knuckle) 2 つ (OD 8mm, ID 4.6mm, 長さ 6mm)
            // 右板は中間 2 個 (Y: -9..-3, 3..9)
            for (y = [-9, 3]) {
                cylinder(h = 6, r = 4, center = [x: 0, y: y + 3, z: 0]);
            }
        }
        
        // M3 皿穴 3 つ
        // 位置:X = 25mm (板の端), Y = -12, -4, 4mm
        for (y = [-12, -4, 4]) {
            // 皿穴
            difference() {
                // テーパ穴
                cylinder(h = 1, r1 = 3, r2 = 1.6, center = [x: 25, y: y, z: 0.5], $fn = 32);
                // 貫通穴
                cylinder(h = 2, r = 1.6, center = [x: 25, y: y, z: 0]);
            }
        }
    }
}

module hinge_pin() {
    // ピン軸 (直径 4mm, 長さ 32mm)
    // 両端 1mm ずつ knuckle から飛び出す
    // knuckle 全体 30mm (-15..15) なので、ピンは -16..16
    cylinder(h = 32, r = 2, center = [x: 0, y: 0, z: 0]);
}

difference() {
    union() {
        hinge_part_left();
        hinge_part_right();
        hinge_pin();
    }
}

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 ... ``` のフェンスで囲んで出力してください。
コードのみで、追加の説明は不要です。

iteration: iter-png

i1 success →
iter 1
23.1s · 1730/2385t
diff vs bare: +28/-16
  // 家具用小型バット蝶番 (180°開き)
  // 3 パーツ構成:左板、右板、ピン軸
  
  module hinge_part_left() {
      // 左板 (鉄板形状:30mm x 25mm x 2mm)
      // 縦 30mm (Y 軸) がピン軸に沿う
      // 横 25mm (X 軸) が回転で開く方向
      // 位置:X < 0 側
      difference() {
          // 本体
          union() {
-             // 板
-             cube([25, 30, 1], [x: -25..0, y: -15..15, z: -1..1]);
+             // 板 - translate して配置
+             translate([-25, 0, 0]) {
+                 cube([25, 30, 2], center = [0, 0, 0]);
+             }
              
              // 筒部 (knuckle) 3 つ (OD 8mm, ID 4.6mm, 長さ 6mm)
              // 縦 30mm を 5 等分 (各 6mm)
              // 左板は外側 2 個 + 中央 1 個 (Y: -15..-9, -3..3, 9..15)
              for (y = [-15, -3, 9]) {
-                 cylinder(h = 6, r = 4, center = [x: 0, y: y + 3, z: 0]);
+                 translate([0, y + 3, 0]) {
+                     cylinder(h = 6, r = 4);
+                 }
              }
          }
          
          // M3 皿穴 3 つ
          // 位置:X = -25mm (板の端), Y = -12, -4, 4mm
          for (y = [-12, -4, 4]) {
              // 皿穴:表面から直径 6mm x 深さ 1mm テーパ + 直径 3.2mm 貫通穴
              // Z = 0 中心,板厚 2mm
-             difference() {
-                 // テーパ穴
-                 cylinder(h = 1, r1 = 3, r2 = 1.6, center = [x: -25, y: y, z: 0.5], $fn = 32);
-                 // 貫通穴
-                 cylinder(h = 2, r = 1.6, center = [x: -25, y: y, z: 0]);
+             translate([-25, y, 0]) {
+                 difference() {
+                     // テーパ穴
+                     cylinder(h = 1, r1 = 3, r2 = 1.6, $fn = 32);
+                     // 貫通穴
+                     cylinder(h = 2, r = 1.6);
+                 }
              }
          }
      }
  }
  
  module hinge_part_right() {
      // 右板 (鉄板形状:30mm x 25mm x 2mm)
      // 位置:X > 0 側
      difference() {
          // 本体
          union() {
              // 板
-             cube([25, 30, 1], [x: 0..25, y: -15..15, z: -1..1]);
+             translate([25, 0, 0]) {
+                 cube([25, 30, 2], center = [0, 0, 0]);
+             }
              
              // 筒部 (knuckle) 2 つ (OD 8mm, ID 4.6mm, 長さ 6mm)
              // 右板は中間 2 個 (Y: -9..-3, 3..9)
              for (y = [-9, 3]) {
-                 cylinder(h = 6, r = 4, center = [x: 0, y: y + 3, z: 0]);
+                 translate([0, y + 3, 0]) {
+                     cylinder(h = 6, r = 4);
+                 }
              }
          }
          
          // M3 皿穴 3 つ
          // 位置:X = 25mm (板の端), Y = -12, -4, 4mm
          for (y = [-12, -4, 4]) {
              // 皿穴
-             difference() {
-                 // テーパ穴
-                 cylinder(h = 1, r1 = 3, r2 = 1.6, center = [x: 25, y: y, z: 0.5], $fn = 32);
-                 // 貫通穴
-                 cylinder(h = 2, r = 1.6, center = [x: 25, y: y, z: 0]);
+             translate([25, y, 0]) {
+                 difference() {
+                     // テーパ穴
+                     cylinder(h = 1, r1 = 3, r2 = 1.6, $fn = 32);
+                     // 貫通穴
+                     cylinder(h = 2, r = 1.6);
+                 }
              }
          }
      }
  }
  
  module hinge_pin() {
      // ピン軸 (直径 4mm, 長さ 32mm)
      // 両端 1mm ずつ knuckle から飛び出す
      // knuckle 全体 30mm (-15..15) なので、ピンは -16..16
-     cylinder(h = 32, r = 2, center = [x: 0, y: 0, z: 0]);
+     cylinder(h = 32, r = 2, center = [0, 0, 0]);
  }
  
  difference() {
      union() {
          hinge_part_left();
          hinge_part_right();
          hinge_pin();
      }
  }
SCAD (93 lines)
// 家具用小型バット蝶番 (180°開き)
// 3 パーツ構成:左板、右板、ピン軸

module hinge_part_left() {
    // 左板 (鉄板形状:30mm x 25mm x 2mm)
    // 縦 30mm (Y 軸) がピン軸に沿う
    // 横 25mm (X 軸) が回転で開く方向
    // 位置:X < 0 側
    difference() {
        // 本体
        union() {
            // 板 - translate して配置
            translate([-25, 0, 0]) {
                cube([25, 30, 2], center = [0, 0, 0]);
            }
            
            // 筒部 (knuckle) 3 つ (OD 8mm, ID 4.6mm, 長さ 6mm)
            // 縦 30mm を 5 等分 (各 6mm)
            // 左板は外側 2 個 + 中央 1 個 (Y: -15..-9, -3..3, 9..15)
            for (y = [-15, -3, 9]) {
                translate([0, y + 3, 0]) {
                    cylinder(h = 6, r = 4);
                }
            }
        }
        
        // M3 皿穴 3 つ
        // 位置:X = -25mm (板の端), Y = -12, -4, 4mm
        for (y = [-12, -4, 4]) {
            // 皿穴:表面から直径 6mm x 深さ 1mm テーパ + 直径 3.2mm 貫通穴
            // Z = 0 中心,板厚 2mm
            translate([-25, y, 0]) {
                difference() {
                    // テーパ穴
                    cylinder(h = 1, r1 = 3, r2 = 1.6, $fn = 32);
                    // 貫通穴
                    cylinder(h = 2, r = 1.6);
                }
            }
        }
    }
}

module hinge_part_right() {
    // 右板 (鉄板形状:30mm x 25mm x 2mm)
    // 位置:X > 0 側
    difference() {
        // 本体
        union() {
            // 板
            translate([25, 0, 0]) {
                cube([25, 30, 2], center = [0, 0, 0]);
            }
            
            // 筒部 (knuckle) 2 つ (OD 8mm, ID 4.6mm, 長さ 6mm)
            // 右板は中間 2 個 (Y: -9..-3, 3..9)
            for (y = [-9, 3]) {
                translate([0, y + 3, 0]) {
                    cylinder(h = 6, r = 4);
                }
            }
        }
        
        // M3 皿穴 3 つ
        // 位置:X = 25mm (板の端), Y = -12, -4, 4mm
        for (y = [-12, -4, 4]) {
            // 皿穴
            translate([25, y, 0]) {
                difference() {
                    // テーパ穴
                    cylinder(h = 1, r1 = 3, r2 = 1.6, $fn = 32);
                    // 貫通穴
                    cylinder(h = 2, r = 1.6);
                }
            }
        }
    }
}

module hinge_pin() {
    // ピン軸 (直径 4mm, 長さ 32mm)
    // 両端 1mm ずつ knuckle から飛び出す
    // knuckle 全体 30mm (-15..15) なので、ピンは -16..16
    cylinder(h = 32, r = 2, center = [0, 0, 0]);
}

difference() {
    union() {
        hinge_part_left();
        hinge_part_right();
        hinge_pin();
    }
}
i2 success →
iter 2
100.3s · 2140/10984t
diff vs i1: +24/-27
  // 家具用小型バット蝶番 (180°開き)
  // 3 パーツ構成:左板、右板、ピン軸
  
  module hinge_part_left() {
      // 左板 (鉄板形状:30mm x 25mm x 2mm)
      // 縦 30mm (Y 軸) がピン軸に沿う
      // 横 25mm (X 軸) が回転で開く方向
      // 位置:X < 0 側
      difference() {
          // 本体
-         union() {
-             // 板 - translate して配置
-             translate([-25, 0, 0]) {
-                 cube([25, 30, 2], center = [0, 0, 0]);
+         translate([-25, 0, 0]) {
+             cube([25, 30, 2], center = [0, 0, 0]);
+         }
+         
+         // 筒部 (knuckle) 3 つ (OD 8mm, ID 4.6mm, 厚さ 2mm)
+         // 縦 30mm を 5 等分 (各 6mm)
+         // 左板は外側 2 個 + 中央 1 個 (Y: -15..-9, -3..3, 9..15)
+         // 筒部は板の端 (X=-25) に配置
+         for (y = [-15, -3, 9]) {
+             translate([-25, y + 3, 0]) {
+                 cylinder(r = 4, h = 2);
              }
-             
-             // 筒部 (knuckle) 3 つ (OD 8mm, ID 4.6mm, 長さ 6mm)
-             // 縦 30mm を 5 等分 (各 6mm)
-             // 左板は外側 2 個 + 中央 1 個 (Y: -15..-9, -3..3, 9..15)
-             for (y = [-15, -3, 9]) {
-                 translate([0, y + 3, 0]) {
-                     cylinder(h = 6, r = 4);
-                 }
-             }
          }
          
          // M3 皿穴 3 つ
-         // 位置:X = -25mm (板の端), Y = -12, -4, 4mm
+         // 位置:板の端 (X = -25mm), Y = -12, -4, 4mm
          for (y = [-12, -4, 4]) {
              // 皿穴:表面から直径 6mm x 深さ 1mm テーパ + 直径 3.2mm 貫通穴
              // Z = 0 中心,板厚 2mm
              translate([-25, y, 0]) {
                  difference() {
                      // テーパ穴
                      cylinder(h = 1, r1 = 3, r2 = 1.6, $fn = 32);
                      // 貫通穴
                      cylinder(h = 2, r = 1.6);
                  }
              }
          }
      }
  }
  
  module hinge_part_right() {
      // 右板 (鉄板形状:30mm x 25mm x 2mm)
      // 位置:X > 0 側
      difference() {
          // 本体
-         union() {
-             // 板
-             translate([25, 0, 0]) {
-                 cube([25, 30, 2], center = [0, 0, 0]);
+         translate([25, 0, 0]) {
+             cube([25, 30, 2], center = [0, 0, 0]);
+         }
+         
+         // 筒部 (knuckle) 2 つ (OD 8mm, ID 4.6mm, 厚さ 2mm)
+         // 縦 30mm を 5 等分 (各 6mm)
+         // 右板は中間 2 個 (Y: -9..-3, 3..9)
+         // 筒部は板の端 (X=25) に配置
+         for (y = [-9, 3]) {
+             translate([25, y + 3, 0]) {
+                 cylinder(r = 4, h = 2);
              }
-             
-             // 筒部 (knuckle) 2 つ (OD 8mm, ID 4.6mm, 長さ 6mm)
-             // 右板は中間 2 個 (Y: -9..-3, 3..9)
-             for (y = [-9, 3]) {
-                 translate([0, y + 3, 0]) {
-                     cylinder(h = 6, r = 4);
-                 }
-             }
          }
          
          // M3 皿穴 3 つ
-         // 位置:X = 25mm (板の端), Y = -12, -4, 4mm
+         // 位置:板の端 (X = 25mm), Y = -12, -4, 4mm
          for (y = [-12, -4, 4]) {
              // 皿穴
              translate([25, y, 0]) {
                  difference() {
                      // テーパ穴
                      cylinder(h = 1, r1 = 3, r2 = 1.6, $fn = 32);
                      // 貫通穴
                      cylinder(h = 2, r = 1.6);
                  }
              }
          }
      }
  }
  
  module hinge_pin() {
      // ピン軸 (直径 4mm, 長さ 32mm)
      // 両端 1mm ずつ knuckle から飛び出す
      // knuckle 全体 30mm (-15..15) なので、ピンは -16..16
      cylinder(h = 32, r = 2, center = [0, 0, 0]);
  }
  
  difference() {
      union() {
          hinge_part_left();
          hinge_part_right();
          hinge_pin();
      }
  }
SCAD (90 lines)
// 家具用小型バット蝶番 (180°開き)
// 3 パーツ構成:左板、右板、ピン軸

module hinge_part_left() {
    // 左板 (鉄板形状:30mm x 25mm x 2mm)
    // 縦 30mm (Y 軸) がピン軸に沿う
    // 横 25mm (X 軸) が回転で開く方向
    // 位置:X < 0 側
    difference() {
        // 本体
        translate([-25, 0, 0]) {
            cube([25, 30, 2], center = [0, 0, 0]);
        }
        
        // 筒部 (knuckle) 3 つ (OD 8mm, ID 4.6mm, 厚さ 2mm)
        // 縦 30mm を 5 等分 (各 6mm)
        // 左板は外側 2 個 + 中央 1 個 (Y: -15..-9, -3..3, 9..15)
        // 筒部は板の端 (X=-25) に配置
        for (y = [-15, -3, 9]) {
            translate([-25, y + 3, 0]) {
                cylinder(r = 4, h = 2);
            }
        }
        
        // M3 皿穴 3 つ
        // 位置:板の端 (X = -25mm), Y = -12, -4, 4mm
        for (y = [-12, -4, 4]) {
            // 皿穴:表面から直径 6mm x 深さ 1mm テーパ + 直径 3.2mm 貫通穴
            // Z = 0 中心,板厚 2mm
            translate([-25, y, 0]) {
                difference() {
                    // テーパ穴
                    cylinder(h = 1, r1 = 3, r2 = 1.6, $fn = 32);
                    // 貫通穴
                    cylinder(h = 2, r = 1.6);
                }
            }
        }
    }
}

module hinge_part_right() {
    // 右板 (鉄板形状:30mm x 25mm x 2mm)
    // 位置:X > 0 側
    difference() {
        // 本体
        translate([25, 0, 0]) {
            cube([25, 30, 2], center = [0, 0, 0]);
        }
        
        // 筒部 (knuckle) 2 つ (OD 8mm, ID 4.6mm, 厚さ 2mm)
        // 縦 30mm を 5 等分 (各 6mm)
        // 右板は中間 2 個 (Y: -9..-3, 3..9)
        // 筒部は板の端 (X=25) に配置
        for (y = [-9, 3]) {
            translate([25, y + 3, 0]) {
                cylinder(r = 4, h = 2);
            }
        }
        
        // M3 皿穴 3 つ
        // 位置:板の端 (X = 25mm), Y = -12, -4, 4mm
        for (y = [-12, -4, 4]) {
            // 皿穴
            translate([25, y, 0]) {
                difference() {
                    // テーパ穴
                    cylinder(h = 1, r1 = 3, r2 = 1.6, $fn = 32);
                    // 貫通穴
                    cylinder(h = 2, r = 1.6);
                }
            }
        }
    }
}

module hinge_pin() {
    // ピン軸 (直径 4mm, 長さ 32mm)
    // 両端 1mm ずつ knuckle から飛び出す
    // knuckle 全体 30mm (-15..15) なので、ピンは -16..16
    cylinder(h = 32, r = 2, center = [0, 0, 0]);
}

difference() {
    union() {
        hinge_part_left();
        hinge_part_right();
        hinge_pin();
    }
}
i3 success →
iter 3
109.2s · 2170/12048t
diff vs i2: +59/-53
  // 家具用小型バット蝶番 (180°開き)
  // 3 パーツ構成:左板、右板、ピン軸
  
- module hinge_part_left() {
-     // 左板 (鉄板形状:30mm x 25mm x 2mm)
-     // 縦 30mm (Y 軸) がピン軸に沿う
-     // 横 25mm (X 軸) が回転で開く方向
-     // 位置:X < 0 側
+ // 共通モジュール:筒部 (knuckle)
+ // Y 軸位置を引数に受け取り、ピン軸位置 (X=0) に配置
+ module knuckle(y_pos) {
+     // 筒部は板の厚さ (2mm) に沿う
+     // 外径 8mm, 内径 4.6mm (半径 2.3mm)
+     // 位置:X=0 (軸心)
      difference() {
-         // 本体
-         translate([-25, 0, 0]) {
-             cube([25, 30, 2], center = [0, 0, 0]);
+         union() {
+             // 筒部本体
+             translate([0, y_pos, 0]) cylinder(h = 2, r = 4);
          }
+         // ピン穴 (半径 2.3mm)
+         translate([0, y_pos, 0]) cylinder(h = 2, r = 2.3);
+     }
+ }
+ 
+ module hinge_part_left() {
+     // 左板
+     // 板厚 2mm (Z 軸), 縦 30mm (Y 軸), 横 25mm (X 軸)
+     // 位置:X < 0 側 (ピン軸中心から左へ 25mm)
+     // 板の中心:X = -12.5, Y = 0
+     difference() {
+         // 板本体
+         translate([-12.5, 0, 0]) cube([25, 30, 2]);
          
-         // 筒部 (knuckle) 3 つ (OD 8mm, ID 4.6mm, 厚さ 2mm)
-         // 縦 30mm を 5 等分 (各 6mm)
-         // 左板は外側 2 個 + 中央 1 個 (Y: -15..-9, -3..3, 9..15)
-         // 筒部は板の端 (X=-25) に配置
-         for (y = [-15, -3, 9]) {
-             translate([-25, y + 3, 0]) {
-                 cylinder(r = 4, h = 2);
-             }
+         // 筒部 (knuckle) 3 つ
+         // 左板:外側 2 個 + 中央 1 個
+         // Y 軸 30mm (中心 0) -> 範囲 -15 ~ 15
+         // 5 等分 (各 6mm) -> 位置 -12, -6, 0, 6, 12
+         // 左板の筒部:-12, 0, 12
+         for (y = [-12, 0, 12]) {
+             knuckle(y);
          }
          
          // M3 皿穴 3 つ
-         // 位置:板の端 (X = -25mm), Y = -12, -4, 4mm
-         for (y = [-12, -4, 4]) {
+         // 位置:板の端 (X = -25mm)
+         // Y 軸方向ピッチ 8mm
+         // 中心対称配置 (板の中心 Y=0) -> Y = -8, 0, 8
+         for (y = [-8, 0, 8]) {
              // 皿穴:表面から直径 6mm x 深さ 1mm テーパ + 直径 3.2mm 貫通穴
-             // Z = 0 中心,板厚 2mm
              translate([-25, y, 0]) {
                  difference() {
-                     // テーパ穴
-                     cylinder(h = 1, r1 = 3, r2 = 1.6, $fn = 32);
-                     // 貫通穴
+                     cylinder(h = 1, r = 3, r2 = 1.6, $fn = 32);
                      cylinder(h = 2, r = 1.6);
                  }
              }
          }
      }
  }
  
  module hinge_part_right() {
-     // 右板 (鉄板形状:30mm x 25mm x 2mm)
-     // 位置:X > 0 側
+     // 右板
+     // 板厚 2mm, 縦 30mm, 横 25mm
+     // 位置:X > 0 側 (ピン軸中心から右へ 25mm)
+     // 板の中心:X = 12.5, Y = 0
      difference() {
-         // 本体
-         translate([25, 0, 0]) {
-             cube([25, 30, 2], center = [0, 0, 0]);
-         }
+         // 板本体
+         translate([12.5, 0, 0]) cube([25, 30, 2]);
          
-         // 筒部 (knuckle) 2 つ (OD 8mm, ID 4.6mm, 厚さ 2mm)
-         // 縦 30mm を 5 等分 (各 6mm)
-         // 右板は中間 2 個 (Y: -9..-3, 3..9)
-         // 筒部は板の端 (X=25) に配置
-         for (y = [-9, 3]) {
-             translate([25, y + 3, 0]) {
-                 cylinder(r = 4, h = 2);
-             }
+         // 筒部 (knuckle) 2 つ
+         // 右板:中間 2 個
+         // Y 軸位置:-6, 6
+         for (y = [-6, 6]) {
+             knuckle(y);
          }
          
-         // M3 皿穴 3 つ
-         // 位置:板の端 (X = 25mm), Y = -12, -4, 4mm
-         for (y = [-12, -4, 4]) {
-             // 皿穴
+         // M3 皿穴 3 つ (右板にも 3 つの穴が必要)
+         // 位置:板の端 (X = 25mm)
+         // Y 軸方向ピッチ 8mm
+         // 中心対称配置
+         for (y = [-8, 0, 8]) {
              translate([25, y, 0]) {
                  difference() {
-                     // テーパ穴
-                     cylinder(h = 1, r1 = 3, r2 = 1.6, $fn = 32);
-                     // 貫通穴
+                     cylinder(h = 1, r = 3, r2 = 1.6, $fn = 32);
                      cylinder(h = 2, r = 1.6);
                  }
              }
          }
      }
  }
  
  module hinge_pin() {
-     // ピン軸 (直径 4mm, 長さ 32mm)
-     // 両端 1mm ずつ knuckle から飛び出す
-     // knuckle 全体 30mm (-15..15) なので、ピンは -16..16
-     cylinder(h = 32, r = 2, center = [0, 0, 0]);
+     // ピン軸
+     // 直径 4mm, 長さ 32mm
+     // 両端 1mm ずつ筒部から飛び出す (筒部範囲 -12~12, ピン -16~16)
+     translate([0, 0, 0]) cylinder(h = 32, r = 2);
  }
  
- difference() {
-     union() {
-         hinge_part_left();
-         hinge_part_right();
-         hinge_pin();
-     }
+ union() {
+     hinge_part_left();
+     hinge_part_right();
+     hinge_pin();
  }
SCAD (96 lines)
// 家具用小型バット蝶番 (180°開き)
// 3 パーツ構成:左板、右板、ピン軸

// 共通モジュール:筒部 (knuckle)
// Y 軸位置を引数に受け取り、ピン軸位置 (X=0) に配置
module knuckle(y_pos) {
    // 筒部は板の厚さ (2mm) に沿う
    // 外径 8mm, 内径 4.6mm (半径 2.3mm)
    // 位置:X=0 (軸心)
    difference() {
        union() {
            // 筒部本体
            translate([0, y_pos, 0]) cylinder(h = 2, r = 4);
        }
        // ピン穴 (半径 2.3mm)
        translate([0, y_pos, 0]) cylinder(h = 2, r = 2.3);
    }
}

module hinge_part_left() {
    // 左板
    // 板厚 2mm (Z 軸), 縦 30mm (Y 軸), 横 25mm (X 軸)
    // 位置:X < 0 側 (ピン軸中心から左へ 25mm)
    // 板の中心:X = -12.5, Y = 0
    difference() {
        // 板本体
        translate([-12.5, 0, 0]) cube([25, 30, 2]);
        
        // 筒部 (knuckle) 3 つ
        // 左板:外側 2 個 + 中央 1 個
        // Y 軸 30mm (中心 0) -> 範囲 -15 ~ 15
        // 5 等分 (各 6mm) -> 位置 -12, -6, 0, 6, 12
        // 左板の筒部:-12, 0, 12
        for (y = [-12, 0, 12]) {
            knuckle(y);
        }
        
        // M3 皿穴 3 つ
        // 位置:板の端 (X = -25mm)
        // Y 軸方向ピッチ 8mm
        // 中心対称配置 (板の中心 Y=0) -> Y = -8, 0, 8
        for (y = [-8, 0, 8]) {
            // 皿穴:表面から直径 6mm x 深さ 1mm テーパ + 直径 3.2mm 貫通穴
            translate([-25, y, 0]) {
                difference() {
                    cylinder(h = 1, r = 3, r2 = 1.6, $fn = 32);
                    cylinder(h = 2, r = 1.6);
                }
            }
        }
    }
}

module hinge_part_right() {
    // 右板
    // 板厚 2mm, 縦 30mm, 横 25mm
    // 位置:X > 0 側 (ピン軸中心から右へ 25mm)
    // 板の中心:X = 12.5, Y = 0
    difference() {
        // 板本体
        translate([12.5, 0, 0]) cube([25, 30, 2]);
        
        // 筒部 (knuckle) 2 つ
        // 右板:中間 2 個
        // Y 軸位置:-6, 6
        for (y = [-6, 6]) {
            knuckle(y);
        }
        
        // M3 皿穴 3 つ (右板にも 3 つの穴が必要)
        // 位置:板の端 (X = 25mm)
        // Y 軸方向ピッチ 8mm
        // 中心対称配置
        for (y = [-8, 0, 8]) {
            translate([25, y, 0]) {
                difference() {
                    cylinder(h = 1, r = 3, r2 = 1.6, $fn = 32);
                    cylinder(h = 2, r = 1.6);
                }
            }
        }
    }
}

module hinge_pin() {
    // ピン軸
    // 直径 4mm, 長さ 32mm
    // 両端 1mm ずつ筒部から飛び出す (筒部範囲 -12~12, ピン -16~16)
    translate([0, 0, 0]) cylinder(h = 32, r = 2);
}

union() {
    hinge_part_left();
    hinge_part_right();
    hinge_pin();
}