如何在Java2D中实现圆形绕自身轴线稳定旋转?
Java 2D 圆形自旋转偏移问题修复
核心错误点
- 角度计算逻辑错误:代码中
Math.PI/180+i的计算结果是「1度对应的弧度值加上i弧度」,单次旋转增量接近57度,完全不符合每次旋转1度的预期,正确的1度增量弧度计算应为i * Math.PI / 180 - 旋转锚点定位错误:
Ellipse2D.Double(160,160,40,40)的参数为左上角坐标+宽高,圆形自身的中心点坐标为(160 + 40/2, 160 + 40/2) = (180,180),你之前用(160,160)作为旋转锚点,必然会出现偏移 - 循环内无帧延迟,无法观察到逐帧旋转的过程,只会看到最终渲染结果
修复代码(简化版)
直接使用AffineTransform自带的锚点旋转API,不需要手动拼接三次变换,降低出错概率:
public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; // 抗锯齿配置 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); BasicStroke bs = new BasicStroke(3.0f); g2d.setStroke(bs); g2d.setPaint(new Color(110, 100, 0)); Shape s = new Ellipse2D.Double(160,160,40,40); sustain(1000); for(int i=0;i<360;i++) { AffineTransform transform = new AffineTransform(); // 直接指定绕圆形中心点(180,180)旋转,角度转换为弧度 transform.setToRotation(i * Math.PI / 180, 180, 180); clearWindow(g2d); g2d.fill(transform.createTransformedShape(s)); // 每帧加10ms延迟,可自行调整速度 sustain(10); } }
手动拼接变换的正确写法(对应你原逻辑)
如果你要保留「平移到原点→旋转→平移回原位置」的手动拼接逻辑,注意锚点和变换拼接顺序即可:
AffineTransform的concatenate为后乘逻辑,先拼接的变换后执行,所以需要按照「平移回原位置→旋转→平移到原点」的顺序拼接
for(int i=0;i<360;i++) { AffineTransform toOrigin = new AffineTransform(); toOrigin.setToTranslation(-180, -180); AffineTransform rotation = new AffineTransform(); rotation.setToRotation(i * Math.PI / 180); AffineTransform toOriginalPos = new AffineTransform(); toOriginalPos.setToTranslation(180, 180); AffineTransform finalTransform = new AffineTransform(); finalTransform.concatenate(toOriginalPos); finalTransform.concatenate(rotation); finalTransform.concatenate(toOrigin); clearWindow(g2d); g2d.setPaint(new Color(110, 100, 0)); g2d.fill(finalTransform.createTransformedShape(s)); sustain(10); }
内容的提问来源于stack exchange,提问作者user16668673
相关产品推荐
相关产品推荐

