Day 21
(3.5)
球体の編み構造
#sphere#weave#wave#polar#3d

✅ Inputs
- radius: float – 球の半径
- amp: float – 縦方向(経線方向)の波の振幅
- wave_cycles: int – 縦方向の波の繰り返し数(山と谷の数はこれの2倍)
- res_theta: int – 経線方向の分割数
- res_curve: int – 各曲線の解像度
- pipe_radius: float – Pipeの太さ
✅ Outputs
- results: list of Brep – 波打つ縦曲線と、それを横方向でつなぐ円に沿ったPipe構造
✅ Code
import Rhino.Geometry as rg
import math
# === 🔧 入力パラメータ例 ===
# radius = 100.0 # 球の半径
# amp = 2.0 # 波の振幅(縦方向)
# wave_cycles = 20 # 波の繰り返し数(経線方向)
# res_theta = 60 # 経線方向の分割数(縦)
# res_curve = 100 # 曲線分解能
# pipe_radius = 2.0 # Pipeの半径
# === 📐 基本設定
circumference = 2 * math.pi * radius
freq = wave_cycles * 2 * math.pi / circumference
# === 🧵 縦方向の波打つ曲線(経線方向)
vertical_curves = []
for i in range(res_theta):
theta = (2 * math.pi) * i / res_theta
phase = math.pi if i % 2 == 1 else 0.0
points = []
for j in range(res_curve + 1):
t = float(j) / res_curve
phi = math.pi * t
arc_len = t * circumference
r = radius + math.sin(arc_len * freq + phase) * amp
x = r * math.sin(phi) * math.cos(theta)
y = r * math.sin(phi) * math.sin(theta)
z = r * math.cos(phi)
points.append(rg.Point3d(x, y, z))
curve = rg.Curve.CreateInterpolatedCurve(points, 3)
vertical_curves.append(curve)
# === 🎯 緯線(波の山谷位置に円を配置)
num_peaks = int(wave_cycles * 2)
horizontal_curves = []
for k in range(num_peaks):
t = (k + 0.5) / (num_peaks)
phi = math.pi * t
r = radius * math.sin(phi)
z = radius * math.cos(phi)
if abs(r) > 1e-6:
circle = rg.Circle(rg.Plane(rg.Point3d(0, 0, z), rg.Vector3d.ZAxis), r)
horizontal_curves.append(circle.ToNurbsCurve())
# === ✅ Pipe化
curves = vertical_curves + horizontal_curves
results = []
for c in curves:
pipes = rg.Brep.CreatePipe(c, pipe_radius, False, rg.PipeCapMode.Round, True, 0.001, 0.001)
if pipes:
results.extend(pipes)