r=f(z)
という関数を考えてそれをぐるっと回転させますが、このメソッドでは、回転角度に応じて関数
f(z)
を変えて回転体を描くことができます。例えば、
theta=0
のときはf(z)
が定数で、theta=PI
のときはf(z)
は2次関数であるようにすれば、人のふくらはぎのような形も簡単に。コードはこちら。
gl_cocoon.rb
require "opengl" module GLUT def GLUT.Cocoon(height, slice, stack) return unless block_given? zStep = height/slice.to_f tStep = Math::PI/stack 0.step(height-zStep+0.0001, zStep){|z| GL.Begin(GL::QUAD_STRIP) (-Math::PI).step(Math::PI+0.0001, tStep){|theta| r1 = yield(z, theta, tStep) r2 = yield(z+zStep, theta+tStep, tStep) phi = atan(zStep/(r2-r1).abs) GL.Normal(cos(theta)*sin(phi), sin(theta)*sin(phi), cos(phi)) GL.Vertex(r1*cos(theta), r1*sin(theta), z) GL.Vertex(r2*cos(theta+tStep), r2*sin(theta+tStep), z+zStep) } GL.End } end
使い方
Z軸周りに回転します。
heightが高さ(Z軸方向の長さ)
sliceが高さ方向の刻み回数
stackが周方向の刻み回数
です。
渡すブロック内で、回転半径を返すようにしてください。
サンプル1
GLUT.Cocoon(6.0, 20, 20){|z,theta,tStep| # r = -a*z*(z-8) です。 # 回転角が PI/3から PI*2/3の時はa=0.07、 # それ以外の時は、a=0.1です。 # 新宿のコクーンタワーのような形になります。 case theta when Math::PI/3 .. 2*Math::PI/3 -0.07*z*(z-8) else -0.1*z*(z-8) end }
サンプル2 人の脛のような形も簡単に。
GLUT.Cocoon(6.0, 15, 15){|z,theta,tStep| # thetaは-PIからPIまで取るので、tは1〜0〜1と連続的に変化します。 t = (theta/Math::PI).abs # tに1.0(定数)をかけ、1-tに-0.1*z^2 + 0.5*z + 1をかけることで、 # f(z)は直線から2次曲線へと連続的に変化することになります。 1.0*t + (1-t)*(-0.1*z*z + 0.5*z+1) }
視点や光の設定などは省いています。このままでは表示されないので注意。