【问题标题】:Changing co-ordinate system改变坐标系
【发布时间】:2011-03-10 00:10:16
【问题描述】:


(来源:roughnotebook at sites.google.com

我需要使用 System::Drawing::Drawing2D(即 GDI+)从上面显示的 XY 坐标系切换到 X'Y' 坐标系。这就是我的想法:

float rotation =                    // +90 below is because AB is the new vertical...
    Math::Atan2(pB.Y - pA.Y, pB.X - pA.X) * 180.0 / Math::PI + 90.0f;

Matrix m;
m.Translate(pA.X, pA.Y);
m.Rotate(rotation);
m.Invert();

array<PointF> points = gcnew array<PointF>{ pC };
m.TransformPoints(points);

有没有办法在最小化舍入误差的同时做到这一点?我可以避免在这里调用Atan2(或其他反三角函数)吗?

【问题讨论】:

  • @Rowland,你现在看到图片了吗?
  • 我现在可以 -- 你看到了多大程度的舍入误差?
  • 没什么了不起的。我还没有查看实际值。但是当我放大某些角落时,相邻的矩形显示它们之间的小重叠或间隙。恕我直言,这可以通过更改或避免旋转计算来最小化。
  • 这可能是您渲染方式的人工产物?我在地理信息系统中看到过类似的情况,其中两个多边形共享一条边,但由于在渲染对角线时用于舍入的算法,会出现小间隙。

标签: math geometry c++-cli gdi+ gdi


【解决方案1】:

我不熟悉 gdi+,但原则上你可以在没有逆触发或运算符反转的情况下做到这一点。 (我说“运算符反转”而不是“矩阵反转”,因为这个 Matrix 在我看来不像矩阵。)

首先,您应该能够通过更改定义运算符的方式来避免矩阵求逆。这是一个盲目的尝试:

Matrix m;
m.Rotate(-rotation);
m.Translate(-pA.X, -pA.Y);

现在对于旋转本身,通常的方法是使用如下所示的矩阵:

cos(theta)  -sin(theta)
sin(theta)   cos(theta)

您正在使用 atan(y/x) 计算 theta。但是如果你想要的是 sin 和 cos,你可以将 x 和 y 归一化并直接使用它们:

x  -y
y   x

不需要 atan。 事实上,根本没有触发!

【讨论】:

  • 我假设您的意思是标准化 (pB-pA),而不是标准化 x 和 y。
  • @Beta,但是标准化 x 和 y 是间接触发,不是吗?
  • @Vulcan:不;如果v=(pB-pA),只需将v.xv.y除以v的长度(v.length = sqrt(v.x^2 + v.y^2)
  • @BlueRaja - Danny Pflughoeft:是的,我说话不小心,我应该说“标准化(pB-pA)”或“标准化[x y]”之类的话。
  • 谢谢。回答接受。但是,我用同样昂贵的平方根运算(计算长度)替换三角函数。是否可以避免平方根?
猜你喜欢
  • 1970-01-01
  • 2018-07-06
  • 1970-01-01
  • 2021-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多