帮助理解这些方程?

时间:2010-07-18 05:33:33

标签: c++ c algorithm vector-graphics

我问了一个关于Bi线性变换的问题并得到了这个答案:

从您发布的那个页面,有一个指向源的链接 码。我将在

中解释双线性变换

http://www.antigrain.com/__code/include/agg_trans_bilinear.h.html

这里的想法是找到形式的转换:

output_x = a * input_x + b * input_x * input_y + c * input_y + d
output_y = e * input_x + f * input_x * input_y + g * input_y + h

术语“双线性”来自于线性的每个方程式 任何一个输入坐标本身。我们想要解决 正确的a,b,c和d值。说你有参考 矩形r1,r2,r3,r4,你要映射到(0,0),(1,0),(0,1), (1,1)(或某些图像坐标系)。

对于a,b,c,d:

0 = a * r1_x + b * r1_x * r1_y + c * r1_y + d
1 = a * r2_x + b * r2_x * r2_y + c * r2_y + d
0 = a * r3_x + b * r3_x * r3_y + c * r3_y + d
1 = a * r4_x + b * r4_x * r4_y + c * r4_y + d

对于e,f,g,h:

0 = e * r1_x + f * r1_x * r1_y + g * r1_y + h
0 = e * r2_x + f * r2_x * r2_y + g * r2_y + h
1 = e * r3_x + f * r3_x * r3_y + g * r3_y + h
1 = e * r4_x + f * r4_x * r4_y + g * r4_y + h

你可以解决这个问题但是你最喜欢。 (如果你熟悉的话 矩阵表示法,这些是矩阵的两个矩阵方程 是一样的,然后你只需要找到LU分解 一次,并解决两个未知的向量)。那么系数就是 应用于将矩形的内部映射到中的位置 矩形。


问题是,我有input_x和input_y以及r1,r2,r3,r4,但我不知道如何实现output_x和output_y。我如何解决这样的等式?我只熟悉用2个变量求解方程式。

由于

2 个答案:

答案 0 :(得分:5)

这是你发现的一个可怕的解释。希望我能帮助你了解发动机罩下发生的事情。

您要做的是将矩形区域(一个四边形)映射到另一个(任意形状)四边形。让我们从一个更简单的情况开始:线性插值(找到位于线的值)

如果你有一条从a到b的线,那么你可以使用这个等式在该线上找到任何一个'c'点:

c = ((1 - p) * a) + (p * b);

这两个位置的值“混合”(插值)沿它们之间的直线(线性)。如果使用p = 0,那么等式变为

c = (1 * a) + (0 * b)   = a

所以在p = 0时,等式给出了'a'点。

当p = 1时,等式变为:

c = (0 * a) + (1 * b)   = b

所以在p = 1时,等式给出了'b'点。

在p的中间值,你得到a和b之间的线上的点。 (所以在p = 0.5时,你得到a和b之间恰好一半的点)

因此,要将像素从屏幕上的一行复制到屏幕上的另一行,我们可以使用线性插值来查找要读取和写入的行上的位置。

for (float p = 0.0; p <= 1.0; p += 0.1)    // copy 10 pixels from line 1 to line 2
    DrawPixelOnLine2(p, GetPixelFromLine1(p));

这两种方法只会使用线性插值来计算读取和绘制像素的正确位置,如下所示:

int ax = 0, ay = 100, bx = 50, by = 170;   // line a-b goes from (0,100) to (50,170)

int px = ((1-p) * ax) + (p * bx);          // calc the x and y values separately
int py = ((1-p) * ay) + (p * by);

(请注意,我必须使用两次计算才能进行2D位置。我可以通过简单地为az / bz / pz坐标添加相同的计算来插入3D)

因此,现在您可以将点从一条任意直线复制到另一条直线。

双线插值完全相同,除了我们想在矩形内而不是在一条线内找到一个点,所以我们需要两个维度来描述该点在矩形中的位置( px沿着矩形的底部,并且py在矩形的一侧)。现在,您可以使用(px,py)坐标对定位矩形中的任何点。

为了进行上述映射,我们简单地在两个维度上进行线性插值计算:首先我们沿着底部和顶部进行插值,以找到垂直穿过矩形中间的直线的两个端点。然后我们沿着这条垂直线进行插值,找到矩形中间的最终点。

“矩形”不需要是矩形。这两个尺寸可用于任何4面形状(即您可以将矩形的角移动到任何您喜欢的位置,方程仍然可以找到角之间的位置以填充形状所包围的区域)

在您找到的示例中,作者使用四个点来描述源形状(a,b,c,d),另外四个点来描述目标形状(e,f,g,h)

此外,他们通过求解方程式来填充变换矩阵,使得计算更有效,该变换矩阵可以与点相乘以进行映射过程。但是,效果与我上面描述的相同。希望我的解释能让你更容易“看到”方程式正在做什么。

答案 1 :(得分:0)

如果要将矩形映射到另一个矩形,则需要进行简单的线性变换。要将点r映射到点q,您需要:

qx = arx + bry + c
qy = drx + ery + f

有6个变量,你需要6个方程(3个点)。要将矩形r映射到矩形q:

q1x = a*r1x + b*r1y + c
q1y = d*r1x + e*r1y + f
q2x = a*r2x + b*r2y + c
q2y = d*r2x + e*r2y + f
q3x = a*r3x + b*r3y + c
q3y = d*r3x + e*r3y + f

从上面你必须解决2个系统的3个线性方程,每个系统有3个变量。只要点不同且不共线,它们就会有1个解决方案(如果是矩形角,则可以实现)。