簡単そうで、意外と作り方が思いつかないサッカーボールを作ってみようと思い立ちました。
どうやって作ったら良いものか。色々とインターネットで調べていたところ、いくつかわかってきました。
少し光が見えてきました。正20面体は、20枚の正三角形でできており、下図のような展開図になるようです。
さらに、サッカーボールの方の正六角形が交わる角度を計算しているサイトがありました(「サッカーボールの正六角形が交わる角度」辺りで検索かけてみてください)。
ここまでわかったら、正20面体は何とかなりそうです。ちなみに、deg=41.8°程度ですね。
展開図と、交わる角度degから、正20面体を作ってみます。
正20面体ですので、平面を20枚定義することになります。ここで定義する平面は、z軸の正方向へ距離1の点を通り、x-y平面に平行な平面とします。Xi-TRACEでは、以下の命令で定義できます。
plane 0,0,1, 0,0,1;
平面はこの1種類のみです。後は、回転の一次変換だけで作ってみます。1つ目の操作は、x軸の周りの回転です。
上図右側は、最初の平面1を定義したところです。この平面1をx軸の周りにdeg°回転して、先ほどと同様、2枚目の平面を定義すると、左側になります。回転するための命令は以下です。
rotx deg;
これで、展開図の一辺を折り進めることができました。上図は、x軸の正方向から見下ろした図ですが、今度は、同じ状態をz軸の正方向から見下ろした図を見てみます。
便宜上、平面を三角形で表示しています。先ほどのx軸周りの回転によって、平面1から平面2まで折り進みました。平面1→平面2の折り目は赤線で示しました。x軸周りの回転ですので、折り目はx軸に平行な直線になります。
最初に示した展開図で、正三角形に番号が振ってありますが、この順で折り進めようと思うと、次は、点線で示した平面3方向へ折り進めることになります。次も先ほどと同じ、x軸周りの回転で折り進めるためには、折り目となる直線(緑線)がx軸と平行になるように調整してやる必要があります。これは、z軸周りの360/3/2°回転で実現でき、上図右側の様になります。回転するための命令は以下です。
rotz +360/3/2;
展開図に戻ると、折り進める方向は以下の通り、2つの方向が必要となります。
先ほどと逆側であるa1方向に折り進めるためには、z軸周りの回転を先ほどと逆側、-360/3/2°回転すればOKです。a1とa2の手続きをprocedureを使って記述しておきます。
procedure a1
{
plane 0,0,1, 0,0,1;
rotx +deg;
rotz -360/3/2;
}
procedure a2
{
plane 0,0,1, 0,0,1;
rotx +deg;
rotz +360/3/2;
}
ここまで来たら、展開図の正三角形を1から20まで順に、折り進んでいけば良いのです。次に折り進む方向がa1なのか、a2なのかに注意しながらprocedureを実行していきます。
// 正20面体
// 展開図を折り曲げながら、20面体を組み立てていく
static : a1; // 20
static : a2; // 19
static : a1; // 18
static : a1; // 17
static : a1; // 16
static : a2; // 15
static : a2; // 14
static : a2; // 13
static : a1; // 12
static : a2; // 11
static : a1; // 10
static : a1; // 9
static : a1; // 8
static : a2; // 7
static : a2; // 6
static : a2; // 5
static : a1; // 4
static : a2; // 3
static : a1; // 2
static : a2; // 1
一次変換の記述順と変換順の関係から、ここに示したように、逆順(下に1番、上に20番目の正三角形)で記述します。この20枚の平面の共通領域が正20面体ですので、この全体をand命令のブロック内に置けば完成です。
常に、「z軸の正方向へ距離1の点を通り、x-y平面に平行な平面」を定義して、後は回転させただけですので、この正20面体は、半径1の球体に外接しています。大きさのイメージとしては、「半径1の球体より、少し大きい」ということですね……。
ちなみに、上のデータ記述を見てお分かりかもしれませんが、最初に示した展開図の通りに折り進んだのではなく、展開図を参考にしながら、1〜20の番号順に折り進みました。
正20面体を表示するデータと、動かしてみた動画をご覧に入れます。
Xi-TRACEデータ:icosahedron.xitr
頂点を削ったら、サッカーボール完成です。
驚くことに、ここまで、数学的な計算はほとんどしていません。唯一、正20面体を構成する正三角形の交わる角度degの計算が必要でしたが、インターネットで何方かが計算していた値を使わせて頂いたので、「作者は」、何も計算していません(1^^;)。
しかし、とうとうここへ来て、少し計算が必要になりました。
ここまで、20枚の面を張ってきましたので、今や、面の位置はわかっています。しかし、ここから先必要なのは、正20面体の「頂点」の位置です。
頂点の位置を知るために必要なdeg2と、頂点を削る位置(中心からの距離)dstの2つを計算してみます(下図)。
deg2は図に示してあります。正20面体の頂点には、5枚の正三角形が集まっており、底面の形状が正五角形の正五角錐を形成しています。図は、最後に20番の平面(AB、緑線で表示)を張ったところから、頂点Aをz軸上に回転させるのに必要な角度deg2を求めるため、必要な1つの正五角錐、底面の正五角形、1枚の正三角形を図示したものです。
頂点を削る位置は正三角形の一辺の長さの1/3の点です。今回は直線AO上の点を知りたいので、Oから正五角錐の高さAEの1/3までの距離をdstとしています。
図中A、B、……などの記号を使って計算していきましょう。
正五角形に着目して、正五角形の中心から頂点までの距離BEを求める
cos (∠JBE) = BJ/BE
BE = BJ/cos (∠JBE) …… BEについて解いた
BE = (AB/2)/cos (108/2°) …… BJは正三角形の一辺の長さ(BH=AB)の1/2
正五角錐に着目して、正五角錐の高さAEを求める
sq (AB) = sq (BE) + sq (AE) …… 三平方の定理(sq(x)はxの2乗)
AE = sqrt (sq (AB) - sq (BE)) …… sqrt(x)はxの平方根
正三角形に着目して、正三角形の高さAFを求める
AF = AB*sin (∠ABF)
AF = AB*sin (60°) …… ∠ABF=60°
図の△ADOに着目して、deg2を求める。
△ADOと△AFEは相似なので、deg2=∠AOD=∠AFE
cos (∠AFE) = AE/AF
cos (deg2) = sqrt (sq (AB) - sq (BE))/(AB*sin (60°)) …… AE,AFを代入
cos (deg2) = sqrt (sq (AB) - sq ((AB/2)/cos (108/2°)))/(AB*sin (60°)) …… BEを代入
cos (deg2) = sqrt (1 - sq (1/2)/sq (cos (108/2°)))/sin (60°) …… ABを約分
未知数が無くなったので、cos (deg2)が計算できます。後は、cosの逆関数acos(アークコサイン)でdeg2を計算して終了です。
deg2が求まったので、この数値を使ってdstを計算していきます。dstを求めるには、AOとAEを求めればOKです。
△AODに着目して、AOを求める
cos (∠AOD) = OD/AO
cos (deg2) = 1/AO …… OD=1,∠AOD=deg2
AO = 1/cos (deg2) …… AOについて解いた
△AODに着目して、ADを求める
sin (∠AOD) = AD/AO
AD = AO*sin (deg2) …… ∠AOD=deg2,ADについて解いた
正三角形に着目して、DFを求める
sin (∠DBF) = DF/BD
DF = AD*sin (30°) …… BD=AD,∠DBF=30°,DFについて解いた
正三角形の高さAFを求める
AF = AD + DF
正三角形の一辺の長さABを求める
sin (60°) = AF/AB
AB = AF/sin (60°) …… ABについて解いた
正五角形に着目して、BEを求める
cos (∠JBE) = BJ/BE
BE = AB/2/cos (108/2°) …… BJ=AB/2,∠JBE=108/2°,BEについて解いた
△ABEに着目して、AEを求める
sq (AB) = sq (BE) + sq (AE) …… 三平方の定理
AE = sqrt (sq (AB) - sq (BE)) …… AEについて解いた
AOとAEが求まりました。dstは以下となります。
dst = AO - AE/3
正20面体の展開図を折り進めて、最後20番目の平面を定義したところで完了しています。前節の図にも、最後20番の平面を緑色の線で示してあります。ここから、x軸周りにdeg2°回転させると、頂点Aがz軸に乗ります。頂点を削る位置dstに新たに平面を定義すると、サッカーボールが完成します。
ここで、もう一度、正20面体の展開図を示します。今度は、頂点に着目するので、頂点の位置にアルファベットを振ってあります。
頂点をたどりながら、平面を定義し、削り取っていきます。以下図のように、ある頂点(赤色で図示)から、次に削り取る頂点を2方向定義しています。
b1とb2の手続きをprocedureを使って記述しておきます。
procedure b1
{
rotx -deg2;
plane 0,0,dst, 0,0,1;
rotx +deg2;
rotx +deg;
rotz -360/3/2;
}
procedure b2
{
rotx -deg2;
plane 0,0,dst, 0,0,1;
rotx +deg2;
rotx +deg;
rotz +360/3/2;
}
データ記述では、頂点を削る繰り返しが展開図で見やすくなるように、一旦、19番の平面へ戻って頂点Jの位置からスタートし、頂点をA→B→C→……→I→Jと、アルファベット順に削っています。最後、頂点Kと、その反対側の極に位置する頂点Lへ飛んで、忘れずに削り取ります。
// 両極の五角形
plane 0,0,dst, 0,0,1; // L
rotx 180;
rotx +deg2;
static : b1; // K
// 繰り返し五角形
static : b1; // J
static : b2; // I
static : b1; // H
static : b2; // G
static : b1; // F
static : b2; // E
static : b1; // D
static : b2; // C
static : b1; // B
static : b2; // A
// 展開図で繰り返しを認識しやすいように19へ戻る
rotz +360/3/2;
rotx -deg;
完成データとサッカーボールを回転させてみた動画を示します。
Xi-TRACEデータ:soccer_ball.xitr
最終データは、平面ではなく球面の一部を使ってサッカーボールを作っています。
こうすることで、「空気が入って、膨らんだサッカーボール」のような感じにはなりますが、本来、平面を張るべきところに球面を張ることになるので、正五角形や正六角形が歪んでしまうのが難点です。
// 平面を生成する手続き
procedure pla l,m,n, a,b,c
{
if (false)
{
// 普通に平面を定義する
plane l,m,n, a,b,c;
}
else
{
// 大きな球面で平面を近似する
// 少し丸みを帯びるので、空気で膨らませたサッカーボールっぽく
// なるかな?
para l,m,n;
leverz a,b,c;
var ra=0.2; // 球がxy平面から飛び出す距離
var rb=1; // 球をxy平面で切った時の円の半径
var r=(sq (ra) + sq (rb))/(2*ra); // 球の半径
sphere 0,0,-(r - ra), r;
}
}
最初のif (false)をif (true)に変更すると、球面ではなく、平面を定義するようになるので、歪みのない正五角形/正六角形のサッカーボールができます。カクカクで硬そうなイメージで、ボールっぽくなくなりますが……。