Geometry 三角形的插值

Geometry 三角形的插值,geometry,interpolation,Geometry,Interpolation,我有一个单位直角三角形和3个顶点的值。 我需要插值来找到三角形内某一点的值。 数小时的搜索并没有发现任何能告诉我如何做的东西。 这是我最近的一次尝试,实际上非常接近,但并不完全正确- result = v1 * (1 - x) * (1 - y) + v2 * x * (1 - y) + v3 * x * y; v1、v2和v3是三角形3个顶点处的值。 (x,y)是

我有一个单位直角三角形和3个顶点的值。 我需要插值来找到三角形内某一点的值。 数小时的搜索并没有发现任何能告诉我如何做的东西。 这是我最近的一次尝试,实际上非常接近,但并不完全正确-

                result = 
                v1 * (1 - x) * (1 - y) +
                v2 * x * (1 - y) +
                v3 * x * y;
v1、v2和v3是三角形3个顶点处的值。 (x,y)是三角形中试图求其值的点

任何一种方法都会对我有所帮助。它不一定是一个单位/直角三角形

更新信息: 我有一个等间距点的网格,每个点都有一个值。 我用网格上最近的3个点做一个三角形。 下面是一张图片来说明它-
所以我必须在5,3,和7之间插值才能得到x的值。 该点也可以位于另一个三角形内,这意味着您将在5、7和正方形左下角的值之间进行插值

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

以下是我最近的尝试-

使用以下内容创建:

        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;
if (x > y)
            return
                (1 - x) * v1 + (x - y) * v2 + y * v3;
        else
            return
                (1 - y) * v1 + (y - x) * v4 + x * v3;
还有另一次尝试-

使用以下内容创建:

        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;
if (x > y)
            return
                (1 - x) * v1 + (x - y) * v2 + y * v3;
        else
            return
                (1 - y) * v1 + (y - x) * v4 + x * v3;

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

好的,我们将做一个线性插值,假设梯度对于x和y是常数
d/dx=v2-v1
d/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)y
d/dy=(v3-v2)x+(v4-v1)(1-x)
f(0,0)=v1

d/dx = (v2 - v1) (1 - y) + (v3 - v4) y
f(x,y) = (v2 - v1) (1 - y) x + (v3 - v4) y x + g(y)
d/dy = (v3 - v2) x + (v4 - v1) (1 - x) = -(v2 - v1) x + (v3 - v4) x + g'(y)
v3 - v2 + (v4 - v1) / x + v4 - v1 = -v2 + v1 + v3 - v4 + g'(y) / x
(v4 - v1) / x + 2*(v4 - v1) = g'(y) / x
g'(y) = (v4 - v1) + 2 x (v4 - v1)
g(y) = (v4 - v1) (1 + 2 x) y + C
f(x,y) = (v2 - v1) (1 - y) x + (v3 - v4) y x + (v4 - v1) (1 + 2 x) y + C
f(0,0) = (v2 - v1) (1 - 0) 0 + (v3 - v4) 0 0 + (v4 - v1) (1 + 2 0) 0 + C = v1
f(x,y) = (v2 - v1) (1 - y) x + (v3 - v4) y x + (v4 - v1) (1 + 2 x) y + v1

下面是最近邻的一些伪代码:

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 )

if(dist(p,p1)我三年前问过这个问题,现在仍在研究一种方法。我确信,除非使用等边三角形,否则没有伪影是不可能做到的。
这里是一个不错的方法,使用重心坐标,然后添加一个技术,消除大部分的工件。
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;
if(x>y)
{
b1=-(x-1);
b2=(x-1)-(y-1);
b3=1-b1-b2;
}
其他的
{
b1=-(y-1);
b2=-((x-1)-(y-1));
b3=1-b1-b2;
}
浮动
abs=x-y;
如果(abs<0)abs*=-1;
如果(abs<0.25f)
{
abs=0.25f—abs;
abs*=abs;
b1-=abs;
b3-=abs;
}
b1*=b1;
b2*=b2;
b3*=b3;
浮动fd=1/(b1+b2+b3);
b1*=fd;
b2*=fd;
b3*=fd;
返回
v1*b1+
v2*b2+
v3*b3;

实际上,最简单、最稳健的解决方案是基于重心坐标-


你应该使用重心坐标。这里有一篇非常详尽的文章,也讨论了替代解决方案以及重心坐标最佳的原因:

基本上,权重最终将如下所示:


那么哪个顶点是哪个?告诉我坐标系是如何工作的,x和y的方向以及v1、v2和v3的位置。@Dan好的,我更新了一些信息,以更深入地说明我在做什么。你有具体的解释方法吗?线性/双线性/最近邻?三角形在这里真的很重要吗?四点插值可以吗?4点双线性插值是我通常的做法,但看起来我可以通过使用三角形来大大提高速度。我通常在v1和v2之间进行插值,然后在v3和v4之间进行插值,然后在这两个新值之间再次进行插值以获得最终值。我想做一些类似的事情,但要使用三角形。我需要某种形式的线性插值重新定位,因为最近的邻居只会生成大的彩色正方形,而不是正方形。它只会在使用正方形位置的采样点时生成正方形,并且您指定了三角形。抱歉,我的意思是它将生成大的纯色三角形*不,它不会。它将具有大的纯色区域,但不会生成三角形-这将生成4边形状。对于一个点,它将使两条边成为三角形外边缘的一半,两条线的垂直平分线与其他点。啊,好的。我还没有测试出来,但问题是它不适合工作。所以假设这将得到正确的值,我还必须考虑不在右上三角形中的点le,将在正方形的左下部分。因此我还需要一个v4。我尝试了这个-
if(x>y)//如果点在右上角三角形中,返回(1-x)*v1+(x-y)*v2+y*v3;else//如果点位于左下角的三角形返回(1-x)*v1+(x-y)*v4+y*v3;
但是它不起作用,你试图生成什么样的梯度?如果你想基于一个正方形,那么它会有点复杂,因为
d/dx=(v2-v1)(1-y)+(v3-v4)y
d/dy=(v3-v2)x+(v4-v1)(1-x)
。这仍然是可能的。不太确定你在问什么,但我正在制作一个平滑的噪波函数。我使用全平方和双线性插值,类似于柏林噪波,但我尝试使用三角形而不是正方形。我找到了一个非常接近的方法,但伪影非常糟糕。比如说,可以吗你把照片贴上去了吗