You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中使用AWT绘制外摆线epicycloid?

AWT实现外摆线绘制方案

外摆线的通用参数方程为:定圆半径R,动圆半径r,参数θ时,坐标点为

x = (R + r)cosθ - rcos( (R+r)θ / r )
y = (R + r)sinθ - rsin( (R+r)θ / r )

实现步骤如下:

  • 自定义类继承Canvas,重写paint(Graphics g)方法,所有绘制逻辑放在该方法内
  • 转换坐标系:AWT默认原点在左上角、y轴向下,需要平移原点到画布中心,翻转y轴匹配数学坐标系习惯
  • 配置参数:可自定义定圆半径R、动圆半径r、参数步长(建议0.01弧度保证曲线平滑),参数θ的遍历范围为0到2π * (r/R和R的最大公约数对应的倍数),保证曲线完全闭合
  • 遍历θ计算每一个点的坐标,用GeneralPath拼接所有点后统一绘制,性能比逐点画直线更优
  • 主逻辑创建Frame窗口,将自定义Canvas加入窗口,配置窗口大小、关闭逻辑即可

可参考的实现代码:

import java.awt.*;
import java.awt.geom.GeneralPath;

public class EpicycloidDrawer extends Frame {
    public EpicycloidDrawer() {
        setTitle("外摆线绘制");
        setSize(600, 600);
        add(new DrawCanvas());
        // 窗口关闭逻辑
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent e) {
                dispose();
                System.exit(0);
            }
        });
    }

    class DrawCanvas extends Canvas {
        @Override
        public void paint(Graphics g) {
            Graphics2D g2d = (Graphics2D) g;
            // 开启抗锯齿优化显示效果
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            // 画布中心坐标
            int centerX = getWidth() / 2;
            int centerY = getHeight() / 2;

            double fixedR = 100; // 定圆半径
            double moveR = 30; // 动圆半径
            double step = 0.01; // 参数步长
            // 计算曲线闭合需要的最大参数值
            double maxTheta = 2 * Math.PI * (moveR / gcd((int)fixedR, (int)moveR));

            GeneralPath path = new GeneralPath();
            boolean isFirst = true;
            for (double theta = 0; theta <= maxTheta; theta += step) {
                double x = (fixedR + moveR) * Math.cos(theta) - moveR * Math.cos((fixedR + moveR) * theta / moveR);
                double y = (fixedR + moveR) * Math.sin(theta) - moveR * Math.sin((fixedR + moveR) * theta / moveR);
                // 转换为AWT坐标系下的坐标
                int drawX = centerX + (int) Math.round(x);
                int drawY = centerY - (int) Math.round(y);
                if (isFirst) {
                    path.moveTo(drawX, drawY);
                    isFirst = false;
                } else {
                    path.lineTo(drawX, drawY);
                }
            }
            g2d.draw(path);
        }

        // 计算最大公约数,用于判断曲线闭合的参数范围
        private int gcd(int a, int b) {
            return b == 0 ? a : gcd(b, a % b);
        }
    }

    public static void main(String[] args) {
        new EpicycloidDrawer().setVisible(true);
    }
}

其他可选绘图方案推荐

  • Swing:AWT的上层封装,组件更丰富,默认开启双缓冲不会出现绘制闪烁问题,是Java桌面端绘图的更常用选择,仅需将上述代码的Canvas替换为JPanel、重写paintComponent方法即可,适配成本极低
  • JavaFX:目前官方主推的Java桌面UI框架,绘图API更现代化,支持动画、交互、CSS样式,如果需要做动态调整参数(比如拖拽修改半径实时查看曲线变化)的需求,实现难度远低于AWT/Swing
  • Processing:面向创意编程、数据可视化的开源框架,语法简洁,不需要处理窗口初始化、坐标系转换等冗余逻辑,适合快速做可视化效果验证

内容的提问来源于stack exchange,提问作者Aska

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 23:39:02