PythonSCADコミュニティ・開発者に感謝申し上げます。ありがとうございます。
以下は、開発者からアドバイスを受けて修正した custom_minicar.py のコードです。PythonSCADならではの「より短く、より直感的に書ける」便利な書き方がたくさん取り入れられています。
高校生の皆さんにも分かりやすいように、変更された4つの重要なポイント(移動、回転、結合、複数配置)について順番に解説していきます。
from pythonscad import *
#--- パラメータ設定 (単位: mm) ---
##座標系の約束:
#X軸=前後(進行方向) / Y軸=左右(車幅方向) / Z軸=上下
#ボディ(下の直方体)
body_x = 60 # 長さ(X方向)
body_y = 20 # 幅(Y方向)
body_z = 10 # 高さ(Z方向)
#キャビン(上の直方体)
cabin_x = 30 # 長さ(X方向)
cabin_y = 20 # 幅(Y方向)
cabin_z = 10 # 高さ(Z方向)
cabin_offset_x = -10 # 「少し後ろ寄り」(Xマイナス方向にずらす)
#タイヤ(円柱)
wheel_r = 8 # 半径
wheel_thick = 3 # 厚さ(円柱の長さ)
wheel_pos_x = 20 # 前後位置(±)
wheel_pos_y = 15 # 左右位置(±)
wheel_pos_z = -body_z / 2 # 取り付け高さ(今回はボディ中心より下側に配置するイメージ)
#車軸(円柱)
axle_r = 2
axle_len = 30 # 車軸の長さ(Y方向に貫通させる)
axle_pos_z = wheel_pos_z # タイヤ中心と同じ高さにする
#表示品質など
fn_val = 80 # 円柱の滑らかさ
eps = 0.1 # 面のチラつき防止用(今回は予備として)
#--- 関数(モジュール)定義 ---
def make_body():
# 土台ボディ(直方体):center=True で原点中心に作る
return cube([body_x, body_y, body_z], center=True)
def make_cabin():
# キャビン(直方体)を上に載せる
cabin = cube([cabin_x, cabin_y, cabin_z], center=True)
# ボディ上面に接する高さへ移動(Z方向)
z_up = body_z / 2 + cabin_z / 2
# 少し後ろ寄りに移動(X方向マイナス)
return cabin + [cabin_offset_x, 0, z_up]
def make_wheel():
# wheel は回転軸が「Y軸」になるように作る(円柱はデフォルトZ方向に伸びるため回転させる)
cyl = cylinder(h=wheel_thick, r=wheel_r, center=True, fn=fn_val)
wheel = cyl.rotx(90) # Z軸方向の円柱 → Y軸方向の円柱
return wheel
def make_axle():
# 車軸も Y軸方向へ(円柱を倒す)
cyl = cylinder(h=axle_len, r=axle_r, center=True, fn=fn_val)
axle = cyl.rotx(90) # Z軸方向 → Y軸方向
return axle
#--- メイン処理 ---
#1) ボディ(下)
car = make_body()
#2) キャビン(上)
car = car | make_cabin()
show(car)
#3) タイヤ4つ(前後左右)
wheel_proto = make_wheel()
wheel_positions = [
[+wheel_pos_x, +wheel_pos_y, wheel_pos_z],
[+wheel_pos_x, -wheel_pos_y, wheel_pos_z],
[-wheel_pos_x, +wheel_pos_y, wheel_pos_z],
[-wheel_pos_x, -wheel_pos_y, wheel_pos_z],
]
#wheels = wheel_proto + wheel_positions
#or
wheels = wheel_proto ^ [[wheel_pos_x, -wheel_pos_x], [wheel_pos_y,-wheel_pos_y], wheel_pos_z]
show(wheels)
#4) 車軸2本(前後)
axle_proto = make_axle()
show( axle_proto ^ [[wheel_pos_x,-wheel_pos_x],0,axle_pos_z] )
1. 移動の書き方:translate から + リストへ
-
元のコード:
translate(cabin, [cabin_offset_x, 0, z_up])と関数を使っていました。 -
新しいコード:
cabin + [cabin_offset_x, 0, z_up]と書いています。
【解説】
PythonSCADでは、3Dオブジェクト(形)に対して [X, Y, Z] のような「座標のリスト」を +(足し算)すると、それが自動的に「移動」として扱われます。関数名をわざわざ書かなくても、「元の形 + ずらす量」という感覚で、より直感的でスッキリとしたプログラムになります。
2. 回転の書き方:rotate から .rotx() へ
-
元のコード:
rotate(cyl, [90, 0, 0])のように、X, Y, Zのすべての角度をリストで指定していました。 -
新しいコード:
cyl.rotx(90)となっています。
【解説】
これはPythonの「オブジェクト指向」という仕組みを活用した書き方です。「円柱(cyl)に対して、X軸を中心に90度回転(rotx)して!」と直接命令しています。X軸を回したいのか、Y軸を回したいのかが一目で分かるようになり、入力ミスも減らすことができます。
3. 図形の結合(和集合):+ から | へ
-
元のコード:
car = car + make_cabin()のように+記号で図形同士を合体していました。 -
新しいコード:
car | make_cabin()となっています。
【解説】
プログラミング(数学の集合演算)において、|(パイプ記号と呼ばれる縦線)は「和集合(どちらも含む)」を表す記号としてよく使われます。1番で解説したように + を「移動」として使うようになったため、図形同士の「結合」には | を使うことで、コードの中で「移動」と「結合」の意味をはっきりと区別できるようになっています。
4. 複数配置の魔法の演算子:for 文から ^ へ
-
元のコード:4つのタイヤの座標リストを作り、
for文の繰り返し処理を使って1つずつ移動・合体させるという、少し長い処理を書いていました。 -
新しいコード:
wheel_proto ^ [[wheel_pos_x, -wheel_pos_x], [wheel_pos_y,-wheel_pos_y], wheel_pos_z]と、なんと1行で書いています。
【解説】
この ^ 記号は、PythonSCADにおける「指定した組み合わせすべてにコピーを配置する」という非常に強力な機能です。
上記のコードでは、X座標のリスト(前後)とY座標のリスト(左右)を渡しています。するとプログラムが自動的に「前の右、前の左、後ろの右、後ろの左」という全パターンの組み合わせを計算し、一気に4箇所にタイヤを配置してくれます。同様に車軸も axle_proto ^ [[wheel_pos_x,-wheel_pos_x],0,axle_pos_z] と書くことで、前後の2箇所へ一瞬で配置しています。
PythonSCADにおいて,、^ 演算子は「XOR(排他的論理和)」ではない
別の記事での説明と内容が食い違ってしまい訂正します。申し訳ございません。
PythonSCADにおいて ^ 演算子は「XOR(排他的論理和)」ではありません。「配列コピー(スタンプ一括配置)」の機能です。
以前書いた説明は、残念ながら「通常のPythonの文法」と「PythonSCAD特有の機能」が混ざってしまった誤った情報です。
通常のPythonプログラミング(数学やデータ処理)では、^ 記号は確かに「XOR(排他的論理和)」を意味します。
しかし、PythonSCADの開発者は、3Dモデリングで頻繁に行う「複数パーツの規則的な配置」を極限まで短く書けるようにするため、この ^ 記号を「座標リストへの一括スタンプ演算子」として特別に改造(オーバーロード)しています。
そのため、PythonSCAD上で part1 ^ part2 のように図形同士を ^ で計算しようとすると、プログラムが「右側は座標のリストじゃないぞ?」と困ってしまい、エラーになります。
^ 演算子(一括スタンプ機能)の正しいまとめ
^ 演算子は、「左側の形」を「右側の座標の組み合わせ」すべてに一気にコピーして配置する機能です。
【基本の書き方】
配置した図形 = 元のパーツ ^ [X座標のリスト, Y座標のリスト, Z座標のリスト]
【覚えておくべき3つのルール】
-
全パターンの組み合わせを作る:
Xに[10, -10]、Yに[20, -20]を渡すと、「(10, 20), (10, -20), (-10, 20), (-10, -20)」の 2×2=4箇所 に自動でスタンプされます。 -
固定したい軸には単一の数字(スカラー値)を渡す:
「Z軸は高さ0のまま変えたくない」という場合は、リスト[0]ではなく、単に0と書くことができます。
例:パーツ ^ [xのリスト, yのリスト, 0] -
リストは直接書いても、変数で渡してもOK:
あらかじめx_list = [0, 10, 20]と変数を作っておき、パーツ ^ [x_list, y_list, 0]と書くのが、プログラムが読みやすくなるコツです。
【おまけ】 もし本当に「XOR(重なっていない部分)」を作りたい時は?
3D CADの世界では、XORにあたる専用の記号は用意されていないことがほとんどです。しかし、私たちが学んできた +(結合) と -(削る) を組み合わせれば、論理的なパズルとして自分で作り出すことができます!
「AとBの重なっていない部分だけを残す」には、以下のように考えます。
-
A から B を削る (
A - B:Aだけにある部分) -
B から A を削る (
B - A:Bだけにある部分) -
その2つを合体させる (
+演算子)
# XOR(排他的論理和)の形状を自作する式
xor_shape = (partA - partB) + (partB - partA)
「XOR(重なっていない部分)」

renderボタンで、2D図形(厚みなし)は赤い線がでます。
from pythonscad import *
partA=circle(r=3,fn=28).show()
partB=(circle(r=3,fn=28)+[4,0,0]).show()
xor_shape = (partA - partB) + (partB - partA)
(xor_shape +[0,-7,0]).show()
球体で、上記のことをやっても、見た目は変わりません。空洞になっているかどうかは、ちょっとだけ移動してみてのぞいてみてください。
^ 演算子を使った規則的な配置例
この ^ 演算子は、PythonSCADの中でもトップクラスに便利で強力な機能です。cube(直方体)を綺麗に並べて、レゴブロックの土台やビル群のような「グリッド配置(格子状の配置)」を作るのにも大活躍します。
今回は、3×3の合計9個の cube を等間隔に配置するサンプルコードを作成しました。さっそく見てみましょう!
1. 完成コード(PythonSCAD)
# ==========================================
# [3×3のブロックアート(cubeの規則配置)]
# 作成日: 2026/07/30
# ==========================================
from pythonscad import *
# --- パラメータ設定 (単位: mm) ---
# 座標系の約束: X軸=前後(長さ) / Y軸=左右(幅) / Z軸=上下(高さ)
cube_size = 10 # キューブ1辺の長さ
spacing = 20 # 配置の間隔(中心から中心までの距離)
base_z = 5 # 土台の高さ
fn_val = 60 # 円・球の滑らかさ(今回は未使用ですが標準として定義)
eps = 0.1 # 面のチラつき防止用の微小値
# 配置したい座標のリスト(前後・左右)
x_positions = [-spacing, 0, spacing]
y_positions = [-spacing, 0, spacing]
# --- 関数(モジュール)定義 ---
# 1. 基準となる柱(キューブ)
def make_pillar():
# center=True を指定し、原点[0,0,0]を中心に作ります
return cube([cube_size, cube_size, cube_size], center=True)
# 2. 全体を支える土台
def make_base():
# 3つのキューブがすっぽり収まるように全体の幅と奥行きを計算
w = spacing * 2 + cube_size + 10
return cube([w, w, base_z], center=True)
# --- メイン処理 ---
# 土台の生成
base = make_base()
# 基準となる柱を1つ生成
pillar = make_pillar()
# 土台の上面に乗るようにZ方向の移動量を計算
# (土台の厚みの半分) + (キューブの高さの半分)
z_up = base_z / 2 + cube_size / 2
# ^ 演算子を使って一気に配置!
# X軸(3パターン) × Y軸(3パターン) = 9個のキューブが生成されます
pillars = pillar ^ [x_positions, y_positions, z_up]
# 土台と9つの柱を結合( + 演算子 )
result = base + pillars
# 3Dプレビュー表示
show(result)
🌟 解説ポイント
1. ^ 演算子は「組み合わせの魔法」
通常のプログラミング(Pythonなど)で縦横に物を並べようとすると、for 文という繰り返し処理を2重(マトリョーシカのような状態)にして書く必要があります。
しかし、PythonSCADの ^ 演算子を使えば、「X座標のリスト」と「Y座標のリスト」を渡すだけで、すべての組み合わせを自動で計算してくれます。
コードの中の pillar ^ [x_positions, y_positions, z_up] の1行だけで、一瞬にして9つのブロックが規則正しく並びます。
2. リストの使い方
今回、X軸(前後)とY軸(左右)の配置場所として [-spacing, 0, spacing](つまり [-20, 0, 20])という「リスト」をあらかじめ変数として定義しました。
これを [-40, -20, 0, 20, 40] のように要素を増やすだけで、5×5=25個のブロック配列へと一瞬で拡張できます。これがパラメトリック設計(数値を変更するだけで全体が変わる設計)の強みです。
3. Z方向(高さ)の計算
今回はブロックを土台の上にピッタリ乗せたかったため、z_up という変数で高さを計算しました。
すべての部品を center=True(原点中心)で作っているため、「土台の厚みの半分」と「ブロックの高さの半分」を足し算すれば、絶対にめり込んだり浮いたりしない正確な位置に移動できます。これはものづくりの図面を考える上でも非常に大切な考え方です。
ぜひ、パラメータの spacing や cube_size の数値を変更して、プレビュー画面でどう変化するか実験してみましょう。
参考資料

