三角形的插值

时间:2012-01-02 04:57:38

标签: geometry interpolation

我有一个单位直角三角形和3个顶点中的每个顶点的值。 我需要插值以在三角形内的某个点找到值。 几个小时的搜索没有发现实际上告诉我如何做到这一点。 这是我最接近的尝试,实际上非常接近但不太正确 -

                result = 
                v1 * (1 - x) * (1 - y) +
                v2 * x * (1 - y) +
                v3 * x * y;

v1,v2和v3是三角形的3个顶点处的值。 (x,y)是您试图找到值的三角形中的点。

任何一种方法都可以帮助我。它不一定需要是单位/右三角形。

更新信息: 我有一个均匀间隔点的网格和每个点的值。 我在网格上最近的3个点做了一个三角形。 这是一张图片来说明它 - enter image description here
所以我必须在5,3和7之间进行插值以找到x的值。 该点也可以位于另一个三角形内,这意味着您将在5,7之间进行插值,并在方形的左下角进行插值。

在我展示的代码中,v1 = 5,v2 = 3,v3 = 7 x是“x”方向的分数距离(范围[0-1]),y是“y”方向的分数距离。
在图片的例子中,x可能约为0.75,y约为0.2

这是我最接近的尝试 -
enter image description here
使用 -

创建
        if (x > y) //if x > y then the point is in the upper right triangle
            return
                v1 * (1 - x) * (1 - y) +
                v2 * x * (1 - y) +
                v3 * x * y;
        else //bottom left triangle
            return
                v1 * (1 - x) * (1 - y) +
                v4 * (1 - x) * y +
                v3 * x * y;

又一次尝试 -
enter image description here
使用 -

创建
if (x > y)
            return
                (1 - x) * v1 + (x - y) * v2 + y * v3;
        else
            return
                (1 - y) * v1 + (y - x) * v4 + x * v3;

它们都接近我的需要,但显然不太正确。

5 个答案:

答案 0 :(得分:9)

您应该使用重心坐标。这里有一个非常详尽的文章,也讨论了替代解决方案以及为什么重心坐标最佳:CodePlea - Interpolating in a Triangle

基本上,权重最终看起来像这样:

enter image description here

答案 1 :(得分:7)

实际上,最简单和最强大的解决方案是基于重心坐标 -

http://answers.unity3d.com/questions/383804/calculate-uv-coordinates-of-3d-point-on-plane-of-m.html

答案 2 :(得分:2)

3年前我问过这个问题,并且仍在努力实现这一目标。我相信除非使用等边三角形,否则是不可能的。 这是一个很好的方法,使用重心坐标,然后添加一个摆脱大多数工件的技术。 v1,v2,v3是三角形三个点的值。 x,y是您要为其找到值的点。

if (x > y)
        {
            b1 = -(x - 1);
            b2 = (x - 1) - (y - 1);
            b3 = 1 - b1 - b2;
        }
        else
        {
            b1 = -(y - 1);
            b2 = -((x - 1) - (y - 1));
            b3 = 1 - b1 - b2;
        }

        float
            abs = x - y;
        if (abs < 0) abs *= -1;
        if (abs < 0.25f)
        {
            abs = 0.25f - abs;
            abs *= abs;
            b1 -= abs;
            b3 -= abs;
        }

        b1 *= b1;
        b2 *= b2;
        b3 *= b3;
        float fd = 1 / (b1 + b2 + b3);
        b1 *= fd;
        b2 *= fd;
        b3 *= fd;

        return
                v1 * b1 +
                v2 * b2 +
                v3 * b3;

答案 3 :(得分:1)

好的,我们将进行线性插值,假设梯度相对于x和y是恒定的。 d/dx = v2 - v1d/dy = v3 - v2以及f(0,0) = v1。我们有一个简单的二维微分方程。

d{f(x,y)} = (v2 - v1)*dx
f(x,y) = (v2 - v1)*x + g(y)
d{f(x,y)} = g'(y) = (v3 - v2)*dy
g(y) = (v3 - v2)*y + C
f(x,y) = (v2 - v1)*x + (v3 - v2)*y + C
f(0,0) = v1 = (v2 - v1)*0 + (v3 - v2)*0 + C = C
f(x,y) = (v2 - v1)*x + (v3 - v2)*y + v1

或就v1 v2和v3而言

f(x,y) = (1 - x)*v1 + (x - y)*v2 + y*v3

如果你想在四个顶点的正方形中进行,如上所述,左下角的v4在x = 0 y = 1,这里是条件:d/dx = (v2 - v1) (1 - y) + (v3 - v4) yd/dy = (v3 - v2) x + (v4 - v1) (1 - x),{ {1}}

f(0,0) = v1

答案 4 :(得分:0)

这是最近邻居的一些伪代码:

if( dist( p, p1 ) <= dist( p, p2 ) && dist( p, p1 ) <= dist( p, p3 ) )
  return val( p1 )
if( dist( p, p2 ) <= dist( p, p3 ) && dist( p, p2 ) <= dist( p, p1 ) )
  return val( p2 )
if( dist( p, p3 ) <= dist( p, p1 ) && dist( p, p3 ) <= dist( p, p2 ) )
  return val( p3 )

我认为这也会产生一个voronoi图