Cylinders

Chapter 13

Cylinders

intersection

ここも Cube のときと同様にあまり書くことがない。ただ、Cube では割とていねいに intersection の解説がされていたのに、こちらでは天下り式にやり方が書かれていて写経するだけになっていたため、その部分をここに残しておく。

Cylinder

円筒部分と Ray との交点を求める。Ray  \mathbf{r}


\mathbf{r}  = \mathbf{d}t + \mathbf{o}

で、y 軸方向にのびる半径 1 の円筒は任意の y において


x^2 + z^2 = 1

となる。よって


\eqalign{
  {r_x}^2 + {r_z}^2 \cr
  &= {({d_x}t + {o_x})}^2 + {({d_z}t + {o_z})}^2 \cr
  &= {d_x}{t}^2 + 2{d_x}{o_x}t + {o_x}^2 + {d_z}{t}^2 + 2{d_z}{o_z}t + {o_z}^2 \cr
  &= {({d_x}^2 + {d_z}^2)}t^2 + 2({d_x}{o_x} + {d_z}{o_z})t + {o_x}^2 + {o_z}^2 \cr
  &= 1
}

これを  t二次方程式  a{t}^2 + bt + c = 0 と見れば、


\eqalign{
  a &= d_x^2 + d_z^2 \cr
  b &= 2(d_x o_x + d_z o_z) \cr
  c &= o_x^2 + o_z^2 - 1
}

としてあとは解の公式に当てはめるだけ。 a = 0 の時には円筒と Ray が平行なので、交点なしとする

y 軸方向に無限に長い円筒ならこれで終わりだけれど、今回実装した Cylinder は minimum と maximum を設定でき、その場合には有限の長さを持つ。
とはいえ、単に y の有効範囲があるというだけ。つまり、上記の二次方程式を解いて得た  t_0, t_1 を Ray の式に代入して  r_y を求める。


r_y  = d_yt + o_y

この  r_y (mininum, maximum) の範囲内にあれば Ray と円筒が交差する。

最後に cap 部分だけど、これもそんなに難しくはない。Ray の  y minimum, maximum になる場所での  x, z が半径 1 の円の中に収まっているかを見るだけ。

 y minimum, maximum になる場所を知るには Ray の  y 成分のみに注目すれば、


\eqalign{
  {d_y}t + o_y &= maximum \cr
  {d_y}t &= maximum - o_y \cr
  t &= \frac{maximum - o_y}{d_y}
}

で求まる。ここでは  maximum のみだけれど、  minimum についても同様。こうして求めた  t を Ray の式にあてはめればその時点での  x, z が求まるので、


  x^2 + z^2 <= 1

で判定できる。

Cone

Cone もほとんど Cylinder と変わらない計算で求まるから、ここでは側面との交点計算についてのみ書いておく。Cylinder の場合、側面は円筒で  y に関係なく常に半径は 1 だった。Cone になるとそうではなくなり、半径は  y になる。そのため、


\eqalign{
  {r_x}^2 + {r_z}^2 &= {r_y}^2\cr
  {(d_xt + o_x)}^2 + {(d_zt + o_z)}^2 &= {(d_yt + o_y)}^2\cr
  {({d_x}^2)}t^2 + 2d_xo_xt + {o_x}^2 + {d_z}^2{t}^2 + 2 d_zo_zt + {o_z}^2 &= {d_y}^2{t}^2 + 2 d_yo_yt + {o_y}^2\cr
  {({d_x}^2 - {d_y}^2 + {d_z}^2)}{t}^2 + 2(d_xo_x - d_yo_y + d_zo_z)t + {o_x}^2 - {o_y}^2 + {o_z}^2 &= 0
}

になり、


\eqalign{
  a &= {d_x}^2 - {d_y}^2 + {d_z}^2 \cr
  b &= 2({d_x}{o_x} - {d_y}{o_y} + {d_z}{o_z}) \cr
  c &= {o_x}^2 - {o_y}^2 + {o_z}^2
}

として二次方程式を解く。 a = 0 のときは  bt + c = 0 の一次方程式として


  t = -c / b

で ok。

結果

f:id:mtXTJocj:20210522145110p:plain

f:id:mtXTJocj:20210529140109p:plain