多面体による球近似
正20面体を元に、多面体により球の近似を行なうためのユーティリティスクリプトです。
3DS MAX がインストールされているディレクトリ下の、Scripts\Startup へ登録してください。
-- *****************************************************************
-- 正20面体と、それを基にした球近似多面体を生成する
--
-- Coded By Yoshiaki Tanaka
-- 2000/03/13
-- *****************************************************************
utility Iconsahedron "正20面体生成"
(
--
-- ユーザーインターフェース定義
--
spinner rspin "最大半径" range:[0.001,20000,50]
button do_create20 "正20面体生成" Width:180
button do_create80 "80面体生成" Width:180
button do_create120 "120面体生成" Width:180
button do_create180 "180面体生成" Width:180
button do_create320 "320面体生成" Width:180
button do_create720 "720面体生成" Width:180
-- 正20面体のベース頂点セット --
fn set_20 faces verts =
(
Local i
Local vertbase = #( [ 0, 0, 1 ] , \ -- 1
[ 0.8944272, 0, 0.4472136 ] , \ -- 2
[ 0.2763932, 0.8506508, 0.4472136 ] , \ -- 3
[ -0.7236069, 0.5257311, 0.4472136 ] , \ -- 4
[ -0.7236068, -0.5257312, 0.4472136 ] , \ -- 5
[ 0.2763933, -0.8506508, 0.4472136 ] , \ -- 6
[ 0.7236067, 0.5257311, -0.4472136 ] , \ -- 7
[ -0.2763932, 0.8506507, -0.4472136 ] , \ -- 8
[ -0.8944271, 0, -0.4472136 ] , \ -- 9
[ -0.2763933, -0.8506507, -0.4472136 ] , \ -- 10
[ 0.7236069, -0.5257308, -0.4472136 ] , \ -- 11
[ 0, 0, -1 ] \ -- 12
)
-- 正20面体のフェースセット --
Local facebase = #( \
[ 1,2,3 ], [ 1,3,4 ], [ 1,4,5 ], [ 1,5,6 ], [ 1,6,2 ], \
[ 3,2,7 ], [ 4,3,8 ], [ 5,4,9 ], [ 6,5,10 ], [ 2,6,11 ], \
[ 3,7,8 ], [ 4,8,9 ], [ 5,9,10 ], [ 6,10,11 ], [ 2,11,7], \
[ 8,7,12 ], [ 9,8,12], [ 10,9,12 ], [ 11,10,12], [ 7,11,12 ] \
)
for i = 1 to vertbase.count do
(
verts[i] = vertbase[i]
)
for i = 1 to facebase.count do
(
faces[i] = facebase[i]
)
)
-- 頂点重複チェック&埋め込み --
fn check_vert vert vertset =
(
Local li, temp
for li = 1 to vertset.count do
(
temp = length (vertset[li] - vert)
if temp < 0.01 do
return li -- 発見!
)
-- 見付からなかったので追加
vertset[vertset.count+1] = vert
vertset.count
)
-- ポリゴン3分割 --
fn polygon_div3 faces verts nfaces nverts =
(
Local i,p1,p2,p3,va,pa
Local fcount = 1
-- 元の頂点をコピーしておく
for i = 1 to verts.count do
(
nverts[i] = verts[i]
)
-- ポリゴン分割 --
for i = 1 to faces.count do
(
-- 追加頂点計算 --
p1 = faces[i].x
p2 = faces[i].y
p3 = faces[i].z
va = normalize( (verts[p1] + verts[p2] + verts[p3]) / 3 )
pa = check_vert va nverts
--フェース3分割 --
nfaces[fcount+0] = [p1, p2, pa]
nfaces[fcount+1] = [pa, p2, p3]
nfaces[fcount+2] = [p3, p1, pa]
fcount = fcount + 3
)
)
-- ポリゴン4分割 --
fn polygon_div4 faces verts nfaces nverts =
(
Local i,p1,p2,p3,va,vb,vc,pa,pb,pc
Local fcount = 1
-- 元の頂点をコピーしておく
for i = 1 to verts.count do
(
nverts[i] = verts[i]
)
-- ポリゴン分割 --
for i = 1 to faces.count do
(
-- 追加頂点計算 --
p1 = faces[i].x
p2 = faces[i].y
p3 = faces[i].z
va = normalize( (verts[p1] + verts[p2]) / 2 )
pa = check_vert va nverts
vb = normalize( (verts[p2] + verts[p3]) / 2 )
pb = check_vert vb nverts
vc = normalize( (verts[p3] + verts[p1]) / 2 )
pc = check_vert vc nverts
--フェース4分割 --
nfaces[fcount+0] = [pa, pb, pc]
nfaces[fcount+1] = [p1, pa, pc]
nfaces[fcount+2] = [p2, pb, pa]
nfaces[fcount+3] = [p3, pc, pb]
fcount = fcount + 4
)
)
-- ポリゴン6分割 --
fn polygon_div6 faces verts nfaces nverts =
(
Local i,p1,p2,p3,v,pa,pb,pc,pd
Local fcount = 1
-- 元の頂点をコピーしておく
for i = 1 to verts.count do
(
nverts[i] = verts[i]
)
-- ポリゴン分割 --
for i = 1 to faces.count do
(
-- 追加頂点計算 --
p1 = faces[i].x
p2 = faces[i].y
p3 = faces[i].z
v = normalize( (verts[p1] + verts[p2] + verts[p3]) / 3 )
pa = check_vert v nverts
v = normalize( (verts[p1] + verts[p2]) / 2 )
pb = check_vert v nverts
v = normalize( (verts[p2] + verts[p3]) / 2 )
pc = check_vert v nverts
v = normalize( (verts[p3] + verts[p1]) / 2 )
pd = check_vert v nverts
--フェース6分割 --
nfaces[fcount+0] = [pa, p1, pb]
nfaces[fcount+1] = [pa, pb, p2]
nfaces[fcount+2] = [pa, p2, pc]
nfaces[fcount+3] = [pa, pc, p3]
nfaces[fcount+4] = [pa, p3, pd]
nfaces[fcount+5] = [pa, pd, p1]
fcount = fcount + 6
)
)
-- ポリゴン9分割 --
fn polygon_div9 faces verts nfaces nverts =
(
Local fcount = 1
Local pa,pb,pc,pd,pe,pf,pg,p1,p2,p3,v
Local i
-- 頂点をコピーしておく
for i = 1 to verts.count do
(
nverts[i] = verts[i]
)
fcount = 1
-- ポリゴン分割 --
for i = 1 to faces.count do
(
-- 追加頂点計算 --
p1 = faces[i].x
p2 = faces[i].y
p3 = faces[i].z
v = normalize( verts[p1] + (verts[p2] - verts[p1]) / 3 )
pa = check_vert v nverts
v = normalize( verts[p2] + (verts[p1] - verts[p2]) / 3 )
pb = check_vert v nverts
v = normalize( verts[p1] + (verts[p3] - verts[p1]) / 3 )
pc = check_vert v nverts
v = normalize( verts[p1] + verts[p2] + verts[p3] )
pd = check_vert v nverts
v = normalize( verts[p2] + (verts[p3] - verts[p2]) / 3 )
pe = check_vert v nverts
v = normalize( verts[p3] + (verts[p1] - verts[p3]) / 3 )
pf = check_vert v nverts
v = normalize( verts[p3] + (verts[p2] - verts[p3]) / 3 )
pg = check_vert v nverts
--フェース9分割 --
nfaces[fcount+0] = [p1, pa, pc]
nfaces[fcount+1] = [pc, pa, pd]
nfaces[fcount+2] = [pc, pd, pf]
nfaces[fcount+3] = [pf, pd, pg]
nfaces[fcount+4] = [p3, pf, pg]
nfaces[fcount+5] = [pa, pb, pd]
nfaces[fcount+6] = [pd, pb, pe]
nfaces[fcount+7] = [pd, pe, pg]
nfaces[fcount+8] = [p2, pe, pb]
fcount = fcount + 9
)
)
-- メッシュの生成 --
fn meshcreate face vert =
(
Local i
-- 半径に応じて拡大・縮小 --
for i = 1 to vert.count do
(
vert[i] = vert[i] * rspin.value
)
Local tobj = mesh vertices:vert faces:face
for i = 1 to tobj.numfaces do
(
setFaceSmoothGroup tobj i 1
)
update tobj
)
--
-- アクション定義
--
---------- 正20面体生成 ----------
on do_create20 pressed do
(
Local vert20
Local face20
-- 基本法線設定 --
vert20 = #()
face20 = #()
set_20 face20 vert20
meshcreate face20 vert20
)
---------- 正20面体を基礎とした80面体を生成 ----------
on do_create80 pressed do
(
Local vert20, vert80
Local face20, face80
-- 基本法線設定 --
vert20 = #()
face20 = #()
set_20 face20 vert20
vert80 = #()
face80 = #()
-- ポリゴン分割 --
polygon_div4 face20 vert20 face80 vert80
meshcreate face80 vert80
)
---------- 正20面体を基礎とした120面体を生成 ----------
on do_create120 pressed do
(
Local vert20, vert120
Local face20, face120
-- 基本法線設定 --
vert20 = #()
face20 = #()
set_20 face20 vert20
vert120 = #()
face120 = #()
-- ポリゴン分割 --
polygon_div6 face20 vert20 face120 vert120
meshcreate face120 vert120
)
---------- 正20面体を基礎とした180面体を生成 ----------
on do_create180 pressed do
(
Local vert20, vert180
Local face20, face180
-- 基本法線設定 --
vert20 = #()
face20 = #()
set_20 face20 vert20
vert180 = #()
face180 = #()
-- ポリゴン分割 --
polygon_div9 face20 vert20 face180 vert180
meshcreate face180 vert180
)
---------- 正20面体を基礎とした240面体を生成 ----------
on do_create240 pressed do
(
Local vert20, vert80, vert240
Local face20, face80, face240
-- 基本法線設定 --
vert20 = #()
face20 = #()
set_20 face20 vert20
vert80 = #()
face80 = #()
vert240 = #()
face240 = #()
-- ポリゴン分割 --
polygon_div4 face20 vert20 face80 vert80
polygon_div3 face80 vert80 face240 vert240
meshcreate face240 vert240
)
---------- 正20面体を基礎とした320面体を生成 ----------
on do_create320 pressed do
(
Local vert20, vert80, vert320
Local face20, face80, face320
-- 基本法線設定 --
vert20 = #()
face20 = #()
set_20 face20 vert20
vert80 = #()
face80 = #()
vert320 = #()
face320 = #()
-- ポリゴン分割 --
polygon_div4 face20 vert20 face80 vert80
polygon_div4 face80 vert80 face320 vert320
meshcreate face320 vert320
)
---------- 正20面体を基礎とした720面体を生成 ----------
on do_create720 pressed do
(
Local vert20, vert180, vert720
Local face20, face180, face720
-- 基本法線設定 --
vert20 = #()
face20 = #()
set_20 face20 vert20
vert180 = #()
face180 = #()
vert720 = #()
face720 = #()
-- ポリゴン分割 --
polygon_div9 face20 vert20 face180 vert180
polygon_div4 face180 vert180 face720 vert720
meshcreate face720 vert720
)
)