Как плавно заполнять эллипсы при перетаскивании мышью - PullRequest
0 голосов
/ 10 мая 2019

Я использую MouseMotion Listeners для добавления фигур в HashSet, а затем заполняю их с помощью Graphics2D. Однако, когда я слишком быстро двигаю мышь, точки больше не образуют связную линию.

Я пробовал поискать в Google, но не нашел соответствующего ответа.

addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseDragged(MouseEvent e) {
                //points.add(new Point(e.getX(), e.getY()));
                shapes.add(new ShapeInfo(circle, new Point(e.getX(), e.getY()), color));
                repaint();
            }
        });
for(ShapeInfo info : shapes) {
            Point location = info.point.getLocation();
            g2d.translate(location.x, location.y);
            g2d.setColor(info.color);
            g2d.fill(info.shape);
            g2d.translate(-location.x, -location.y);
        }

Я надеюсь получить красивую, плавную линию, сделанную из кругов, но в конечном итоге получу более замкнутые круги. https://imgur.com/a/KLOyPcn <- Вот что происходит, когда я слишком быстро перетаскиваю мышь во время рисования. </p>

Ответы [ 2 ]

1 голос
/ 10 мая 2019

Вот попробуй это.

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
import javax.swing.*;

public class FillOvals extends JPanel {
   private JFrame      frame  = new JFrame();
   private List<Point> points = new ArrayList<>();

   public static void main(String[] args) {
      SwingUtilities.invokeLater(() -> new FillOvals().start());
   }

   public FillOvals() {
      setPreferredSize(new Dimension(500, 500));
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.add(this);
      frame.pack();
      frame.setLocationRelativeTo(null); // center on screen
      frame.setVisible(true);
   }

   public void start() {
      MyMouseListener ml = new MyMouseListener();
      addMouseMotionListener(ml);
      addMouseListener(ml);
   }

   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (points.size() < 1) {
         return;
      }
      Graphics2D g2d = (Graphics2D) g.create();

      // keep the line smooth on the edges
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

      g2d.setColor(Color.BLUE);
      Point p = points.get(0);
      int lastx = p.x;
      int lasty = p.y;
      g2d.setStroke(new BasicStroke(10.f));
      for (int i = 1; i < points.size(); i++) {

         p = points.get(i);
         g2d.drawLine(lastx, lasty, p.x, p.y);
         lastx = p.x;
         lasty = p.y;
      }
      g2d.dispose();
   }

   private class MyMouseListener extends MouseAdapter {

      public void mouseDragged(MouseEvent e) {
         points.add(e.getPoint());
         repaint();
      }

      public void mousePressed(MouseEvent e) {
         points.add(e.getPoint());
         repaint();
      }

   }
}

JVM / мышь не могут так быстро справляться с рисованием кругов. Приведенный мной пример рисует линию между двумя точками непрерывно.

1 голос
/ 10 мая 2019

Ваша мышь работает на определенной частоте (обычная мышь работает на частоте около 100 Гц), поэтому она будет выбирать определенное количество точек при ее перемещении.

Если вы покроете 1000 пикселей за полсекунды (что не очень быстро), он выберет 50 точек, они будут разнесены на каждые 20 пикселей.

Если радиус вашего круга меньше этого, вы увидите пунктирную линию.

Даже если использовать очень быструю мышь, вы не сможете получить непрерывную линию.

Вы можете нарисовать линию между точками вместо рисования окружности, если хотите, или интерполировать координаты между последней и текущей окружностью и создать другие окружности между 2.

...