正文
什么是仿射变换
一组设备无关的坐标被用来将所有的坐标信息传递给Graphics2D对象。
AffineTransform
对象作为
Graphics2D
对象状态的一部分。该对象定义了如何将用户空间的坐标转化为设备空间的设备相关的坐标点。
AffineTransform
类代表一个2D的仿射变化,将一组2D的坐标进行线性映射到另一组保留了平行关系和竖直关系的2D坐标中。该转化包括平移,缩放,翻转,旋转和扭曲。
根据AffineTransform定义的变化有两个非常重要的属性:
直线依然是直线
平行的线依然保持平行
AffineTransform
是限次那个转化,所以可以通过矩阵的形式表示转化,然以一个AffineTransform可以通过数学的形式转化为一个包含六个数字的矩阵。
sx shx tx
shy sy ty
这里省略了矩阵的大括号。
不要方!
不要担心看不懂矩阵。你不需要了解矩阵运算的一切。你只需要有些许的基础知识即可。
事实上,你甚至不用担心需要理解一般的矩阵运算来完成接下来我将说明的简单转换,但是这些可以帮助你更好的理解它是如何运作的。
矩阵里的符号都代表啥?
我将说明如何使用
AffineTransform
使图片在展示于外设之前进行下列转换:
在上面的矩阵中,
sx
和
sy
代表缩放的比例,
tx
和
ty
是实现平移的参数。
shx
和
shy
是实现扭曲的参数。
旋转实际上是缩放和扭曲的组合,所以它可以由上面的参数组合完成操作。
如何使用这些参数?
// ‘*’ 代表乘号
newX = sx*x + shx*y + tx
newY = shy*x + sy*y + ty
假设在用户空间中存在坐标(x, y),这些参数将通过上面的公式计算出新的坐标,从而实现缩放,扭曲和平移。
我们后面会看到,如果表示剪切和平移的因子的值为零,那么将不执行该类型的变换。如果缩放的值为1(默认值),那么图片不会进行缩放。其它的任何值都会导致缩放,平移或扭曲的发生。
对于所有三种类型的变换,用于变换x坐标的值与用于变换y坐标的值无关。因此,例如,可以对x进行大树枝的平移,并在y中用进行小数值平移。
在详细描述执行这些转换之前,对每个转换提供些许解释可能会很有用。
缩放
缩放可能是四种转化中最好理解的一种。它是指如果一个点在用户空间中的坐标为
(x,y)
,那么它在设备空间中的坐标为
(sx * x, sy * y )
。乘数
sx
与
sy
可以为正数或是负数。
平移
平移的目的是在设备空间中移动坐标系的原点。
比如,默认的原点是组件左上角的点。假设组件是一个边长四英寸的Frame,你可能希望原点位于框架的中心,而不是左上角。你可以通过将原点坐标分别从水平和垂直方向平移两英寸实现。
另一个使用平移的场景(与缩放同时使用)是翻转垂直轴的默认正方向,从而使y轴值的增加使得点向上移动而不是默认的向下移动。
扭曲
这是网上给的一个shearing的图例,即将原图以平行四边形拉伸。
旋转
旋转从视觉上很好理解。为了可视化旋转,在一张纸上画一张照片。 使用一个钉子将其粘到公告板上。 然后围绕大头钉旋转纸张。
在Java 2D中,旋转是使用radians而不是degree的形式传入参数。如果您不熟悉使用弧度度量来指定角度,请记住以下标识:
PI radians = 180 degrees
PI是在几何类中学到的数值。它的值为3.14159...........。但是,你无须记住PI的数值,因为MATH类中包含了它的静态值。你可以通过
Math.PI
获得该值。