Ink

Contents related to tech, hobby, etc

直線をAAにラスタライズする

|

直線をAAにラスタライズする

Cj-bc/brick-3d を作成している間、「二つの頂点を結ぶ直線をAAに落としこむ」作業が 必要になったのでメモ。 今回は二つの頂点は平面上にあるものとして扱いますが、他の次元でも同じだと思います。

  • 二つの頂点を結ぶ直線の式は \vec{begin} + t(\vec{end} - \vec{begin}) ( t \in [0..1] )

  • tが0の時は \vec{begin} 、1の時は \vec{end} になる

  • tをよしなな感覚で0~1の間で取ってやり、それを一つめに示した式に入れる

前提知識

  • ベクトルについてちょっと

  • 媒介変数

ベクトルと媒介変数を用いた直線の式

まず直線の式を考えます。二つの頂点は位置ベクトルとして捉えます。 この二点を \vec{begin}\vec{end} とおくことにすると、 この2点間を結ぶベクトル \vec{v} の式は

\begin{align} \vec{v} &= \vec{end} - \vec{begin} \end{align}

となります。

これはベクトルなので実数を掛けることができ、 0をかけると長さ0のベクトル、1を掛けるとそのままのベクトルが出来ます。

\begin{align} \vec{v} \times 0 &= 0 \\ \vec{v} \times 1 &= \vec{v} \end{align}

そこで、媒介変数 t を0から1の間の数を持たせてやると、 これは \vec{v} 上の点を表す式(=線分の式)になります。

\begin{align} f(t) &= t\vec{v} \end{align}

このベクトルは位置ベクトルではないため空間上のどこに存在しても良い状態なので、 ベクトルの開始地点を \vec{begin} に移してあげます。

\begin{align} f'(t) = \vec{begin} + \vec{v} \end{align}

これで直線の式になります。

直線の式からその上にある頂点を計算する

媒介変数表示の式になっているので、後は t の値を少しずつ ずらしていってあげれば、線分上の頂点が得られます。

自分のプロジェクトではHaskellで書いていたのでそのまま書かせてもらうと:

type Vertex = (Flaot, Float)

-- | 先程の「媒介変数で表示した直線の式」
f :: Float -> Vertex

-- | 細分化したt。
-- Haskellでは, xからyまでの範囲の値のリスト [x..y]
-- をFloatで作れないため, 一度Int型で0~100までの値のリストを生成して
-- その全てを100で割っている
ts :: [Float]
ts = fmap (/ 100) [0..100]

-- | 直線上にある 'Vertex' のリスト
vertices = fmap f ts

という感じ(実際に使っているコードとは違う)

おまけ: 実際に使っている部分