绘制曲线一点一点

我需要绘制一条曲线,知道我每隔x毫秒或x秒接收一次点数,并且每次收到一个新点时曲线向左移动一个像素。 我正在使用Bezier算法从我收到的点绘制曲线,所以我需要至少三个点才能开始。 我想知道如何在图像上逐位绘制曲线。

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

int xPos = 0; Point2D.Double[] points = new Point2D.Double[listYpos.size()]; for (int i = 0; i  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)

在此处输入图像描述在此处输入图像描述在此处输入图像描述

 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 points = new ArrayList(); 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(); } }