如何计算插值参数?
等式两边同时叉乘$\overrightarrow{AA_3}$得$\alpha:\beta=\overrightarrow{AA_2}\times\overrightarrow{AA_3}:\overrightarrow{AA_3}\times\overrightarrow{AA_1}$,同叉乘$\overrightarrow{AA_1}$得$\beta:\gamma=\overrightarrow{AA_3}\times\overrightarrow{AA_1}:\overrightarrow{AA_1}\times\overrightarrow{AA_2}$,于是:
$$ \alpha:\beta:\gamma=\overrightarrow{AA_2}\times\overrightarrow{AA_3}:\overrightarrow{AA_3}\times\overrightarrow{AA_1}:\overrightarrow{AA_1}\times\overrightarrow{AA_2} $$这非常巧合,因为最终结果不在意三个参数的绝对值,所以可以认为:
$$ \begin{cases} \alpha=\overrightarrow{AA_2}\times\overrightarrow{AA_3} \\ \beta=\overrightarrow{AA_3}\times\overrightarrow{AA_1} \\ \gamma=\overrightarrow{AA_1}\times\overrightarrow{AA_2} \end{cases} $$已知三角形三点和目标A点在光栅上的位置时,可以用三角形三点位置表示目标点位置,即可用三角形三点深度表示目标点深度。
如何编码?
这里的叉积是在光栅坐标系上的叉积,即二维的,所以由其几何意义可知α、β、γ的和为三角形面积,而每个系数的几何意义是小三角形的面积。
三角形顶点编号为1、2、3,系数α、β、γ,则:
$$ \begin{cases} \alpha=x(A_{2y}-A_{3y})+(A_{3x}-A_{2x})y+A_{2x}A_{3y}-A_{3x}A_{2y} \\ \beta=x(A_{3y}-A_{1y})+(A_{1x}-A_{3x})y+A_{3x}A_{1y}-A_{1x}A_{3y} \\ \gamma=x(A_{1y}-A_{2y})+(A_{2x}-A_{1x})y+A_{1x}A_{2y}-A_{2x}A_{1y} \end{cases} $$也可以通过除以三角形面积得到实际系数。
std::tuple<float,float,float> computeBarycentric2D(float x,float y,Eigen::Vector3f* v){
float c1 = x*(v[1].y()-v[2].y())
+(v[2].x()-v[1].x())*y
+v[1].x()*v[2].y()
-v[2].x()*v[1].y();
float c2 = x*(v[2].y()-v[0].y())
+(v[0].x()-v[2].x())*y
+v[2].x()*v[0].y()
-v[0].x()*v[2].y();
float c3 = x*(v[0].y()-v[1].y())
+(v[1].x()-v[0].x())*y
+v[0].x()*v[1].y()
-v[1].x()*v[0].y();
float sum=c1+c2+c3;
return {c1/sum,c2/sum,c3/sum};
}
如何判断点在三角形内?
将该三角形1、2、3顶点(A1、A2、A3)按顺序连成12、23、31矢量,则当$\mathrm{sign}(\overrightarrow{A_1A_2}\times\overrightarrow{A_1A})=\mathrm{sign}(\overrightarrow{A_2A_3}\times\overrightarrow{A_2A})=\mathrm{sign}(\overrightarrow{A_3A_1}\times\overrightarrow{A_3A})$时有A在三角形内。
$$ \begin{cases} \overrightarrow{A_1A_2}\times\overrightarrow{A_1A}=2S_{\triangle AA_1A_2}=\gamma \\ \overrightarrow{A_2A_3}\times\overrightarrow{A_2A}=2S_{\triangle AA_2A_3}=\alpha \\ \overrightarrow{A_3A_1}\times\overrightarrow{A_3A}=2S_{\triangle AA_3A_1}=\beta \end{cases} $$则当α、β、γ同号时有A在三角形中,所以插值深度和判断点在三角形内可以一起完成,或者认为完成这两个任务的代码可以复用。
zcxsb
点赞