AffineTransform通过实时更新并设置到Graphics2D来实现图形动态变换;需按平移→旋转→缩放顺序组合,绕任意点旋转须手动平移-旋转-平移,交互时用成员变量控制变换参数,并注意坐标系影响与性能优化。

AffineTransform 是 Java 2D 中用于执行二维仿射变换的核心类,能高效实现图形的平移、缩放、旋转、斜切等操作。它不直接绘制图形,而是通过修改坐标系(即变换 Graphics2D 的变换矩阵)来影响后续所有绘图操作。要实现“变量图形”的动态平移、缩放、旋转(比如随鼠标拖动、滚轮缩放、按键旋转),关键在于**实时更新 AffineTransform 并将其设为 Graphics2D 的当前变换**。
一、基础三步:创建、组合、应用变换
每次绘制前需重置并重建变换,避免累积误差:
-
创建新实例:用
AffineTransform.getTranslateInstance(tx, ty)或new AffineTransform()起手,避免复用旧对象导致状态残留 - 按逻辑顺序组合变换:通常顺序是「平移 → 旋转 → 缩放」或「平移 → 缩放 → 旋转」,顺序不同结果差异显著(例如绕中心旋转需先平移到中心,再旋转,再平移回)
-
设置到 Graphics2D:调用
g2d.setTransform(at)(完全替换)或g2d.transform(at)(叠加到当前变换)
二、绕任意点旋转的关键写法
直接 at.rotate(angle) 是绕原点 (0,0) 旋转。要绕图形中心 (cx, cy) 旋转,必须手动拼接三步:
- 平移 -cx, -cy(把中心移到原点)
- 旋转 angle 弧度
- 平移 cx, cy(移回原位)
代码示例:
double cx = rect.x + rect.width / 2.0;<br>double cy = rect.y + rect.height / 2.0;<br>AffineTransform at = new AffineTransform();<br>at.translate(cx, cy);<br>at.rotate(angle);<br>at.translate(-cx, -cy);
三、支持交互的变量控制结构
将平移量(tx/ty)、缩放因子(scaleX/scaleY)、旋转角(angle)定义为成员变量,响应用户输入实时更新:
- 鼠标拖动 → 更新
tx,ty - 滚轮滚动 → 更新
scaleX,scaleY(建议以当前中心为锚点缩放) - 键盘 R 键 →
angle += Math.PI / 18(每次转10度) - 绘制时统一构建 AffineTransform:
at.translate(tx, ty);
at.scale(scaleX, scaleY);
at.rotate(angle, cx, cy);(rotate 的双参数重载可一步完成绕点旋转)
四、注意坐标系与性能细节
变换作用于整个坐标系,会影响文字、线条宽度、笔触等所有后续绘制内容。若只需变换图形本身,建议:
- 用
g2d.setTransform(originalAT)绘制前保存原始变换,绘制后恢复 - 对复杂图形,优先使用
Shape.createTransformedShape(at)得到新 Shape 再绘制,避免影响其他元素 - 避免在 paintComponent 中频繁 new AffineTransform(可复用对象,但需 clear() 或 reset())










