
- radius: float – 球の半径
- amp: float – 縦方向(経線方向)の波の振幅
- wave_cycles: int – 縦方向の波の繰り返し数(山と谷の数はこれの2倍)
- res_theta: int – 経線方向の分割数
- res_curve: int – 各曲線の解像度
- pipe_radius: float – Pipeの太さ- results: list of Brep – 波打つ縦曲線と、それを横方向でつなぐ円に沿ったPipe構造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)ライセンス・利用規約
| 項目 | 可否 | 説明 |
|---|---|---|
| 自身のプロジェクトへの組み込み | ○ | 個人・商用問わず、スクリプトや作品の一部として自由に使えます。 |
| コードの改変・学習利用 | ○ | 自身の学習や、目的に合わせたカスタマイズは大歓迎です。 |
| SNSへのシェア・紹介 | ○ | 作品の画像やURLのシェアは許可不要です。ぜひご紹介ください! |
| 再配布・転載 | × | コードやファイルを丸ごと自身のサイト等でコンテンツとして公開しないでください。 |
| 素材・プログラムとしての転売 | × | 本サイトの内容をそのまま、あるいは微調整のみで有料販売しないでください。 |
| 著作権表示・リンク | 任意 | 必須ではありませんが、引用元としてリンクを貼っていただけると励みになります。 |