Drawing curve bit by bit

后端 未结 1 1896
一整个雨季
一整个雨季 2021-01-03 11:34

I need to draw a curve, knowing that I receive points every x milliseconds or x seconds, and that the curve is moving to the left by one pixel each time I receive a new poin

相关标签:
1条回答
  • 2021-01-03 12:17

    I think that gImg.dispose();

    maybe this code can help you with that (from 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();
        }
    }
    
    0 讨论(0)
提交回复
热议问题