クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

レイと球の交差判定

このレッスンのあとで: レイと球が当たるかを判定し、当たる場所までの距離を求められる。

90分のレッスンコマンド2件コンピュータビジョンラボ:JupyterLab でピクセル、しきい値、物の数え方

レイを飛ばして、球に当たるか調べる

レイトレーシングでは、目から画面のピクセルへ向けて、レイと呼ぶ半直線を飛ばし、何に当たるかを調べます。球に当たるかどうかは、2次方程式を解くだけで分かります。

このレッスンでは、レイを式で表し、球との交差を判定して、当たる場所までの距離を求めます。

このレッスンのゴール

メモ

レイと球が当たるかを判定し、当たる場所までの距離を求められる。

キーワード

ことばいみれい
レイ出発点から、ある向きへ伸びる半直線
方向レイが進む向きを表す3つの数(0, 0, 1)
内積対応する数をかけて、足した値
判別式2次方程式の解の数を決める値
交点レイと球が当たる点

学生が入力するセルは、このプレビューでは空白です。

レイは、出発点と方向で決まる

レイは、出発点 o から、方向 d へ伸びる半直線です。レイの上の点は、o + t × d と書けます。t は 0 以上の数で、どこまで進んだかを表します。

方向 d の長さが 2 なら、t が 1 増えるごとに、2 進みます。点は (x, y, z) の3つの数で表します。

レイの上の点の例

to + t × d の計算点
0o = (1, 0, 0)、d = (0, 1, 2)(1, 0, 0)
1(1, 0, 0) + 1 × (0, 1, 2)(1, 1, 2)
3(1, 0, 0) + 3 × (0, 1, 2)(1, 3, 6)

学生が入力するセルは、このプレビューでは空白です。

球は、中心から同じ距離にある点の集まり

球は、中心 m から、距離が半径 r の点の集まりです。点 p が球の上にあるのは、p と m の距離の2乗が、r の2乗に等しいときです。

レイの点 o + t × d を、この式に入れると、t についての2次方程式になります。これを解けば、レイが球に当たる t が分かります。

判別式が、当たるかどうかを決める

2次方程式は、a × t² + b × t + c = 0 の形になります。a は d と d の内積、b は d と (o − m) の内積の 2 倍、c は (o − m) と (o − m) の内積から r² を引いた値です。

判別式は b² − 4 × a × c です。負なら外れ、0 なら1点にかすり、正なら2点で当たります。

判別式と当たり方

判別式当たり方解の数
負外れる0
01点にかする1
正2点で当たる2

学生が入力するセルは、このプレビューでは空白です。

a、b、c と判別式を求める

コード: python
o = [0, 0, 0]
d = [0, 0, 1]
m = [0, 0, 7]
r = 2
offset = [o[0] - m[0], o[1] - m[1], o[2] - m[2]]
a = d[0] * d[0] + d[1] * d[1] + d[2] * d[2]
b = 2 * (d[0] * offset[0] + d[1] * offset[1] + d[2] * offset[2])
c = offset[0] ** 2 + offset[1] ** 2 + offset[2] ** 2 - r * r
print(a, b, c)
print("判別式:", b * b - 4 * a * c)
# m を [0, 5, 7] に変えて、もう一度実行します。
# 判別式は、負になりますか。

中心 (0, 0, 7)、半径 2 の球の計算

値計算結果
a(0, 0, 1) と (0, 0, 1) の内積1
b2 × (0, 0, 1) と (0, 0, -7) の内積-14
c49 − 445
判別式(-14)² − 4 × 1 × 4516
t(14 ± 4) ÷ 25 と 9

学生が入力するセルは、このプレビューでは空白です。

2次方程式の解を numpy で確かめる

numpy の roots は、2次方程式の解を求めます。a、b、c の順に渡します。

次のコマンドは、a = 1、b = -14、c = 45 の解を表示します。出力は [9. 5.] で、t が 9 と 5 の2点で当たります。小さい方の t = 5 が、手前の交点 (0, 0, 5) です。

a = 1、b = -14、c = 45 の解を求める

コマンド
docker exec jupyter python3 -c "import numpy as np; print(np.roots([1, -14, 45]))"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

手前の交点は、0 より大きい最小の t

2つの解のうち、レイが先に通るのは、小さい方の t です。ただし、t が負なら、その点はレイの後ろにあります。

t が両方とも負なら、球はレイの後ろにあり、当たりません。出発点が球の中なら、小さい方は負で、大きい方が出口になります。

よくある間違い

注意

判別式が正なら、必ず球に当たると考えがちです。判別式が教えるのは、レイをのばした直線との交わりです。t が負なら、当たる点はレイの後ろなので、t の符号も調べます。

レイを全ピクセルに飛ばして、形を見る

すべてのピクセルから、同じ向きにレイを飛ばしたとします。球を正面から見ると、ピクセル (x, y) のレイが、中心 (10, 5)、半径 4 の球に当たるのは、(x − 10)² + (y − 5)² が 16 以下のときです。

次のコマンドは、当たるピクセルを # で、外れるピクセルを . で、21 × 11 の枠に並べます。真ん中の行は # が9個で、上から2行目と下から2行目は1個です。丸い形が見えます。

球の輪郭を # と . で表示する

コマンド
docker exec jupyter python3 -c "print(chr(10).join(''.join('#' if (x - 10) ** 2 + (y - 5) ** 2 <= 16 else '.' for x in range(21)) for y in range(11)))"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

このラボとソースについて: コンピュータビジョンラボ:JupyterLab でピクセル、しきい値、物の数え方

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。