我一直在使用Affine Transform在我的java项目中旋转一个String,而我还不是一个经验丰富的程序员,所以我花了很长时间做一个看似很小的任务。旋转字符串。
现在我终于按照我的希望或多或少地开始工作,除非它没有像我想要的那样精确地完成......但是。
由于经过了大量的反复试验并阅读了仿射变换的描述,我仍然不太清楚它到底是做什么的。我想我现在所知道的是,我取一个字符串,并定义字符串的中心(或我想要旋转的点),但是矩阵在哪里? (显然我不知道嘿嘿)
有没有人可以尝试向我解释仿射变换是如何工作的,换句话说就是java doc?也许它可以帮助我调整我的实现,而且,我真的很想知道:)
提前致谢。
答案 0 :(得分:5)
要了解什么是仿射变换及其工作原理,请参阅维基百科article。
通常,它是线性变换(如缩放或反射),可以实现为特定矩阵的乘法,然后是通过添加矢量完成的平移(移动)。因此,要计算每个像素[x,y]的新位置,您需要将其乘以特定矩阵(进行线性变换),然后添加然后添加特定向量(进行平移)。
答案 1 :(得分:4)
除了其他答案,还有更高级别的观点:
屏幕上的点具有x和y坐标,即可以写为矢量(x,y)。更复杂的几何对象可以被认为是由一组点描述的。
向量(点)可以乘以矩阵,结果是另一个向量(点)。
有一些特殊的(即巧妙构造的)矩阵,当与向量相乘时,结果向量等效于旋转,缩放,倾斜或输入点的一些欺骗性转换。< / p>
基本上就是这就是它的全部。这种方法有一些更奇特的功能:
有关详细信息,请参阅其他答案。
答案 2 :(得分:2)
实际上,我发现有两件事有助于理解AffineTransform
:
您可以转换图形上下文,Graphics2D
或任何实现Shape
界面的类,如上所述here。
连续转换有一个明显的最后指定的首次应用顺序,也提到here。
答案 3 :(得分:2)
除了其他人已经给出的答案之外,我想展示一个实用的技巧,即我在旋转琴弦或其他物体时通常应用的模式:
translate(-x,-y)
将旋转点(x,y)移动到空间原点。rotate(angle)
(也可以在此处进行缩放)translate(x,y)
将所有内容移回原点。请记住,您必须以相反的顺序应用这些步骤(请参阅trashgod的答案)。
对于具有第一次平移的字符串,我通常将边界框的中心移动到原点,并且使用最后一次平移将字符串移动到屏幕上应显示中心的实际点。然后我可以简单地在我喜欢的任何位置绘制字符串。
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);
答案 4 :(得分:2)
以下是纯粹的数学视频指南,指导如何根据需要设计转换矩阵http://www.khanacademy.org/video/linear-transformation-examples--scaling-and-reflections?topic=linear-algebra
您可能需要观看之前的视频才能了解此矩阵的工作原理和原因。无论如何,如果你有足够的耐心,这是学习线性代数的好资源。