brilliant.jpg


ラウンドブリリアントカットを削り出す

 ダイヤモンドをキラキラと美しく見せるカットとして有名な、ラウンドブリリアントカットを削り出してみたいと思います。
 とはいえ、専門ではないので、まずは「ラウンドブリリアントカット」で調べてみました。

調査結果

 わかったのは、ざっと、以下のような感じ。

 ここからは、実際の絵を見ながら説明した方が楽なのですが、少々作図が難しいので、順番が逆になりますが完成したレイトレーシング画像を使って説明します。ワイヤフレームモデルではないので、面の濃淡で稜線を視認する必要があり、ちょっと見にくいですがご容赦を。
 横から見た図。

brilli_side.jpg

 ついでなので、これから作ろうとしているモデルの座標軸やパラメータも図示してあります。図の奥側へ向かってy軸が伸びています。x軸とz軸の交わったところをストーンの中心として、原点を置きます。z軸正の方向がcrown、負の方向がpavilion、そのつなぎ目に当たる部分をgirdleと呼びます。名前の付いた面毎に色分けしてあるのですが、各面の呼び名については別な図で説明します。パラメータに関しては、最初のまとめで記したようにサイトによってばらつきがあるので、適当に「それらしい値」を選択してデータを作成しました。
 自然界でたまたま見つかった原石から、少しでも大きなストーンを切り出したいでしょうから、多少サイズにばらつきがあるのかな?と、理解しています。
 以下、上から見た図です。

brilli_top.jpg

 table(1、カッコ内は面数)、star facet(8)、bezel facet(8)、upper girdle facet(16)と呼ばれる面があります。
 次は下から見た図。

brilli_btm.jpg

 pavilion facet(8)、lower girdle facet(16)、culet(1)と呼ばれる面があります。culetは一番下のとがった部分で、少しだけ面取りしてあるようです。レイトレ画像では小さすぎて見えていませんが……、データ上はgirdle直径の0.1%程度の深さで面取りしてあるつもりです。


削り出してみよう

ベースとなる形状

 まず、ベースとなるのは、crown(上側)の八面体と、pavilion(下側)の八面体です。規則的な図形なので、8回ループを回して作ります。ちなみに、ここで削り出した面が、bezel facetとpavilion facetになります。

  var R=50; // girdle半径
  var a_crown=34.5; // crown角度
  var a_pavil=40.8; // pavilion角度
  idx=0;
  while (idx<8)
  {
    screwz idx*360/8;
    model
    {
      // bezel facet
      para R,0,0;
      screwy a_crown;
      plane 0,0,0, 0,0,1;
    }
    model
    {
      // pavilion facet
      para R,0,0;
      screwy -a_pavil;
      plane 0,0,0, 0,0,-1;
    }
    idx=idx + 1;
  }


 キーとした定数は、crown角度a_crown、pavilion角度a_pavil、girdle半径Rの3つです。これらの定数を使って、下図の様に平面を上下2枚づつ、z軸の周りに回転させながら定義しています。

brilli_base.jpg

 示したソースリストには入っていませんが、このずっと上位で、全体を括るand { }ブロックがあって、全ての定義した平面のandを取って、最終的にラウンドブリリアントカットが完成しています。
 やはりここでも、「少しでも大きなストーンを切り出したい」という思いが見えるのは、凹ませる(えぐる様な)カットが1つもないという事。図形としては、いわゆる凸多面体という分類となります。ですので、and { }ブロック1つの中に、58面全ての平面を定義したら、完成、となっています(全ての平面の共通部分、andがラウンドブリリアントカットになっています)。

tableとculet

 tableとculetを削り取ると、だいぶそれらしい形になりました。ここまでculetを含めて18面。全部で58面なので、まだまだ、完成には程遠いんですけどね。

brilli_table.jpg

  var r_crown=0.16; // crown高さ(直径を1とした比)
  var r_pavil=0.43; // pavilion高さ(直径を1とした比)
  // table
  plane 0,0,2*R*r_crown, 0,0,1;
  // culet
  plane 0,0,-2*R*r_pavil, 0,0,-1;


 キーとなった定数は、girdle直径に対するtableの高さr_crownと、pavilionの深さr_pavilです。実際には、これに加えて、girdleの厚さも2.5%程度持っているようですが、今回はこの分を0%としました。
 pavilion角度a_pavil=40.8°で、girdle半径Rですので、pavilionの一番下で8つの面が集約している部分の頂点までの長さL_pavil=R*tan(40.8°)=0.863R=0.4316×(2R)。girdle直径2Rの43.16%に相当する深さ、となります。culetの面取りを2Rのr_pavil=0.43(43%)で実施しているので、直径2Rの0.16%程度が面取り(culet)で削られている計算です。この設定だと、ほぼ、点ですね。

star facet

 bezel facetとtableを削った時点の模式図(上面図)を書いてみます。

brilli_top2.png

 外側の六角形がgirdle部分、内側の六角形がtable部分ですので、実際には高さが異なっています。
 いくつか補助線が引いてあって、説明しやすい様に記号を振ってあります。「D(E)」など、括弧付きで2つの記号が振ってある点は、上から見ると同じ位置ですが、高さが違っていることを示しています。補助線ODBとOCAで切った断面図を示します。

brilli_csec.png

 star facetは、△GEE'となります。点GとEの座標を計算し(E'はEのy軸座標を符号反転)、三点を含む平面を定義します。

G点

 Gのx座標は、girdle半径RとOCの中点に置きます。
 既知なパラメータは以下。

 この数値を使って、Gの座標を計算します。

E(E')点

 Eは∠AOBだけz軸の周りに回転しているので、以下の通り。

三点を含む平面

 Xi-TRACEの平面定義は、平面上の1点(px,py,pz)と、法線ベクタ(nx,ny,nz)を指定するようになっています。

  plane px,py,pz, nx,ny,nz;

 今回は、計算した「三点を含む平面」を定義したいので、三点[a]、[b]、[c]を含む平面を定義する手続きを作っておきます。ここでは、[ ]をベクタを示すのに使います。[a]=(ax,ay,az)という三次元ベクタだと思ってください。
 平面上の1点[p]は、そのまま[a]を使うことにします:[p]=[a]。
 [a]から[b]へ向かうベクタ:[b]-[a]と、[a]から[c]へ向かうベクタ:[c]-[a]を考え、この2ベクタに垂直なベクタが法線ベクタ[n]となります。理屈はアレですが、([b]-[a])と([c]-[a])のベクタ積(外積)が、2ベクタに垂直なベクタになりますので、[n]=([b]-[a])*([c]-[a])と、なります。ここで、'*'はベクタ積です。[n]の方向は、掛け算の順番で決まり、[n]は、([b]-[a])が([c]-[a])に回転する方向が反時計回りに見える側を向きます。
 以下、完成した手続きです。

  procedure pla3p a.x,a.y,a.z, b.x,b.y,b.z, c.x,c.y,c.z
  {
    // 三点a,b,cを含む平面を定義する。
    // 法線ベクタは、a→b→cが反時計回りに見える方向を向く
    var ab.x,ab.y,ab.z;
    var ac.x,ac.y,ac.z;
    ab.x=b.x - a.x;
    ab.y=b.y - a.y;
    ab.z=b.z - a.z;
    ac.x=c.x - a.x;
    ac.y=c.y - a.y;
    ac.z=c.z - a.z;
    var n.x,n.y,n.z;
    n.x=ab.y*ac.z - ab.z*ac.y;
    n.y=ab.z*ac.x - ab.x*ac.z;
    n.z=ab.x*ac.y - ab.y*ac.x;
    var l;
    l=sqrt (sq (n.x) + sq (n.y) + sq (n.z));
    // l=0だと、平面にならない。
    if (l=0)
    {
      return;
    }
    n.x=n.x/l;
    n.y=n.y/l;
    n.z=n.z/l;
    plane a.x,a.y,a.z, n.x,n.y,n.z;
  }


 △GEE'(star facet)を削り取ると、以下となります。

brilli_star.jpg

upper girdle facet

 さて、もう一度、上からみた模式図を示しておきます。

brilli_cir.png

 ここまでは、上から見て正八角形をしています。ここから、正八角形の頂点を削って、正1六角形にしていきます。上図には、正八角形に内接する円を補助線として引いてあります。OAと内接円の交点がHです。ごちゃごちゃするので、他の記号を消してしまったのですが、upper girdle facetは、△GHBと△GHB'です。点HとB(B'はBのy軸座標を符号反転)の座標を計算して、三点を含む平面を定義すればOKです。

 upper girdle facetを削ると、こうなります。

  // upper girdle facet
  pla3p G.x,G.y,G.z, H.x,H.y,H.z, B.x,B.y,B.z;
  pla3p G.x,G.y,G.z, B.x,-B.y,B.z, H.x,H.y,H.z;


 pla3pに渡す座標の順番に気を付けてください。「三点を含む平面」で解説した通り、pla3pに渡す座標の順番が、反時計回りに見える側に法線ベクタが向いた平面が定義されるので、順番を間違うと逆側を向いてしまい、and演算すると何も残らなくなってしまいます。上に示したように、△GHBに関してはpla3pにG→H→Bの順番で渡していますが、△GHB'に関してはG→B'→Hの順で渡さないと表裏反転してしまいます。

brilli_upper.jpg

lower girdle facet

 いよいよ最後の面です。OAで切った下側(pavilion)の断面図で説明します。

brilli_csec2.png

 パラメータは、lower half length:r_lhalf(=0.75)です。この値はgirdle直径からの比で、左右のlower half lengthの和が直径のr_lhalfという事みたいです。つまり、上図の様に片側(右半分)で考える場合には、girdlr半径Rのr_lhalf倍と解釈しました。
 lower girdle facetは、△HJBと△HJB'です。点HとBの座標は計算済みなので、残りのJ座標を計算します。

ラウンドブリリアントカットの完成

 58面全てを削り終えました。では、削り出しの過程をまとめてみます。

brilli_shape.jpg

 一応、色分け画像作成用のデータを載せておきます。画像が小さくて見にくい場合は、ダウンロードしてレイトレーシングしてみてください。

  Xi-TRACEデータ:brilliant_shape.xitr


ダイヤモンドにしてみよう

属性の設定

 ダイヤモンドの屈折率は約2.42程度ですね。色や屈折率、反射率などの属性を指定する命令、attr命令の中で、indexという項目が物体の屈折率を指定する項目なので、ここにセットします。

  index 2.42;

 反射率の設定reflについては、まず、反射率は1.00に設定します。これは、「全ての光を反射する」という意味ではありません。Xi-TRACEでは、フレネルの式(物理モデル)に従って、入射角と屈折率から反射率(R_spc_fles)を計算しています。レンダリングに用いる鏡面反射率は、R_spc_rend=R_spc_fles×<R_spc>で計算しています。ここで、reflの第1パラメータに設定した、1.00と言う数値が<R_spc>に相当します。よって、フレネルの式による反射率R_spc_flesをそのまま使う場合には、<R_spc>=1.00とします。蛇足ですが、R_spc_flesの値を使用せず、直接反射率を設定したい場合、<R_spc>に負の値を設定します。<R_spc><0の場合には、その絶対値をレンダリングに使用します:R_spc_rend=abs(<R_spc>)。
 reflについては、ハイライトに関する設定を適当にして終わりです。比較的鈍いハイライトがつくように設定しました(第3パラメータ0.6)。ハイライトの起きる角度が広がるので、より輝いて見えるはず。本来は、凹凸を少なくきれいに研磨していれば、鋭いハイライト(第3パラメータが0.2等)になるべきなのかもしれません。

  refl 1.00, 1, 0.6;

 透過率の設定tranについては、reflと同様に、フレネルの式で算出した透過率をそのまま使うように、透過率(第1パラメータ)を1.00に設定しています。その他、拡散透過無し(第2パラメータ0.00)、透過中の光の減衰なし(第3パラメータ0)と、理想的な値に設定してあります。

  tran 1.00, 0.00, 0;

 フレネルの式をそのまま使うのは、今回のデータには特に重要です。何しろ、ダイヤモンドの上面から入射した光が、下の面(pavilion)で全反射することによって、100%の強度で跳ね返り、そのほとんどが上面から外へ出ていくことによって、キラキラと輝くわけです。固定反射率を使ってしまって全反射が起きなくなったら、意味がありません。

brilli_refl.png

 以下、attr命令のまとめです。

  attr brilliant=
  {
    index 2.42;
    tran 1.00, 0.00, 0;
    refl 1.00, 1, 0.6;
  };


brilliantrt.jpg

キラキラさせる

 完成した画像は、まあ、「こんなものかな?」という感じですね。キラキラしているようにも見えるし、そうでもない様にも……。後は、うまく光線源強度なり、ハイライト強度なりを調整して、もっとキラキラ感を醸し出すことは可能だと思います。
 しかし、ここでは、手っ取り早く、Olive+のフィルタを使って、キラキラした画像にしてみます。前の節で示した画像をOlive+で読み込みます。メニューから、「フィルタメニュー ⇒ ハーロー」を選択します。

brilli_halo.png

 ダイアログが表示されるので、上のように設定してOKを押します。以下が結果。

brilliant.jpg

 例によって、レイトレーシングで動画を生成するので、ハーローフィルタも動画に対して掛けてみます。

  1. Olive+を起動する
  2. 「連続メニュー ⇒ Modela」を選択します。
  3. ダイアログが表示されるので、入力ファイルをレイトレーシングで作ったAVIファル、出力ディレクトリを適切に設定、出力ファイル形式に「avi」を選択します。

    brilli_avi.png

  4. 次のダイアログが表示されるので、以下のように入力します。

    brilli_halo2.png

    filter halo, 8 5,150;

  5. OKを押すと、動画全体に対してハーローフィルタをかけて、新しいAVIファイルを出力してくれます。処理終了までお待ちください。

完成動画

 完成したデータと動画です。

  Xi-TRACEデータ:brilliant.xitr

 まずはレイトレーシングしたままのラウンドブリリアントカットダイヤモンド。



 次はOlive+のハーローフィルタで輝かせたラウンドブリリアントカットダイヤモンド。



後日のアップデート

 動画は作り直していませんが、girdleに厚みを持たせたバージョンのデータを作りましたので、置いておきます。

  Xi-TRACEデータ:brilliant_girdle.xitr

 最初に作成した時には、girdle部分の厚みを0としていましたが、実際にカットされたダイヤモンドでは、girdle部分が有限の厚みを持っています。具体的には、手を入れる必要のある面数の少ない、pavilion(下)側をgirdle厚み(r_girdle)分だけ平行移動しました。対象となった面は以下の通りです。

 加えて、1つ円柱面(cylind)を追加し、girdle部分を丸く削りました。追加部分に関しては、「brilliant.xitr」と「brilliant_girdle.xitr」を見比べてみてください。


home

download

gallery