use*_*460 2 java geometry transform graphics2d
在Java的Graphics2D类中,它有一个transform方法。
public abstract void transform(AffineTransform Tx)
Run Code Online (Sandbox Code Playgroud)
这是根据文档的描述:
根据后指定先应用的规则与此 Graphics2D 中的 Transform 组合一个 AffineTransform 对象。如果当前Transform是Cx,则与Tx合成的结果是新的Transform Cx'。Cx' 成为该 Graphics2D 的当前变换。通过更新的变换 Cx' 变换点 p 相当于先通过 Tx 变换 p,然后通过原始变换 Cx 变换结果。换句话说,Cx'(p) = Cx(Tx(p))。如有必要,会制作 Tx 的副本,因此对 Tx 的进一步修改不会影响渲染。
我读了好几遍了,但还是不明白它的作用。我也尝试过寻找其他来源,但关于 g2d 的转换方法的内容并不多。
所以我的问题是:转换到底做什么?我们什么时候使用它?
如果有人能以简化的方式解释它,那就太好了。
可能的答案范围非常广泛,从“它按照 JavaDoc 的说法执行”到完全引用图形编程圣经的几个章节。我会尝试给出一个介于两者之间的答案。它更接近第一个选项,但某些链接指向的信息可能比掌握基本概念所需的信息更详细。
a 的变换Graphics2D描述AffineTransform了对象在绘制之前应如何变换。这样的AffineTransform矩阵可以被想象为修改绘制对象的所有点的位置的东西。例如,它可以是旋转矩阵,以便在绘制对象之前旋转对象。
举个例子:当你在paintComponentsome 的方法中JPanel,并且获得了Graphics2D,那么你就可以进行绘图操作:
protected void paintComponent(Graphics gr) {
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
...
// Draw a rectangle
g.drawRect(0,0,50,100);
}
Run Code Online (Sandbox Code Playgroud)
绘制的矩形宽度为 50 像素,高度为 100 像素。
现在,您可以在绘制之前对对象应用新的变换Graphics2D:
protected void paintComponent(Graphics gr) {
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
...
// Obtain an AffineTransform that describes a scaling
AffineTransform scalingTransform =
AffineTransform.getScaleInstance(2,2);
// Apply the transform to the graphics
g.transform(scalingTransform );
// Draw a rectangle.
g.drawRect(0,0,50,100);
}
Run Code Online (Sandbox Code Playgroud)
现在绘制的矩形将是 100 像素宽、200 像素高,因为变换将所有内容缩放为 2 倍。您还可以使用执行旋转的变换,例如
g.transform(AffineTransform.getRotateInstance(Math.toDegrees(45)));
Run Code Online (Sandbox Code Playgroud)
这样矩形就会旋转 45 度。
transform关于 API 及其效果,这基本上就是该方法的作用。
旁注:确实rotate(...),translate(...)、shear(...)和scale(...)方法Graphics2D只是便捷方法。代替
g.transform(AffineTransform.getRotateInstance(Math.toDegrees(45)));
Run Code Online (Sandbox Code Playgroud)
你可以简单地打电话
g.rotate(Math.toDegrees(45));
Run Code Online (Sandbox Code Playgroud)
以达到同样的效果。该transform方法非常通用,因为它可以接收可能在其他地方组成的任意变换矩阵 - 例如在某些其他方法中,其中对象Graphics2D根本不可用。
如果您想知道该方法内部做了什么:这实际上非常简单。它只是执行矩阵乘法。它将AffineTransform中包含的Graphics2D与AffineTransform传递给该transform方法的 相乘。
这种变换矩阵的乘法可以想象为以相反的顺序应用相应的变换:
AffineTransform scalingByFactor2 =
AffineTransform.getScaleInstance(2,2);
AffineTransform rotationBy45degrees =
AffineTransform.getRotateInstance(Math.toDegrees(45));
g.transform(rotationBy45degrees);
g.transform(scalingByFactor2);
g.drawRect(0,0,50,100);
Run Code Online (Sandbox Code Playgroud)
结果会画出一个矩形,即
所以结果将是一个更大的旋转矩形。
如果您应用了这样的操作
g.transform(scalingByFactor2);
g.transform(rotationBy45degrees);
Run Code Online (Sandbox Code Playgroud)
那么这个矩形就会看起来像一个大的菱形物体。
编辑回应评论:
对象看起来不同的原因是变换是独立应用的。也就是说,它们应用于可能已经被其他变换变换过的对象。我认为矩形(或正方形)的例子在这里可能相当直观:

这与通常的绘画或绘图程序基本相同,您对对象应用一种变换,然后再应用另一种变换,变换的顺序会影响结果。
transform关于和方法之间的差异有一些猜测setTransform。正如 MadProgrammer 最后指出的那样:
该transform方法将图形对象的当前变换与新变换连接起来(即:将矩阵相乘)。您可以使用它来“组合”多个变换,如上面的旋转和缩放示例所示。
与此相反,该Graphics2D#setTransform方法具有完全不同的目的,并且文档包含相应的警告:
警告:切勿使用此方法在现有变换之上应用新的坐标变换
它只能用于在调用序列之后恢复图形的原始转换,transform如 JavaDoc 示例中所示。