LoginSignup
9
5

More than 1 year has passed since last update.

三角形内の線形補間

Posted at

三角形の各頂点が値を持つときに、三角形内の任意の位置でその値を線形補間します。

三角形の各頂点位置を$\boldsymbol{p}_0, \boldsymbol{p}_1, \boldsymbol{p}_2$とすると 、三角形内の任意の位置$\boldsymbol{p}$は次のように表現できます。

\boldsymbol{e}_u = \boldsymbol{p}_1 - \boldsymbol{p}_0 \\
\boldsymbol{e}_v = \boldsymbol{p}_2 - \boldsymbol{p}_0 \\
\boldsymbol{p} = \boldsymbol{p}_{0} + u\boldsymbol{e}_u + v\boldsymbol{e}_v\\
(u\geqq0,v\geqq0, u+v\leqq1)

ここで各頂点の補間したい値を$C_0,C_1,C_2$とすると、位置$\boldsymbol{p}$における補間値$C$は次のようになります。

C = C_0+u(C_1-C_0)+v(C_2-C_0)

ということで、$\boldsymbol{p}$に関して$u,v$が求まれば、補間値$C$が求まります。

先ほどの$\boldsymbol{p}$を各要素ごとに展開すると次のようになります(ここでは2次元の場合を考えますが、3次元でも同じだと思います)。

\boldsymbol{p}_0 = \left(\begin{array}{cc} p_{0x} \\ p_{0y}\\ \end{array} \right),
\boldsymbol{e}_u = \left(\begin{array}{cc} e_{ux} \\ e_{uy}\\ \end{array} \right),
\boldsymbol{e}_v = \left(\begin{array}{cc} e_{vx} \\ e_{vy}\\ \end{array} \right) \\

\boldsymbol{p} = \left(\begin{array}{cc} p_{x} \\ p_{y}\\ \end{array} \right) = \left(\begin{array}{cc} p_{0x}+ue_{ux}+ve_{vx} \\ p_{0y}+ue_{uy}+ve_{vy}\\ \end{array} \right)

これを$u,v$についての整理すると次のようになり、$u,v$に関する連立方程式となります。

\left\{
\begin{array}{l}
e_{ux}u+e_{vx}v = p_x - p_{0x} \\
e_{uy}u+e_{vy}v = p_y - p_{0y}
\end{array}
\right.

この連立方程式を解くと、$u,v$は次のように求まります。

\left\{
\begin{array}{l}
u=\frac{-e_{vx}(p_y-p_{0y})+e_{vy}(p_x-p_{0x})}{e_{ux}e_{vy}-e_{vx}e_{uy}} \\
v=\frac{e_{ux}(p_y-p_{0y})-e_{uy}(p_x-p_{0x})}{e_{ux}e_{vy}-e_{vx}e_{uy}}
\end{array}
\right.

これをGLSLで実装すると、以下のようになります。ここでは補間する値を三次元ベクトルにしています。

vec3 lerpTriangle(vec2 p, vec2 p0, vec2 p1, vec2 p2, vec3 c0, vec3 c1, vec3 c2) {
    vec2 eu = p1 - p0;
    vec2 ev = p2 - p0;
    
    float d = eu.x * ev.y - ev.x * eu.y;
    float a = p.y - p0.y;
    float b = p.x - p0.x;
    
    float u = (-ev.x * a + ev.y * b) / d;
    float v = (eu.x * a - eu.y * b) / d;
    
    return c0 + u * (c1 - c0) + v * (c2 - c0);
}

三角形の各頂点に赤、緑、青の値を持たせると次のように補間されます。
KodeLife 2022-04-26 at 19.31.06 0000.png


以下の記事を参考にしました。

9
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5