global_settings { charset utf8 } #include "colors.inc" //--------------------------------------------------------------- // 背景色とアンモナイトの色など共通定数を定義する background { color Gray90 } #declare ammo_color = Gray25; // 殻の色 // #declare ammo_color = Gold; // 殻の色 #declare spine_ratio=0.19; // 殻口径に対する疣のサイズの比 #declare costal_interval=10; // 肋が発生するインターバル #declare spine_interval=2; // 疣が発生するインターバル(肋に対して) //--------------------------------------------------------------- // パーツ1:Didymocerasの幼殻部を定義する #declare didymoceras1 = union { // アンモナイトの描画パラメータ #declare sita_step = pi/400; // 1描画単位の回転角 (ラジアン) #declare proto = 0.02; // 初房サイズ #declare start_size = proto/4; // 殻口径の初期サイズ #declare num_whorl=5; // 巻き数 // 螺旋の計算パラメータ #declare fact_rt = 0.06; // 回転角に応じて半径が大きくなる割合(初期値) #declare fact_wt = 0.105; // 回転角に応じて太さが大きくなる割合(初期値) #declare fact_ar=0.069; // 回転角に応じてfact_rtが大きくなる割合 #declare fact_aw=0.007; // 回転角に応じてfact_wtが大きくなる割合 #declare fact_ah=0.0004; // 回転角に応じて巻きが垂れ下がる割合 // 初房を定義する sphere { <0, 0, 0>, proto texture { pigment { color ammo_color } finish { specular 0.5 roughness 0.005 ambient 0.35 } } } // 螺旋の初期設定 #declare max_wt = num_whorl*(2.0*pi/sita_step); // 全体の描画に必要なループ回数 #declare wt = 0; // ループカウンタの初期値 #declare wsita = sita_step*wt; // 回転角の初期値 #while (wt <= max_wt) // wtがmax_wt以上になるまでループする // 螺旋座標値の計算 #declare wr = (exp(fact_ar*wsita))*proto/2.0*(exp(fact_rt*wsita)); #declare ww = (exp(fact_aw*wsita))*start_size*(exp(fact_wt*wsita)); #declare wx=wr*cos(wsita); #declare wy=wr*sin(wsita); #declare wz=fact_ah*pow(wsita,1.9); // 似せるために微妙に調整(苦) // 肋生成周期の判定 #declare costal_level=1.0; #if(mod(wt,costal_interval)=0) #declare costal_level=1.1; // 肋の部分の殻口径は1.1に拡大する #end // 1成長単位を描画する定義 torus { ww, wr*0.05 scale texture { pigment { color ammo_color } finish { specular 0.5 roughness 0.005 ambient 0.35 } } rotate <0, 0, degrees(wsita)> translate <-wx, -wy, -wz> } // 疣の生成周期の判定 #if(mod(wt+costal_interval,costal_interval*spine_interval)=0) // 疣(2列)を描くための定義 sphere { // 一方の疣 , ww*spine_ratio scale <1, 0.7, 0.6> rotate <0, -150, 0> rotate <0, 0, degrees(wsita)> translate <-wx, -wy, -wz> texture { pigment { color ammo_color } finish { specular 0.5 roughness 0.005 ambient 0.35 } } } sphere { // もう一方の疣 , ww*spine_ratio scale <1, 0.7, 0.6> rotate <0, -210, 0> rotate <0, 0, degrees(wsita)> translate <-wx, -wy, -wz> texture { pigment { color ammo_color } finish { specular 0.5 roughness 0.005 ambient 0.35 } } } #end #declare wt=wt+1; // ループカウンタをカウントアップ #declare wsita = wsita+sita_step; // 回転角を加算 #end } // 第1ステージの最終情報を記憶する #declare End1W=ww; #declare End1Z=wz; #declare End1R=wr; //--------------------------------------------------------------- // パーツ2:Didymocerasの巻きの主部を定義する #declare didymoceras2 = union { // アンモナイトの描画パラメータ #declare sita_step = pi/400; // 1描画単位の回転角 (ラジアン) #declare start_r = End1R; // 開始半径 #declare start_size = End1W; // 殻口径の初期サイズ #declare num_whorl=2.25; // 巻き数 // 螺旋の計算パラメータ #declare fact_rt = 0.002; #declare fact_wt = 0.009; #declare fact_ar=0.03; #declare fact_aw=0.05; #declare fact_ah=0.06; // 螺旋の初期設定 #declare max_wt = num_whorl*(2.0*pi/sita_step); // 全体の描画に必要なループ回数 #declare wt = 0; // ループカウンタの初期値 #declare wsita = sita_step*wt; // 回転角の初期値 #while (wt <= max_wt) // wtがmax_wt以上になるまでループする // 螺旋座標値の計算 #declare wr = (exp(fact_ar*wsita))*start_r*(exp(fact_rt*wsita)); #declare ww = (exp(fact_aw*wsita))*start_size*(exp(fact_wt*wsita)); #declare wx=wr*cos(wsita); #declare wy=wr*sin(wsita); #declare wz=exp(fact_ah*wsita)-1+End1Z; // 縦位置を微妙に調整(苦) // 肋生成周期の判定 #declare costal_level=1.0; #if(mod(wt,costal_interval)=0) #declare costal_level=1.1; #end // 1成長単位を描画する定義 torus { ww, wr*0.05 scale texture { pigment { color ammo_color } finish { specular 0.5 roughness 0.005 ambient 0.35 } } rotate <0, 0, degrees(wsita)> translate <-wx, -wy, -wz> } // 疣の生成周期の判定 #if(mod(wt+costal_interval,costal_interval*spine_interval)=0) // 疣(2列)を描くための定義 sphere { // 一方の疣 , ww*spine_ratio scale <1, 0.7, 0.6> rotate <0, -150, 0> rotate <0, 0, degrees(wsita)> translate <-wx, -wy, -wz> texture { pigment { color ammo_color } finish { specular 0.5 roughness 0.005 ambient 0.35 } } } sphere { // もう一方の疣 , ww*spine_ratio scale <1, 0.7, 0.6> rotate <0, -210, 0> rotate <0, 0, degrees(wsita)> translate <-wx, -wy, -wz> texture { pigment { color ammo_color } finish { specular 0.5 roughness 0.005 ambient 0.35 } } } #end #declare wt=wt+1; #declare wsita = wsita+sita_step; #end } // 第2ステージの最終位置を記憶する #declare End2=<-wx, -wy, -wz>; //--------------------------------------------------------------- // パーツ3:Didymocerasの住房部を定義する #declare didymoceras3 = union { //住房部を定義するベジェ曲線のパラメータ // U字の形状を正面から見た場合のベジェ曲線のパラメータ // (前半) #declare P0Ix=0.0; // FIX #declare P0Iy=0.0; // FIX #declare P1Ix=1.4; #declare P1Iy=0.0; #declare P2Ix=1.4; #declare P2Iy=-2.0; #declare P3Ix=0.0; #declare P3Iy=-2.0; // (後半) #declare P0Ox=P3Ix; // FIX #declare P0Oy=P3Iy; // FIX #declare P1Ox=-0.9; #declare P1Oy=-2.0; #declare P2Ox=-1.1; #declare P2Oy=-0.7; #declare P3Ox=-1.1; #declare P3Oy=-0.5; // U字の形状を横から見た場合のベジェ曲線のパラメータ // (前半) #declare P0Iz=0; // FIX #declare P1Iz=0; #declare P2Iz=-0.75; #declare P3Iz=-0.75; // (後半) #declare P0Oz=P3Iz; // FIX #declare P1Oz=-0.75; #declare P2Oz=-0.75; #declare P3Oz=-0.75; // 前半と後半の変化点 (0.0-1.0) #declare RevPointXY = 0.65; #declare RevPointZ = 0.65; // U字型描画の初期設定 #declare lastX=0.0; // 前回の座標値 #declare lastY=0.0; #declare lastZ=0.0; #declare dispFlg=0; // 殻口の向きを決めるために最初の1回をスキップするためのフラグ #declare cnt=0; // 肋と疣の周期判定用カウンタ #declare wt = 0.0; #declare t_step=0.0015; // ベジェ曲線の計算サイクル #while (wt <= 0.9) // 0.0~0.9までの範囲でベジェ曲線を計算し、殻を描く // ベジェ曲線によるXY座標の計算(計算式は以下のとおり) // B(t)=pow((1-t),3)*P0 + 3*t*pow((1-t),2)*P1 + 3*pow(t,2)*(1-t)*P2 + pow(t,3)*P3 #if (wt > RevPointXY) // 前半/後半の判定 // (後半部分の場合の計算) #declare wxyt=(wt-RevPointXY)/(1-RevPointXY); #declare wx=pow((1-wxyt),3)*P0Ox + 3*wxyt*pow((1-wxyt),2)*P1Ox + 3*pow(wxyt,2)*(1-wxyt)*P2Ox + pow(wxyt,3)*P3Ox; #declare wy=pow((1-wxyt),3)*P0Oy + 3*wxyt*pow((1-wxyt),2)*P1Oy + 3*pow(wxyt,2)*(1-wxyt)*P2Oy + pow(wxyt,3)*P3Oy; #else // (前半部分の場合の計算) #declare wxyt=wt/RevPointXY; #declare wx=pow((1-wxyt),3)*P0Ix + 3*wxyt*pow((1-wxyt),2)*P1Ix + 3*pow(wxyt,2)*(1-wxyt)*P2Ix + pow(wxyt,3)*P3Ix; #declare wy=pow((1-wxyt),3)*P0Iy + 3*wxyt*pow((1-wxyt),2)*P1Iy + 3*pow(wxyt,2)*(1-wxyt)*P2Iy + pow(wxyt,3)*P3Iy; #end // 簡易的にZ方向の位置を計算する #declare zt=wt; #if (zt > RevPointZ) // 前半/後半の判定 // (後半部分の場合の計算) #declare wzt=(zt-RevPointZ)/(1-RevPointZ); #declare wz=pow((1-wzt),3)*P0Oz + 3*wzt*pow((1-wzt),2)*P1Oz + 3*pow(wzt,2)*(1-wzt)*P2Oz + pow(wzt,3)*P3Oz; #else // (前半部分の場合の計算) #declare wzt=zt/RevPointZ; #declare wz=pow((1-wzt),3)*P0Iz + 3*wzt*pow((1-wzt),2)*P1Iz + 3*pow(wzt,2)*(1-wzt)*P2Iz + pow(wzt,3)*P3Iz; #end #if(dispFlg=1) // 2回目以降を描画対象とする // 肋生成周期の判定 #declare costal_level=1.0; #if(mod(cnt-costal_interval+1,costal_interval)=0) #declare costal_level=1.1; #end // 前回と比較して移動量(ベクトル)の絶対値を求める #declare wwr=vlength(); // 最も移動量の大きい座標軸を使って、新しい殻口の向きを決める #if(abs(wx-lastX) >= max(abs(wy-lastY),abs(wz-lastZ))) // X軸を使用して殻口の向きを決める #if(wx; #else #declare rot1=<-90, 90, 0>; #end #declare rty = -asin((wz-lastZ)/wwr); #declare rtz = atan((wy-lastY)/(wx-lastX)); #declare rot2=<0, degrees(rty), 0>; #declare rot3=<0, 0, degrees(rtz)>; #declare trans1=; #else #if(abs(wy-lastY)>=abs(wz-lastZ)) // Y軸を使用して殻口の向きを決める #if(wy; #else #declare rot1=<180, 90, 0>; #end #declare rtx = asin((wz-lastZ)/wwr); #declare rtz = -atan((wx-lastX)/(wy-lastY)); #declare rot2=; #declare rot3=<0, 0, degrees(rtz)>; #declare trans1=<0, wwr, 0>; #else // Z軸を使用して殻口の向きを決める #if(wz; #else #declare rot1=<-90, 0, 0>; #end #declare rtx = -asin((wy-lastY)/wwr); #declare rty = atan((wx-lastX)/(wz-lastZ)); #declare rot2=; #declare rot3=<0, degrees(rty), 0>; #declare trans1=<0, 0, wwr>; #end #end // 殻口(1描画単位)を描くための定義 torus { 0.4+wt*0.08, 0.05 scale rotate rot1 translate trans1 rotate rot2 rotate rot3 translate texture { pigment { color ammo_color } finish { specular 0.5 roughness 0.005 ambient 0.35 } } } // 疣の生成周期の判定 #if(mod(cnt-costal_interval+1,costal_interval*spine_interval)=0) // 住房部の疣(2列)を描くための定義 #declare cost_deg=min(240*wt, 120); sphere { // 一方の疣 <0, 0, (0.4+wt*0.08)*1.15>, (0.4+wt*0.08)*spine_ratio scale <0.7, 0.6, 1> rotate <0, -60+cost_deg, 0> rotate rot1 translate trans1 rotate rot2 rotate rot3 translate texture { pigment { color ammo_color } finish { specular 0.5 roughness 0.005 ambient 0.35 } } } sphere { // もう一方の疣 <0, 0, (0.4+wt*0.08)*1.15>, (0.4+wt*0.08)*spine_ratio scale <0.7, 0.6, 1> rotate <0, -120+cost_deg, 0> rotate rot1 translate trans1 rotate rot2 rotate rot3 translate texture { pigment { color ammo_color } finish { specular 0.5 roughness 0.005 ambient 0.35 } } } #end #else #declare dispFlg=1; // 2回目以降描画対象とする #end #declare lastX=wx; // 最後の座標を記憶 #declare lastY=wy; #declare lastZ=wz; #declare cnt=cnt+1; #declare wt=wt+t_step; #end } //--------------------------------------------------------------- // 上記の部品を組み合わせて、Didymoceras全体を構成する #declare didymoceras = union { #declare End2=vrotate(End2,<-90, 0, 0>); object { didymoceras1 rotate <-90, 0, 0> translate <0, 0, 0> } object { didymoceras2 rotate <-90, 0, 0> } object { didymoceras3 rotate <0, 0, 0> translate } } //--------------------------------------------------------------- // カメラは手前方向から、中央やや下を見て撮影 camera { location <0, 0, -7.5> look_at <0, -1, 0> } //--------------------------------------------------------------- // ライトは手前やや上と、左手からの2つで照明 light_source { <0, 2, -10> color White} light_source { <-10, 0, 0> color White} //--------------------------------------------------------------- // Didymocerasを実際に描画する object { didymoceras // U字の正面から // rotate <0, 180, 0> // <-----裏面を描画する場合は、生かす translate <-2, 2, 0> rotate <-10, -20, 0> } object { didymoceras // U字の側面から rotate <0, 90, 0> rotate <-10, 0, 0> translate <2, 2, -1> } object { didymoceras // 上面から rotate <-70, 0, 0> translate <0, -2.4, -2> }