将坐标从一个畸变的坐标系转换到另一个

这个问题最好用一个例子来解释:

http://dl.dropbox.com/u/1013446/distortedcoordinatespace.exe

将小红色方块拖放到右边的小方块内。 它对应于左边大四边形的红色方块。 您还可以拖动左侧大四边形的四个角,以查看它如何占据正方形内空间的扭曲版本。

给定一个正方形的四个点的绝对坐标以及正方形内任意点的坐标,将点的坐标重新映射到一个任意的四边形是很简单的。

我想要的是能够以任意的四边形开始,并能够做同样的事情,将四边形变换为任何其他四边形,但保持点的相对扭曲位置,

所以考虑到2个不规则四边形A和B中的每一个的4个绝对坐标,如何将C点的坐标转换为绝对坐标?

也很有帮助,我会在这里错过任何这些转换将被称为的术语,因为我想更多地了解它们

好吧,我试图实施btilly的解决方案,这是我迄今为止:

   #include<complex>
#define cf complex<float>

cf i=sqrt(complex<float>(-1));

cf GetZ(float x,float y)
{
    return cf(x)+(cf(y)*i);
}

cf GetPathIntegral(cf p1,cf p2,cf q1,cf q2, int n)
{
    cf sum;
    for (int index=0;index<=n;index++)
    {
        cf s=cf(float(index)/float(n));
        cf weight;
        if (index==0||index==n)
            weight=1;
        else if(index%2)
            weight=4;
        else weight =2;


        sum+=(((cf(1)-s)*q1)+(s*q2))*(p2-p1)*weight;
    }
    return sum/cf((3.0*(n-1.0)));
}

在我从这里前进之前,我想确保我目前为止是......

另外,这一段让我困惑了一下:

好的,我们可以做路径积分。 那是什么价值? 那么假设我们在我们地区的某个地方有一个随机点z0 = x + iy。 假设f(z)在路径上定义。 然后Cauchy积分公式说明f(z)/(2 *π* i *(z-z0))的区域周围的积分(这是我们知道如何做的4个分段积分的总和)是一个真正的很好的功能,这将匹配我们在边界上的原始功能。

函数做了什么?


(我的第一个传球是一个自然而然的表达式的复杂推导,但后来我意识到有一个更好的解决方案,如果我在过去的20年中使用了复杂分析,那么我早就会记得这一点。)

正确的做法是应用Cauchy积分公式。 有了这个,你可以将任何多边形映射到任何其他多边形。 如果多边形不是自相交的,则它将边界发送到边界,内部发送到内部。 该映射也将具有共形的优异属性,这意味着角度得以保留。 我的意思是,如果一对曲线在你的区域相交,那么它们将被映射到一对以相同角度相交的曲线。 (埃舍尔的许多绘图都是基于共形映射的。)

足够的炒作。 你怎么做呢? 我会解释它,假设你对复杂分析一无所知。 我将使用一些微积分术语,但即使您根本不知道任何微积分,您也应该能够遵循我的指导。 由于我假设这么少,所以解释必须很长。 我很抱歉。

真实平面中的每个点(x, y)都可以看作一个复数z = x + iy 。 我们可以使用通常的代数规则和i * i = -1的事实来添加和乘上复数。 此外注意1 = (x + iy) * (x - iy)/(x2 + y2)所以如果我们让1/z = (x - iy)/(x2 + y2) 因此我们拥有所有通常的算术规则。

但我们可以做得比这更好。 我们可以做微积分。 特别是我们可以在曲线周围进行路径积分。 沿着曲线的函数的积分是该函数在该曲线上的点的加权平均。 你可以阅读如何做到这一点。 但在这种情况下,如何做到这一点。

假设起始区域具有角落P1, P2, P3, P4 。 区域周围的路径由四条线段(P1, P2), (P2, P3), (P3, P4), (P4, P1) 。 我会谈谈如何处理第一条线段。 其他人是相似的。

f(z)(P1, P2)上的路径积分是f((1-s)P1 + sP2)(P2 - P1)从0到1的积分。 为了评估积分,最简单的事情就是使用辛普森规则进行数值积分。 要做到这一点,选择一个奇数n并为值s = 0, 1/n, 2/n, ..., (n-1)/n, 1分配他们权重模式1, 4, 2, 4, 2, ..., 2, 4, 1 。 (终点为1,其他所有部分在4和2之间交替)。现在为每个点计算f((1-s)P1 + sP2)(P2 - P1) ,乘以权重,并将它们加在一起。 然后除以魔法值3 * (n-1) 。 结果大约是你的积分。 (随着n增加,这个近似值的误差是O(1/n4) 。在你的情况下,如果你取n = 21那么近似值应该足够好以便将像素映射到正确的像素,除了边界附近的一些像素,让它稍大一点,问题区域会变小,在边缘你需要一边的像素数的倍数,以使错误变小。)

好的,我们可以做路径积分。 那是什么价值? 那么假设我们在我们地区的某个地方有一个随机点z0 = x + iy 。 假设f(z)在路径上定义。 然后Cauchy积分公式说明f(z)/(2 * π * i * (z - z0))区域周围的积分(这是我们知道如何做的4个分段积分的总和f(z)/(2 * π * i * (z - z0))是一个真正的很好的功能,将与我们在边界上的原始功能相匹配。 我不会涉及所有关于它的“非常好”的事情,但我上面关于共形的描述就是其中的一部分。

现在什么功能f我们如何使用? 那么假设我们的地区正在映射到角落Q1, Q2, Q3, Q4 。 我们希望第一个路径片映射到第二个路径片。 所以我们希望f((1-s)P1 + sP2)(1-s)Q1 + sQ2 。 这告诉我们如何计算f在所有我们需要做我们的积分点。

现在,你问,你如何扭转它? 这很简单。 只需扭转两个多边形的角色,并计算逆向变换! 这带来了非常好的单元测试。 你应该定义几个奇怪的区域,在中间选择一个点,并验证如果你从第一个映射到第二个,并且再次返回,你会接近你开始的位置。 如果你通过了这个测试,那么你可能没有犯错。

最后,我做出的一般多边形声明呢? 那么我们将我们的路径定义为我们线性遍历的四部分。 更高程度的多边形只有更多的路径,否则计算完全以相同的方式完成。


找到了解决方案。 我不得不说,这比我预期的要复杂得多:

假设一个正方形或四边形有四个角落:

AB
CD

你需要一个插值因子:xt表示x轴,yt表示y轴

如果你定义了一个线性插值公式:

lerp(j,k,t)
{
     return (t*(k-j))+j;
}

ABCD quad内的点p被定义为:

p.x=lerp(lerp(a.x,b.x,xt),lerp(c.x,d.x,xt),yt)

p.y=lerp(lerp(a.y,c.y,yt),lerp(b.y,d.y,yt),xt)

那么你需要定义的值是xt和yt

xt =((2 * cx * ay) - (dx * ay) - (2 * ax cy)+(bx cy) - (cx * by)+(ax * dy) - (ay * px)+(cy * px)+(by px) - (dy px)+(ax py) - (bx py) - (cx * py)+(dx * py)-sqrt(-4 *((cx * ay) - (dx * ay) - (ax * cy)+(bx * cy) - (cx * by)+(dx * by)+(ax dy) - (bx dy))*((cx * ay) - (ax * cy) - (ax * px)+(cy * px)+(ax * py) - (cx * py))+((-2 * cx ay)+(dx ay)+(2 * ax cy) - )+(cx * by) - (ax * dy)+(ay * px) - (cy * px) - (by * px)+(dy * px) - (ax * py)+(bx * py)+ (cx * py) - (dx py))^ 2))/(2((cx * ay) - (dx * ay) - (ax * cy)+(bx * cy) - dx * by)+(ax * dy) - (bx * dy)))

一旦你有了

yt=(p.x-lerp(a.x,b.x,('xt')))/(lerp(c.x,d.x,('xt'))-lerp(a.x,b.x,('xt')))
链接地址: http://www.djcxy.com/p/64011.html

上一篇: transforming coordinates from one distorted coordinate system to another

下一篇: order when drawing in a one