【问题标题】:transforming coordinates from one distorted coordinate system to another将坐标从一个扭曲的坐标系转换到另一个
【发布时间】:2011-03-23 20:55:11
【问题描述】:

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

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

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

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

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

所以给定 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) 在路径上定义。然后 柯西积分公式说 我们地区的积分(即 4个分段积分的总和 我们知道怎么做) f(z)/(2 * π * i * (z - z0)) 是一个非常好的函数,它将与我们的原始函数相匹配 边界上的函数。

这个函数究竟做了什么?

【问题讨论】:

  • 到目前为止,您所写的内容看起来很合理。至于函数的作用,当你完成后,f(z) 将是你的映射。在您的原始区域中取任何一点,您应该在新区域中获得一个点。一开始,您知道如何处理边界,但不知道其他任何地方。该积分在边界内的任何地方找到函数的值。
  • 抱歉,我说错了。我的意思是公式 f(z)/(2 * π * i * (z - z0))。我对我应该在哪里插入什么感到有点困惑。我得到 z0 是我们的任意点,但是对于 f(z) 和 z,我只是选择路径上的任何点吗?这个公式实际上是使用积分来获得新位置吗?和“这是我们知道如何做的 4 个分段积分的总和”,所以我总结了 4 个边的积分,那在哪里插入?并且这个公式中的f(z)还是(1-s)Q1 + sQ2,还是我们现在说的是积分公式?

标签: math geometry coordinate-systems coordinate-transformation


【解决方案1】:

(我的第一遍是对一个看起来很自然的公式的复杂推导。但后来我意识到有一个更好的解决方案。如果我在过去 20 年使用复杂分析,我会更早记得.)

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

足够的炒作。你怎么做呢?我会解释它,假设你对复杂分析一无所知。我将使用一些微积分术语,但即使你根本不知道任何微积分,你也应该能够按照我的指示进行操作。由于我假设很少,因此解释必须有点长。对此我很抱歉。

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

但我们可以做得更好。我们可以做微积分。特别是我们可以在曲线周围做path integrals。函数沿曲线的积分是该函数对该曲线中各点的加权平均值。您可以阅读一般的操作方法。但这里是在这种情况下如何做到这一点。

假设起始区域有角P<sub>1</sub>, P<sub>2</sub>, P<sub>3</sub>, P<sub>4</sub>。该区域周围的路径由四个线段(P<sub>1</sub>, P<sub>2</sub>), (P<sub>2</sub>, P<sub>3</sub>), (P<sub>3</sub>, P<sub>4</sub>), (P<sub>4</sub>, P<sub>1</sub>) 定义。我将讨论如何处理第一条线段。其他类似。

f(z)(P<sub>1</sub>, P<sub>2</sub>) 的路径积分是f((1-s)P<sub>1</sub> + sP<sub>2</sub>)(P<sub>2</sub> - P<sub>1</sub>) 从 0 到 1 的积分。要评估该积分,最简单的方法是使用Simpson's Rule 进行数值积分。为此,请选择一个奇数 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)P<sub>1</sub> + sP<sub>2</sub>)(P<sub>2</sub> - P<sub>1</sub>),乘以权重,然后将它们加在一起。然后除以魔法值3 * (n-1)。结果大约是您的积分。 (随着n 的增长,此近似值的误差为O(1/n<sup>4</sup>)。在您的情况下,如果您采用n = 21,那么近似值应该足以将像素映射到正确的像素,边界附近的一些像素除外。把它弄大一点,问题区域就会变小。在边缘,你会想要一个边上像素数的倍数,以使误差变小。)

好的,所以我们可以进行路径积分。那有什么价值呢?好吧,假设我们在我们区域的某个地方随机取一个点z<sub>0</sub> = x + iy。假设在路径上定义了f(z)。然后Cauchy Integral Formula 表示f(z)/(2 * π * i * (z - z<sub>0</sub>)) 的区域周围的积分(这是我们知道如何做的 4 个分段积分的总和)是一个非常好的函数,它将与边界上的原始函数相匹配。我不会深入讨论它的所有“非常好的”事情,但我上面所说的关于 conformal 的内容就是其中的一部分。

现在我们使用什么函数f?好吧,假设我们的区域被映射到一个有角的区域Q<sub>1</sub>, Q<sub>2</sub>, Q<sub>3</sub>, Q<sub>4</sub>。我们希望第一个路径片段映射到第二个路径片段。所以我们希望f((1-s)P<sub>1</sub> + sP<sub>2</sub>)(1-s)Q<sub>1</sub> + sQ<sub>2</sub>。这告诉我们如何在需要积分的所有点上计算 f

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

最后,我提出的一般多边形声明呢?好吧,我们将路径定义为线性遍历的四个部分。更高阶的多边形只是在其路径中包含更多片段,但除此之外,计算方式完全相同。

【讨论】:

  • 谢谢。我只是一直在寻找一些更简单的答案,因为将一个轴的插值的逆插入到另一个轴似乎比问题应得的要复杂得多,但这似乎是唯一的方法。你可以在我的回答中看到,结果公式并不漂亮
  • @lucid 您可以在编辑历史记录中找到我的原始答案,但我只是重写了它以使用一个非常非常不同的答案,在许多方面要好得多。它并没有变得更简单,但新答案具有更好的属性(例如保持角度相同)。
  • 哇。我不能感谢你。我还没有机会实施它。我即将离开去工作,但你刚刚为我的项目所做的一切,基本上是我想要完成的理想化版本。我打算应用原始问题来近似一个点在弯曲形状上的位置,这当然实际上是一个多面多边形。我想到的解决方案将非常复杂。但是,您的解决方案更有机的性质对项目的其余部分有很多其他更大的影响。
  • 你启发了我学习微积分。再次感谢您。
  • @lucid:不客气。请注意,稍加努力,您应该能够准确地解析积分。这可能比我推荐的数值解计算得更快。
【解决方案2】:

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

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

AB
CD

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

如果定义线性插值公式:

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

ABCD四边形内的点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* c.x* a.y) - (d.x* a.y) - (2 *a.x c.y) + (b.x c.y) - (c.x* b.y) + (a.x* d.y) - (a.y* p.x) + (c.y* p.x )+ (b.y p.x) - (d.y p.x) + (a.x p.y) - (b.x p.y) - (c.x* p.y) + (d.x* p.y) - Sqrt(-4* ((c.x* a.y) - (d.x* a.y) - (a.x* c.y) + (b.x* c.y) - (c.x* b.y) + (d.x* b.y) + (a.x d.y) - (b.x d.y))* ((c.x* a.y) - (a.x* c.y) - (a.y* p.x) + (c.y* p.x) + (a.x* p.y) - (c.x* p.y)) + ((-2 *c.x a.y) + (d.x a.y) + (2 * a.x c.y) - (b.x c.y) + (c.x* b.y) - (a.x* d.y) + (a.y* p.x) - (c.y* p.x) - (b.y* p.x) + (d.y* p.x) - (a.x* p.y) + (b.x* p.y) + (c.x* p.y) - (d.x p.y))^2))/(2 ((c.x* a.y) - (d.x* a.y) - (a.x* c.y) + (b.x* c.y) - (c.x* b.y) + (d.x *b.y) + (a.x *d.y) - (b.x *d.y))))

一旦你有了它

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

【讨论】:

  • 3d 变换矩阵可以做到这一点吗?
  • @hfossli,我希望如此,但可能会复杂得多。如果我现在不那么忙,我自己会努力解决的。为了得到超长方程,我在原始方程组上使用了mathematica。作为旁注,如果它是用于实时目的(就像 2d 版本一样),请事先知道即使 2d 版本也是相当密集的处理器,所以它可能会在 3d 中变得令人望而却步
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-30
  • 1970-01-01
  • 1970-01-01
  • 2013-09-20
  • 2013-03-14
  • 2013-03-25
相关资源
最近更新 更多