一点点绘制曲线

2023-12-09

我需要绘制一条曲线,知道我每 x 毫秒或 x 秒收到点,并且每次收到新点时,曲线都会向左移动一个像素。我正在使用贝塞尔算法从收到的点绘制曲线,因此我至少需要三个点来开始。我想知道如何继续在图像上一点一点地绘制曲线。

这就是我现在正在做的事情:

int xPos = 0;
Point2D.Double[] points = new Point2D.Double[listYpos.size()];

for (int i = 0; i < listYpos.size(); i++) {
    points[i] = new Point2D.Double(i, listYpos.get(i));
}

if (curveImg == null) {
    curveImg = gc.createCompatibleImage(imageWidth, imageHeight, Transparency.BITMASK);
}

if (points.length > 3) {
    Graphics2D gImg = (Graphics2D) curveImg.getGraphics();
    renderCurve(gImg, Arrays.copyOfRange(points, listYpos.size() - 4, listYpos.size() - 1));
    gImg.dispose();
}

AffineTransform at = g.getTransform();
at.scale(-1, 1);
at.translate(-xPos++, listYpos.get(listYpos.size() - 1));

g.drawImage(curveImg, at, null);

每次每 x 毫秒或 x 秒接收到一个新点时都会调用此方法。


我觉得gImg.dispose();

也许这段代码可以帮助你(来自old.forums.sun.com)

enter image description hereenter image description hereenter image description here

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import javax.swing.*;

public class BezierTest {

    private class Animator implements ActionListener {

        private double distance = 0;
        private boolean moveTo = true;
        private ArrayList<Point2D> points = new ArrayList<Point2D>();
        private double step = -1;
        private double steps;
        private Timer timer = new Timer(0, this);

        @Override
        public void actionPerformed(ActionEvent e) {
            step++;
            if (step <= steps) {
                double t = step / steps;
                Point2D newPoint = computeBezierPoint(new Point2D.Double(), t, curvePoints);
                marks[marks.length - 1].setFrame(newPoint.getX() - 5, newPoint.getY() - 5, 10, 10);
                points.add(newPoint);
                if (moveTo) {
                    path.moveTo(newPoint.getX(), newPoint.getY());
                    moveTo = false;
                } else {
                    path.lineTo(newPoint.getX(), newPoint.getY());
                }
                lines[3] = new Line2D.Double(computePointOnLine(lines[0], t), computePointOnLine(lines[1], t));
                lines[4] = new Line2D.Double(computePointOnLine(lines[1], t), computePointOnLine(lines[2], t));
                lines[5] = new Line2D.Double(computePointOnLine(lines[3], t), computePointOnLine(lines[4], t));
                // The maximum distance encountered between the results of two calculation methods.
                // newPoint from computeBezierPoint() the other via the lines method
                distance = Math.max(distance, newPoint.distance(computePointOnLine(lines[5], t)));
                demoComponent.repaint();
            } else {
                timer.stop();
                animationButton.setEnabled(true);
                if (distance > 0d) {
                    System.out.println("Maximum difference " + distance);
                }
            }
        }

        public void init() {
            timer.stop();
            animationButton.setEnabled(false);
            steps = sliderStep.getValue();
            step = -1;
            distance = 0;
            moveTo = true;
            path = new Path2D.Double();
            int sleepTime = (int) Math.round(1000d * sliderDuration.getValue() / steps);
            timer.setDelay(sleepTime);
            timer.setInitialDelay(0);
            timer.start();
        }

        private Point2D computeBezierPoint(Point2D rv, double t,
                Point2D... curve) {
            if (rv == null) {
                rv = new Point2D.Double();
            } else {
                rv.setLocation(0, 0);
            }
            int n = curve.length - 1;
            double oneMinusT = 1.0 - t;
            for (int index = 0; index < curve.length; index++) {
                double multiplier = index == 0 || index == n ? 1 : StrictMath.min(n - index, index) * n;
                multiplier *= StrictMath.pow(t, index) * StrictMath.pow(oneMinusT, n - index);
                rv.setLocation(rv.getX() + multiplier * curve[index].getX(), rv.getY() + multiplier * curve[index].getY());
            }
            return rv;
        }

        private Point2D computePointOnLine(Line2D line, double t) {
            return new Point2D.Double((line.getX2() - line.getX1()) * t + line.getX1(), (line.getY2() - line.getY1()) * t + line.getY1());
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new BezierTest().createGUI();
            }
        });
    }
    private final JButton animationButton = new JButton(new AbstractAction("Start animation") {

        private static final long serialVersionUID = 1L;

        @Override
        public void actionPerformed(ActionEvent e) {
            animator.init();
        }
    });
    private final Animator animator = new Animator();
    private Point2D[] curvePoints = new Point2D[]{new Point(10, 50), new Point(190, 10), new Point(190, 190), new Point(10, 150)};
    private JComponent demoComponent = new JComponent() {

        private static final long serialVersionUID = 1L;

        {
            setPreferredSize(new Dimension(400, 400));
            addComponentListener(new ComponentAdapter() {

                @Override
                public void componentResized(ComponentEvent e) {
                    int w = getWidth();
                    int h = getHeight();
                    recalculateAfterResize(w, h);
                }
            });
        }

        @Override
        protected void paintComponent(Graphics g) {
            if (isVisible()) {
                g.setColor(Color.WHITE);
                g.fillRect(0, 0, getWidth(), getHeight());
                super.paintComponent(g);
                paintBezier(g);
            }
        }
    };
    private Line2D[] lines = new Line2D[6];
    private final Ellipse2D[] marks;
    private Path2D path;
    private final JSlider sliderDuration = createSlider(1, 20, 2, "Duration in seconds", 9, 1);
    private final JSlider sliderStep = createSlider(8, 128, 64, "Animation steps", 16, 1);
    private Path2D totalCurve;

    {
        marks = new Ellipse2D[curvePoints.length + 1];
        for (int index = 0; index < marks.length; index++) {
            marks[index] = new Ellipse2D.Double();
        }
    }

    private void createGUI() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(demoComponent, BorderLayout.CENTER);
        JToolBar toolBar = new JToolBar();
        toolBar.add(animationButton);
        toolBar.add(sliderStep);
        toolBar.add(sliderDuration);
        frame.add(toolBar, BorderLayout.PAGE_START);
        frame.pack();
        frame.setLocation(150, 150);
        frame.setVisible(true);
    }

    private JSlider createSlider(int min, int max, int value, String title, int major, int minor) {
        JSlider slider = new JSlider(min, max, value);
        slider.setBorder(BorderFactory.createTitledBorder(title));
        slider.setMajorTickSpacing(major);
        // slider.setMinorTickSpacing(minor);
        slider.setPaintLabels(true);
        slider.setPaintTicks(true);
        return slider;
    }

    private void paintBezier(Graphics g) {
        Path2D path1 = this.path;
        if (path1 != null) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setColor(Color.GREEN);
            for (Shape mark : marks) {
                g2.fill(mark);
            }
            g2.setStroke(new BasicStroke(2f));
            g2.setColor(Color.BLACK);
            for (Shape mark : marks) {
                g2.draw(mark);
            }
            g2.setStroke(new BasicStroke(0f));
            g2.draw(totalCurve);
            g2.setStroke(new BasicStroke(1f));
            g2.setColor(Color.RED);
            g2.draw(path1);
            g2.setStroke(new BasicStroke(.5f));
            g2.setColor(Color.BLACK);
            for (Line2D line : lines) {
                if (line != null) {
                    g2.draw(line);
                }
            }
        }
    }

    private void recalculateAfterResize(int w, int h) {
        curvePoints = new Point2D[]{new Point2D.Double(10, h / 4.0), new Point2D.Double(w - 10, 10), new Point2D.Double(w - 10, h - 10), new Point2D.Double(10, h - h / 4.0)};
        totalCurve = new Path2D.Double();
        totalCurve.moveTo(curvePoints[0].getX(), curvePoints[0].getY());
        totalCurve.curveTo(curvePoints[1].getX(), curvePoints[1].getY(), curvePoints[2].getX(), curvePoints[2].getY(), curvePoints[3].getX(), curvePoints[3].getY());
        for (int index = 0; index < curvePoints.length; index++) {
            marks[index].setFrame(curvePoints[index].getX() - 5, curvePoints[index].getY() - 5, 10, 10);
        }
        marks[marks.length - 1].setFrame(marks[0].getFrame());
        for (int index = 0; index < curvePoints.length - 1; index++) {
            lines[index] = new Line2D.Double(curvePoints[index], curvePoints[index + 1]);
        }
        lines[3] = null;
        lines[4] = null;
        lines[5] = null;
        animator.init();
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一点点绘制曲线 的相关文章

随机推荐

  • 如何解决 rstudio 中的“plot.new() 错误:图形边距太大”?

    我已阅读与此问题相关的所有帖子 但事实是 如果您有很多变量要绘制 则此问题仍然会发生 我的笔记本电脑分辨率是 1080p 我打开 rstudio 并运行以下脚本 a lt iris 1 4 gt a lt t a gt a lt as da
  • 正则表达式忽略重复匹配

    我有这样的字符串 var str When Home is on fire go and dance in fire 我想检查我的字符串是否有单词home and fire 为此 我使用了这个正则表达式 var words str matc
  • 托管到 iis 时无法访问打印机

    我在 MVC 中使用 rdlc 报告 在 Visual Studio 中运行时打印操作工作正常 但是当发布到同一台机器中设置的 iis 时 打印操作没有发生 但是当我将报告作为 pdf 返回时 报告会显示在那里 我可以使用 javascri
  • EaselJS onclick 接管整个画布

    我正在使用 canvas 和 EaselJS 构建游戏 但是在 onclick 内执行任何删除窗口焦点的操作时会出现问题 即 提示 警报 窗口打开 据我所知 它发生在 FireFox 和一些移动 Android 设备上 我想我明白为什么会这
  • Git rebase:没有跟踪信息

    我在用git version 2 9 0 windows 1我想重新设置本地存储库 非远程 但我总是得到 当前分支没有跟踪信息 请指定您要针对哪个分支进行变基 有关详细信息 请参阅 git rebase 1 git 变基 如果您想为此分支设
  • 无法使用图像和名称正确填充 ListPicker 控件

    我已经为用户创建了一个 ListPicker 控件来更改他或她的背景 但并非所有信息都正确填充在 ListPicker 控件中 当用户导航到我的 SettingsPage 时 会出现问题 所有 ListPicker 项目的文本都正确显示 但
  • Android - 使用 LocationManager 不会提供地理修复

    我正在尝试使用以下代码获取 G1 的 GPS 位置 活动中 MyLocationListener myListener new MyLocationListener LocationManager myManager LocationMan
  • 更改 app.config 后强制重新生成 Settings.settings 文件

    我有一个自动构建过程 可以将应用程序设置为指定模式 例如 Dev uat live 根据这种模式 我想将连接字符串更新为相关的连接字符串 但是 在我的数据访问层中有一个 app config 文件 它存储连接字符串 用于提供 Setting
  • 使用 JSOUP 将文档加载到 WebView

    我正在尝试将网页的一部分解析为 WebView 我正在使用 jsoup 库获取我需要的部分页面 然后加载到 webview 这是代码 public void loadArticleWithHTML Thread downloadThread
  • 随机创建两个列表

    我使用 pandas 从 CSV 文件导入大量数据 读取后我将其格式化为仅包含数字数据 然后返回列表中的列表 每个列表包含大约 140k 位数据 numericalData 从这个列表中 我希望创建Testing and Training
  • iPhone - 可以覆盖 UITableViewCell setSelected:animated

    我正在绘制自定义 UITableViewCells 我的单元格是不透明的 并且完全绘制在单元格的 drawRect 中 以帮助提高性能 我想自己处理选定单元格的外观 如果不这样做 那么我的单元格的内容将被添加的 selectedBackgr
  • 找不到 javax.servlet.jsp.jstl.core.Config 类

    我正在尝试将 Spring 与 Hibernate 一起使用 视图使用 JSTL 当我在浏览器中打开页面时 我看到错误 java lang ClassNotFoundException javax servlet jsp jstl core
  • 为什么我应该将 XPathContext 与 Perl 的 XML::LibXML 一起使用?

    该脚本可以在有或没有的情况下使用XPathContext 我为什么要使用它XPathContext usr bin env perl use warnings use strict use XML LibXML use 5 012 my p
  • 在登录屏幕中禁用stormpath的创建帐户选项

    我想在stormpath登录屏幕中禁用创建帐户 对 api 的调用应该已经由经过应用程序身份验证的用户进行 我尝试将stormpathEnableRegistration 设置为 false 但注册功能仍然启用 app use stormp
  • 如何调用一个哈希值的方法?

    之前 我询问过一种在给定条件下执行方法的巧妙方法 Ruby 是一种根据条件执行函数的巧妙方法 解决方案和响应时间都很棒 但在实施后 拥有 lambda 哈希值很快就会变得丑陋 所以我开始尝试 以下代码有效 def a puts hello
  • java - 谷歌番石榴缓存 invalidateAll() 和 cleanUp() 之间的区别

    说我有一个Cache定义如下 private static Cache
  • 如何计算 Java 中事件的经过时间? [复制]

    这个问题在这里已经有答案了 使用 Java 访问系统时钟的简单 容易的方法是什么 以便我可以计算事件的经过时间 我会避免使用System currentTimeMillis 用于测量经过的时间 currentTimeMillis 返回 挂钟
  • Grails Gorm:对象引用未保存的瞬态实例

    在 Grails 中保存 Trip 实例时出现以下异常 2011 01 26 22 37 42 801 http 8090 5 ERROR 错误 GrailsExceptionResolver 对象引用未保存的瞬态实例 保存 刷新前的瞬态实
  • 如果已连接,如何使用 javascript 刷新页面?

    我有一个网页 我希望它每 2 分钟刷新一次 使用以下代码 location reload 问题是我假设用户已连接 但如果他 她没有在线连接 页面将失败并给出默认浏览器 无连接错误页面 并且页面永远不会刷新 除非用户手动刷新 我可以包含一个
  • 一点点绘制曲线

    我需要绘制一条曲线 知道我每 x 毫秒或 x 秒收到点 并且每次收到新点时 曲线都会向左移动一个像素 我正在使用贝塞尔算法从收到的点绘制曲线 因此我至少需要三个点来开始 我想知道如何继续在图像上一点一点地绘制曲线 这就是我现在正在做的事情