8

我一直在我的java项目中使用仿射变换来旋转一个字符串,我还不是一个有经验的程序员,所以我花了很长时间来完成一个看似很小的任务..旋转一个字符串。

现在我终于让它或多或少地像我希望的那样工作,除了它没有像我想要的那样精确......但是。

由于需要大量的试验和错误并阅读仿射变换的描述,我仍然不太确定它的真正作用。我想我现在知道的是,我拿了一个字符串,并定义了字符串的中心(或我想要旋转的点),但是矩阵在哪里出现呢?(貌似我不知道呵呵)

任何人都可以尝试向我解释仿射变换是如何工作的,换句话说,不是java doc吗?也许它可以帮助我调整我的实现,而且,我真的很想知道:)

提前致谢。

4

5 回答 5

6

要了解什么是仿射变换及其工作原理,请参阅维基百科文章

一般来说,它是一种线性变换(如缩放或反射),可以通过与特定矩阵相乘来实现,然后通过添加一个向量来完成平移(移动)。因此,要为每个像素 [x,y] 计算其新位置,您需要将其乘以特定矩阵(进行线性变换),然后添加然后添加特定向量(进行平移)。

于 2011-04-14T22:08:57.980 回答
4

除了其他答案之外,更高级别的视图:

  • 屏幕上的点有 ax 和 ay 坐标,即可以写成向量 (x,y)。更复杂的几何对象可以被认为是由点的集合来描述的。

  • 向量(点)可以乘以一个矩阵,结果是另一个向量(点)。

  • 有一些特殊的(即巧妙构造的)矩阵,当与向量相乘时,产生的向量等效于旋转、缩放、倾斜或输入点的一些技巧平移。

基本上就是这样。这种方法还有一些更奇特的功能:

  • 如果你将 2 个矩阵相乘,你会再次得到一个矩阵(至少在这种情况下;停止挑剔 ;-))。
  • 如果将 2 个矩阵相乘,相当于 2 个几何变换,则生成的矩阵相当于一个接一个地进行 2 个几何变换(顺便说一句,顺序很重要)。
  • 这意味着您可以在单个矩阵中编码这些几何变换的任意链。您可以通过将各个矩阵相乘来创建此矩阵。
  • 顺便说一句,这也适用于 3D。

有关更多详细信息,请参阅其他答案。

于 2011-04-15T05:33:26.857 回答
3

除了其他人已经给出的答案之外,我想展示一个实用的技巧,即我通常在旋转字符串或其他对象时应用的模式:

  1. 通过应用 将旋转点 (x,y) 移动到空间原点translate(-x,-y)
  2. 进行旋转rotate(angle)(也可能在此处进行缩放)
  3. 将所有内容移回原点translate(x,y)

请记住,您必须以相反的顺序应用这些步骤(请参阅垃圾神的答案)。

对于第一次翻译的字符串,我通常将边界框的中心移动到原点,最后一次翻译将字符串移动到屏幕上应该出现中心的实际点。然后我可以简单地在我喜欢的任何位置绘制字符串。

Rectangle2D r = g.getFontMetrics().getStringBounds(text, g);
g.translate(final_x, final_y);
g.rotate(-angle);
g.translate(-r.getCenterX(), -r.getCenterY());
g.drawString(text, 0, 0);

或者

Rectangle2D r = g.getFontMetrics().getStringBounds(text, g);
AffineTransform trans = AffineTransform.getTranslateInstance(final_x, final_y);
trans.concatenate(AffineTransform.getRotateInstance(-angle));
trans.concatenate(AffineTransform.getTranslateInstance(-r.getCenterX(), -r.getCenterY()));
g.setTransform(trans);
g.drawString(text, 0, 0);
于 2011-04-15T05:12:12.510 回答
2

作为一个实际问题,我发现有两件事有助于理解AffineTransform

  1. 您可以转换图形上下文,Graphics2D或任何实现Shape接口的类,如此所述。

  2. 级联转换具有明显的最后指定先应用顺序,这里也提到过。

于 2011-04-14T23:28:33.813 回答
2

这是纯粹的数学视频指南,如何根据您的需要设计变换矩阵http://www.khanacademy.org/video/linear-transformation-examples--scaling-and-reflections?topic=linear-algebra

不过,您可能需要观看以前的视频才能了解此矩阵的工作原理和原因。无论如何,如果你有足够的耐心,它是学习线性代数的好资源。

于 2012-02-12T11:58:46.927 回答