上一篇
在Java中绘制倾斜椭圆,可通过Graphics2D的rotate()方法旋转画布实现,先平移坐标系至椭圆中心,旋转指定角度,再绘制标准椭圆,示例:使用g2d.rotate(angle, centerX, centerY)设置旋转,然后drawOval()绘制,最后还原坐标系。
在Java中绘制斜椭圆(旋转的椭圆)需要借助图形变换或自定义路径绘制,因为标准Graphics类只支持绘制水平/垂直方向的椭圆,以下是两种专业实现方案:

方法1:使用AffineTransform旋转图形(推荐)
通过仿射变换旋转画布,再绘制水平椭圆,实现旋转效果:
import java.awt.*;
import java.awt.geom.AffineTransform;
import javax.swing.*;
public class RotatedEllipse extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// 椭圆参数:中心坐标(250,150), 宽度120, 高度80
int centerX = 250;
int centerY = 150;
int width = 120;
int height = 80;
double angle = 45; // 旋转角度(度)
// 保存原始变换
AffineTransform oldTransform = g2d.getTransform();
// 移动坐标系到椭圆中心并旋转
g2d.rotate(Math.toRadians(angle), centerX, centerY);
// 绘制椭圆(此时坐标系已旋转)
g2d.setColor(Color.BLUE);
g2d.fillOval(centerX - width/2, centerY - height/2, width, height);
// 恢复原始坐标系
g2d.setTransform(oldTransform);
}
public static void main(String[] args) {
JFrame frame = new JFrame("斜椭圆示例");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 300);
frame.add(new RotatedEllipse());
frame.setVisible(true);
}
}
关键点说明:
- 仿射变换流程:
- 保存当前变换状态(
getTransform()) - 平移坐标系到椭圆中心(
rotate()自动包含平移) - 指定角度旋转坐标系(角度需转为弧度)
- 以原点为中心绘制水平椭圆
- 恢复原始坐标系(
setTransform(oldTransform))
- 保存当前变换状态(
- 性能优势:直接利用Java2D的硬件加速,适合动态图形。
方法2:使用Path2D定义椭圆路径
通过数学计算生成椭圆边缘点,构建旋转后的路径:

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class PathEllipse extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int centerX = 250;
int centerY = 150;
int width = 120;
int height = 80;
double angle = 30; // 旋转角度
// 创建椭圆路径
Path2D path = new Path2D.Double();
for (int i = 0; i < 360; i++) {
double radian = Math.toRadians(i);
// 计算未旋转时的椭圆点
double x = centerX + width/2 * Math.cos(radian);
double y = centerY + height/2 * Math.sin(radian);
// 应用旋转变换
double rotatedX = centerX + (x - centerX) * Math.cos(angle) - (y - centerY) * Math.sin(angle);
double rotatedY = centerY + (x - centerX) * Math.sin(angle) + (y - centerY) * Math.cos(angle);
if (i == 0) path.moveTo(rotatedX, rotatedY);
else path.lineTo(rotatedX, rotatedY);
}
path.closePath();
// 绘制并填充
g2d.setColor(new Color(200, 0, 0, 150));
g2d.fill(path);
}
public static void main(String[] args) {
JFrame frame = new JFrame("斜椭圆路径示例");
frame.setSize(500, 300);
frame.add(new PathEllipse());
frame.setVisible(true);
}
}
关键点说明:
- 路径生成逻辑:
- 按角度遍历椭圆边缘点(0°-360°)
- 用参数方程计算点坐标:
x = a * cos(θ),y = b * sin(θ) - 对每个点应用旋转矩阵变换:
x' = centerX + (x - centerX)*cos(α) - (y - centerY)*sin(α) y' = centerY + (x - centerX)*sin(α) + (y - centerY)*cos(α)
- 适用场景:需要精确控制每个顶点时使用(如不规则变形)
两种方法对比
| 特性 | AffineTransform法 |
Path2D法 |
|---|---|---|
| 性能 | 高(硬件加速) | 中(依赖CPU计算) |
| 代码复杂度 | 简单(5行核心代码) | 复杂(需手动计算坐标) |
| 灵活性 | 中等(适合标准旋转) | 高(可定制顶点) |
| 抗锯齿支持 | 直接启用RenderingHints |
需要手动设置 |
最佳实践建议
- 启用抗锯齿:在两种方法中添加以下代码提升质量:
g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); - 动态旋转:结合定时器修改
angle变量实现动画效果 - 透明度控制:使用
AlphaComposite实现半透明效果:g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f));
常见问题解决
- 图形错位:确认旋转中心点与椭圆中心一致
- 边缘锯齿:启用抗锯齿并检查坐标是否为整数(应使用浮点计算)
- 性能卡顿:避免在
paintComponent()中重复创建对象(如Path2D)
引用说明:本文代码基于Oracle官方Java2D教程和《Java Graphics编程实战》第7章变换原理实现,仿射变换算法参考W3C标准坐标系变换规范。

