gpt4 book ai didi

java - Graphics2D的transform方法有什么作用?

转载 作者:行者123 更新时间:2023-11-30 08:10:50 27 4
gpt4 key购买 nike

在Java的Graphics2D类中,它具有转换方法。

public abstract void transform(AffineTransform Tx)


这是根据文档的描述:


  根据后指定先应用的规则,在此Graphics2D中用Transform组成一个AffineTransform对象。如果当前Transform为Cx,则使用Tx合成的结果为新的Transform Cx'。 Cx'成为此Graphics2D的当前Transform。通过更新的Transform Cx'转换点p等效于首先通过Tx转换p,然后通过原始Transform Cx转换结果。换句话说,Cx'(p)= Cx(Tx(p))。如果需要,可以复制Tx,因此对Tx的进一步修改不会影响渲染。


我已经读过好几次了,但我仍然不明白它的作用。我也尝试过寻找其他来源,但是g2d的transform方法没有太多内容。

所以我的问题是:转换到底能做什么?我们什么时候使用它?

如果有人可以简化的方式解释它,那就太好了。

最佳答案

可能的答案范围非常广泛,从“它按照JavaDoc所说的做”到完全引用the graphics programming bible的几章。我将尝试给出一个介于两者之间的答案。它更接近第一个选项,但是某些链接导致的信息可能比掌握基本概念所必需的信息更为详细。

Graphics2D的变换是AffineTransform,它描述对象在绘制之前应如何变换。这样的AffineTransformMatrix,可以想象为修改绘制对象所有点的位置的内容。例如,它可以是rotation matrix,以便在绘制对象之前先旋转它们。

一个示例:当您处于某些paintComponentJPanel方法中并获得了Graphics2D时,则可以执行绘制操作:

protected void paintComponent(Graphics gr) {
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
...

// Draw a rectangle
g.drawRect(0,0,50,100);
}


在此绘制的矩形将宽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);
}


由于将所有内容缩放2倍的变换,现在在此处绘制的矩形将宽100像素,高200像素。您还可以使用执行旋转的变换,例如

g.transform(AffineTransform.getRotateInstance(Math.toDegrees(45)));


以便将矩形旋转45度。

关于API及其作用,基本上是 transform方法所做的。

旁注:的确, rotate(...)translate(...)shear(...)scale(...)Graphics2D方法只是方便的方法。代替

g.transform(AffineTransform.getRotateInstance(Math.toDegrees(45)));


你可以简单地打电话

g.rotate(Math.toDegrees(45));


达到同样的效果。 transform方法非常通用,因为它可以接收可能在其他地方组成的任意转换矩阵-例如在其他方法中, Graphics2D对象根本不可用。



如果您想知道该方法在内部执行的操作:这实际上很简单。它只执行 Matrix Multiplication。它将 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);


结果,将绘制一个矩形,即


首先在x和y方向缩放2倍
然后旋转45度


因此,结果将是一个更大的旋转矩形。

如果您应用了这样的操作

g.transform(scalingByFactor2);
g.transform(rotationBy45degrees);


那么矩形将看起来像一个大的菱形物体。


  根据评论进行编辑:


对象看起来不同的原因是,转换是独立应用的。即,它们被应用于可能已经被其他转换转换的对象。我认为矩形(或正方形)的示例在这里可能很直观:



这与通常的绘画或绘图程序基本相同,在该程序中,您先将一个转换应用于一个对象,然后再将另一个应用于对象,然后转换的顺序会影响结果。



关于 transformsetTransform方法之间的区别,有一些猜测。正如MadProgrammer最终指出的那样:

transform方法将图形对象的当前变换与新变换连接在一起(即:它与矩阵相乘)。您可以使用它来“组成”多个转换,如上面的旋转和缩放示例所示。

与此相反, Graphics2D#setTransform方法的用途完全不同,文档中包含相应的警告:


  警告:永远不要使用此方法在现有转换之上应用新的坐标转换


如JavaDoc示例所示,在调用 transform的序列之后,仅应将其用于恢复图形的原始转换。

关于java - Graphics2D的transform方法有什么作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31483777/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com