内插三角形

Interpolating a triangle

我目前正在为一个简单的模拟开发一个网格,我的任务是插入一些与三角形顶点相关的值。

到目前为止我有这个:

let val1 = 10f 
let val2 = 15f 
let val3 = 12f

let point1 = Vector2(100f, 300f), val1
let point2 = Vector2(300f, 102f), val2 
let point3 = Vector2(100f, 100f), val3

let points = [point1; point2; point3]
let find (points : (Vector2*float32) list) (pos : Vector2) = 
    let (minX, minXv) = points |> List.minBy (fun (v, valu) -> v.X)
    let (maxX, maxXv) = points |> List.maxBy (fun (v, valu)-> v.X)
    let (minY, minYv) = points |> List.minBy (fun (v, valu) -> v.Y)
    let (maxY, maxYv) = points |> List.maxBy (fun (v, valu) -> v.Y)
    let xy = (pos - minX)/(maxX - minX)*(maxX - minX)
    let dx = ((maxXv - minXv)/(maxX.X - minX.X))
    let dy = ((maxYv - minYv)/(maxY.Y - minY.Y))
    
    ((dx*xy.X + dy*xy.Y)) + minXv

从哪里可以得到构成三角形的点列表。我找到最小的 X 和 Y 以及最大的 X 和 Y 以及与之关联的相应值。

问题是这种方法只适用于直角三角形。对于等边三角形,中点最终会在其顶点处具有比设置值更高的值。

所以我想这里的方法基本上是投影一个直角三角形并在任何三角形和这个投影三角形之间创建某种变换矩阵?

这是正确的吗?如果没有,那么任何指针将不胜感激!

您可能想要一个 linear interpolation,其中插值是

形式的函数的结果
f(x, y) = a*x + b*y + c

如果你在 3d 中考虑这个,(x,y) 一个在地面上的位置和 f(x,y) 它上面的高度,这个公式会给你一个平面。

获取参数你可以使用你拥有的点数:

f(x1, y1) = x1*a + y1*b * 1*c = v1        ⎛x1 y1 1⎞   ⎛a⎞   ⎛v1⎞
f(x2, y2) = x2*a + y2*b * 1*c = v2        ⎜x2 y2 1⎟ * ⎜b⎟ = ⎜v2⎟
f(x3, y3) = x3*a + y3*b * 1*c = v3        ⎝x3 y3 1⎠   ⎝c⎠   ⎝v3⎠

这是一个 3×3 system of linear equations:三个方程,三个未知数。

您可以通过多种方式解决这个问题,例如使用 Gaussian elimination, the inverse matrix, Cramer's rule 或一些线性代数库。数值专家可能会告诉您,这些方法之间的数值稳定性存在差异,特别是当三角形的角接近位于一条直线上时。但只要您远离那种退化的情况,它可能不会对简单的用例产生巨大的实际影响。请注意,如果您想相对于单个三角形对多个位置的值进行插值,您只需计算 a,b,c 一次,然后只需对每个输入位置使用简单的线性公式,这可能会导致相当大的加速.

高级信息:对于某些应用程序,线性插值不够好,但要找到更合适的东西,您需要提供比您的问题建议的可用数据更多的数据。我想到的一个例子是用于 3D 渲染的三角形网格。如果您使用线性插值将三角形映射到纹理坐标,那么它们将沿着边缘排列,但映射的方向可能会突然改变,从而导致明显的接缝。一种投影插值或加权插值可以避免这种情况,正如我从一篇关于 conformal equivalence of triangle meshes(Springborn、Schröder、Pinkall,2008)的论文中了解到的那样,但为此你需要知道世界坐标中的三角形如何映射到纹理坐标中的三角形,并且您还需要三角形网格和与纹理的对应关系才能与此映射兼容。然后你将以这样一种方式进行映射,你不仅可以将角传输到角,还可以将外接圆传输到外接圆。