ジオメトリ(形状)

ジオメトリ(Geometry)とは

ジオメトリとは、3次元空間に配置する物体の「形状」を表現するデータ(頂点・辺・面など)の集まりです。

3次元空間に配置する物体の「基本形状」と表現すると分かりやすいかも知れません。

直方体・球・平面・三角錐・四角錐・トーラス・etc…と、多種多様な形状のジオメトリが、標準機能として用意されています。

ジオメトリは、物体の形状・サイズを決めるものですが、それだけでは3次元空間に配置することはできません。

物体は、形状の他にも、表面材質と位置情報が伴わないと、3次元空間に配置してカメラで撮影することができないためです。

材質と位置情報はそれぞれ後述しますが、ここでは代表的なジオメトリの種類と、その生成方法を見ていきましょう。

BoxGeometry(直方体)

直方体を表すジオメトリです。

initializeメソッドは以下のようになります。

Mittsu::BoxGeometry.new(width, height, depth, segment_w = 1, segment_h = 1, segment_d = 1) #-> BoxGeometry
引数意味
width横幅
height縦幅
depth奥行
segment_w横方向の分割数
segment_h縦方向の分割数
segment_d奥行方向の分割数

(例)

横・縦・奥行の大きさをそれぞれ1とし、各方向に4分割した立方体。

geometry = Mittsu::BoxGeometry.new(1, 1, 1, 4, 4, 4)

上記で生成したジオメトリを、ワイヤーフレームマテリアルを適用の上でメッシュ化して表示したものが以下になります。

横・縦・奥行のそれぞれの方向に4分割ずつされて、四角ポリゴンが4 * 4 * 4 = 64個で構成されていることが分かります。

SphereGeometry(球)

球体を表すジオメトリです。

initializeメソッドは以下のようになります。

Mittsu::SphereGeometry.new(
  radius = 50.0, width_segments = 8, height_segments = 6,
  phi_start = 0.0, phi_length = (::Math::PI * 2.0),
  theta_start = 0.0, theta_length = ::Math::PI) #-> SphereGeometry
引数意味
radius球の半径
width_segments横方向の分割数
height_segments縦方向の分割数
phi_start水平方向の描画開始角度(単位: rad)
phi_length水平方向の描画量(単位: rad)
theta_start垂直方向の描画開始角度(単位: rad)
theta_length垂直方向の描画量(単位: rad)

(例)

半径を1とし、縦・横それぞれ16分割した球は以下のようになります。

geometry = Mittsu::SphereGeometry.new(1, 16, 16)

上記で生成したジオメトリを、ワイヤーフレームマテリアルを適用の上でメッシュ化して表示したものが以下になります。

phi_*, theta_* について

これらのオプションを指定する機会はあまり無いかもしれませんが、それぞれ水平・垂直方向の描画量を決めるパラメータです。

例えば、水平方向の描画開始角度(phi_start)を0.0とし、描画量(phi_length)を、デフォルトの半分である π(Math::PI)に設定した場合に描画されるジオメトリは以下のように縦に切られた半球となります。

geometry = Mittsu::SphereGeometry.new(1, 16, 16, 0.0, Math::PI)

theta_start, theta_lengthをそれぞれ0.0, π/2(デフォルトの半分)にすると、当然ながら横方向に切られたような半球になります。

geometry = Mittsu::SphereGeometry.new(1, 16, 16, 0.0, Math::PI * 2, 0.0, Math::PI / 2)
PlaneGeometry(平面)

平面を表すジオメトリです。

initializeメソッドは以下のようになります。

Mittsu::PlaneGeometry.new(width, height, width_segments = 1, height_segments = 1) #-> PlaneGeometry
引数意味
width横幅
height縦幅
width_segments横方向の分割数
height_segments縦方向の分割数

(例)

横幅を4、縦幅を1とし、縦・横それぞれ4分割した平面は以下のようになります。

geometry = Mittsu::PlaneGeometry.new(4, 1, 4, 4)

上記で生成したジオメトリを、ワイヤーフレームマテリアルを適用の上でメッシュ化して表示したものが以下になります。

CylinderGeometry(円筒)

円筒を表すジオメトリです。

initializeメソッドは以下のようになります。

Mittsu::CylinderGeometry.new(
  radius_top = 20.0, radius_bottom = 20.0, height = 100.0,
  radial_segments = 8, height_segments = 1, open_ended = false,
  theta_start = 0.0, theta_length = Math::PI * 2.0) #-> CylinderGeometry
引数意味
radius_top上端部の半径
radius_bottom下端部の半径
height円筒の高さ
radial_segments円周方向の分割数
height_segments高さ方向の分割数
open_ended終端部を閉じるか開くか(true: 開く=リレーのバトンのような、末端が開いた円筒となる)
theta_start垂直方向の描画開始角度(単位: rad)
theta_length垂直方向の描画量(単位: rad)

(例)

全てデフォルト値で構成した円筒は以下のようになります。

geometry = Mittsu::CylinderGeometry.new

上記で生成したジオメトリを、ワイヤーフレームマテリアルを適用の上でメッシュ化して表示したものが以下になります。

CircleGeometry(円)

平面の円を表すジオメトリです。

initializeメソッドは以下のようになります。

Mittsu::CircleGeometry.new(
  radius = 50.0, segments = 8,
  theta_start = 0.0, theta_length = (::Math::PI * 2.0)) #-> CircleGeometry
引数意味
radius上端部の半径
segments下端部の半径
height円筒の高さ
theta_start描画開始角度(単位: rad)
theta_length描画量(単位: rad)

(例)

半径を1、分割数を8(デフォルト)とした円は以下のようになります。

geometry = Mittsu::CircleGeometry.new(1)

上記で生成したジオメトリを、ワイヤーフレームマテリアルを適用の上でメッシュ化して表示したものが以下になります。

その他のジオメトリ

Ruby合宿2022において使用する主なジオメトリは上記の通りです。

その他のジオメトリについては、名称とinitializeメソッドの仕様だけ以下に列挙します。

DodecahedronGeometry
Mittsu::DodecahedronGeometry.new(radius = 1.0, detail = 0) #-> DodecahedronGeometry
IcosahedronGeometry
Mittsu::IcosahedronGeometry.new(radius = 1.0, detail = 0) #-> IcosahedronGeometry
LatheGeometry
Mittsu::LatheGeometry.new(points, segments = 12, phi_start = 0.0, phi_length = (::Math::PI * 2.0)) #-> LatheGeometry
OctahedronGeometry
Mittsu::OctahedronGeometry.new(radius = 1.0, detail = 0) #-> OctahedronGeometry
ParametricGeometry
Mittsu::ParametricGeometry.new(func, slices, stacks) #-> ParametricGeometry
PolyhedronGeometry
Mittsu::PolyhedronGeometry.new(vertices, indices, radius = 1.0, detail = 0) #-> PolyhedronGeometry
RingGeometry
Mittsu::RingGeometry.new(inner_radius = 0.0, outer_radius = 50.0, theta_segments = 8, phi_segments = 8, theta_start = 0.0, theta_length = (::Math::PI * 2.0)) #-> RingGeometry
TetrahedronGeometry
Mittsu::TetrahedronGeometry.new(radius = 1.0, detail = 0) #-> TetrahedronGeometry
TorusGeometry
Mittsu::TorusGeometry.new(radius = 100.0, tube = 40.0, radial_segments = 8, tubular_segments = 6, arc = (::Math::PI * 2.0)) #-> TorusGeometry
TorusKnotGeometry
Mittsu::TorusKnotGeometry.new(radius = 100.0, tube = 40.0, radial_segments = 64, tubular_segments = 8, p_val = 2, q_val = 3) #-> TorusKnotGeometry