2015-02-17 2 views
0

Я хотел бы знать, как я могу заставить java определить, связан ли эллипс с линией или прямоугольником, и программа также должна определить форму, с которой она связана.Как обнаружить пересечение фигур в java?

Эллипс нарисован, линия также нарисована и прямоугольником. Java должна определить, есть ли что-то, связанное с эллипсом, если да, то узнайте через линию, что связано с ней.

enter image description here

Вот мой код, чтобы рисовать фигуры.

import java.awt.AlphaComposite; 
 
import java.awt.BasicStroke; 
 
import java.awt.BorderLayout; 
 
import java.awt.Color; 
 
import java.awt.Dimension; 
 
import java.awt.Graphics; 
 
import java.awt.Graphics2D; 
 
import java.awt.Point; 
 
import java.awt.RenderingHints; 
 
import java.awt.Shape; 
 
import java.awt.event.ActionEvent; 
 
import java.awt.event.ActionListener; 
 
import java.awt.event.MouseAdapter; 
 
import java.awt.event.MouseEvent; 
 
import java.awt.event.MouseMotionAdapter; 
 
import java.awt.geom.Ellipse2D; 
 
import java.awt.geom.Line2D; 
 
import java.awt.geom.Rectangle2D; 
 
import java.awt.image.BufferedImage; 
 
import java.io.File; 
 
import java.io.IOException; 
 
import java.io.OutputStream; 
 
import java.io.OutputStreamWriter; 
 
import java.io.Writer; 
 
import java.text.DecimalFormat; 
 
import java.util.ArrayList; 
 
import java.util.Iterator; 
 
import java.util.Scanner; 
 

 
import javax.imageio.ImageIO; 
 
import javax.swing.Box; 
 
import javax.swing.Icon; 
 
import javax.swing.ImageIcon; 
 
import javax.swing.JButton; 
 
import javax.swing.JColorChooser; 
 
import javax.swing.JComponent; 
 
import javax.swing.JFileChooser; 
 
import javax.swing.JFrame; 
 
import javax.swing.JLabel; 
 
import javax.swing.JMenu; 
 
import javax.swing.JMenuBar; 
 
import javax.swing.JMenuItem; 
 
import javax.swing.JOptionPane; 
 
import javax.swing.JPanel; 
 
import javax.swing.JSeparator; 
 
import javax.swing.JSlider; 
 
import javax.swing.JTextField; 
 
import javax.swing.SwingConstants; 
 
import javax.swing.event.ChangeEvent; 
 
import javax.swing.event.ChangeListener; 
 
import javax.swing.filechooser.FileNameExtensionFilter; 
 

 
public class Lesson49_1 extends JFrame { 
 

 
    private static final long serialVersionUID = -140274271716086522L; 
 

 
    JMenuBar menubar; 
 
    JMenu File, Exit; 
 
    JMenuItem New, Open; 
 
    JComponent DrawingBoard; 
 

 
    JButton lineBut, ellipseBut, rectBut, strokeBut; 
 

 
    DecimalFormat dec = new DecimalFormat("#.##"); 
 

 
    // Contains all of the rules for drawing 
 

 
    Graphics2D graphSettings; 
 

 
    
 
    // Going to be used to monitor what shape to draw next 
 

 
    int currentAction = 1; 
 

 
    // Transparency of the shape 
 

 
    // Default stroke and fill colors 
 

 
    Color strokeColor = Color.BLACK; 
 

 
    public static void main(String[] args) { 
 
     new Lesson49_1(); 
 
    } 
 

 
    public Lesson49_1() { 
 
     // Define the defaults for the JFrame 
 

 
     this.setSize(800, 600); 
 
     this.setTitle("ERD BUILDER"); 
 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
 
     this.setJMenuBar(menubar); 
 

 
     JMenuBar menuBar = new JMenuBar(); 
 

 
     // Add the menubar to the frame 
 
     setJMenuBar(menuBar); 
 

 
     // Define and add two drop down menu to the menubar 
 
     JMenu fileMenu = new JMenu("File"); 
 
     JMenu editMenu = new JMenu("Edit"); 
 
     JMenu dbMenu = new JMenu("Database"); 
 
     JMenu ToolsMenu = new JMenu("Tools"); 
 
     JMenu HelpMenu = new JMenu("Help"); 
 
     menuBar.add(fileMenu); 
 
     menuBar.add(editMenu); 
 
     menuBar.add(dbMenu); 
 
     menuBar.add(ToolsMenu); 
 
     menuBar.add(HelpMenu); 
 
     // Create and add simple menu item to one of the drop down menu 
 
     JMenuItem newAction = new JMenuItem("New Project"); 
 
     JMenuItem openAction = new JMenuItem("Open File"); 
 
     JMenuItem exitAction = new JMenuItem("Quit"); 
 
     JMenuItem cutAction = new JMenuItem("Cut"); 
 
     JMenuItem copyAction = new JMenuItem("Copy"); 
 
     JMenuItem pasteAction = new JMenuItem("Paste"); 
 
     JMenuItem UndoAction = new JMenuItem("Undo"); 
 
     JMenuItem RedoAction = new JMenuItem("Redo"); 
 
     JMenuItem clearAction = new JMenuItem("Clear"); 
 
     JMenuItem saveAction = new JMenuItem("Save"); 
 
     JMenuItem exportAction = new JMenuItem("Export"); 
 
     JMenuItem printAction = new JMenuItem("Print"); 
 
     JMenuItem ConvertAction = new JMenuItem("Convert To Tables"); 
 
     JMenuItem ColorAction = new JMenuItem("Color Picker"); 
 
     JMenuItem ZoomAction = new JMenuItem("Zoom"); 
 
     JMenuItem EntityAction = new JMenuItem("Entity & Attributes"); 
 
     JMenuItem RelationshipAction = new JMenuItem("Relationship Attributes"); 
 
     JMenuItem HelpAction = new JMenuItem("Help"); 
 
     JMenuItem AboutAction = new JMenuItem("About"); 
 

 
     fileMenu.add(newAction); 
 
     fileMenu.addSeparator(); 
 
     fileMenu.add(openAction); 
 
     fileMenu.addSeparator(); 
 
     fileMenu.add(saveAction); 
 
     fileMenu.addSeparator(); 
 
     fileMenu.add(exportAction); 
 
     fileMenu.addSeparator(); 
 
     fileMenu.add(printAction); 
 
     fileMenu.addSeparator(); 
 
     fileMenu.add(exitAction); 
 

 
     editMenu.add(UndoAction); 
 
     editMenu.addSeparator(); 
 
     editMenu.add(RedoAction); 
 
     editMenu.addSeparator(); 
 
     editMenu.add(cutAction); 
 
     editMenu.addSeparator(); 
 
     editMenu.add(copyAction); 
 
     editMenu.addSeparator(); 
 
     editMenu.add(pasteAction); 
 
     editMenu.addSeparator(); 
 
     editMenu.add(clearAction); 
 

 
     dbMenu.add(ConvertAction); 
 

 
     ToolsMenu.add(ColorAction); 
 
     ToolsMenu.addSeparator(); 
 
     ToolsMenu.add(ZoomAction); 
 
     ToolsMenu.addSeparator(); 
 
     ToolsMenu.add(EntityAction); 
 
     ToolsMenu.addSeparator(); 
 
     ToolsMenu.add(RelationshipAction); 
 

 
     HelpMenu.add(HelpAction); 
 
     HelpMenu.addSeparator(); 
 
     HelpMenu.add(AboutAction); 
 
     
 
     
 
     exitAction.addActionListener(new ActionListener() { 
 
      public void actionPerformed(ActionEvent arg0) { 
 
       
 
     }} 
 
     ); 
 
     
 
     
 
     
 
     
 
     
 
     
 
     ConvertAction.addActionListener(new ActionListener() { 
 
      public void actionPerformed(ActionEvent arg0) { 
 
       
 
       new ConvertForm().setVisible(true); 
 
       
 
       
 
       
 
     }} 
 
     ); 
 
     
 
     
 
     
 

 
     newAction.addActionListener(new ActionListener() { 
 
      public void actionPerformed(ActionEvent arg0) { 
 

 
       new Lesson49_1().setVisible(true); 
 
      } 
 
     }); 
 
     
 
     
 

 
     JPanel buttonPanel = new JPanel(); 
 
     
 
     JPanel FieldPanel = new JPanel(); 
 

 
     // Swing box that will hold all the buttons 
 

 
     Box theBox = Box.createVerticalBox(); 
 
     Box theBoxs = Box.createVerticalBox(); 
 

 
     // Make all the buttons in makeMeButtons by passing the 
 
     // button icon. 
 

 
     
 
     lineBut = makeMeButtons("./src/line.png", 2); 
 
     ellipseBut = makeMeButtons("./src/ellipse.png", 3); 
 
     rectBut = makeMeButtons("./src/rectangle.png", 4); 
 

 
     // Make all the buttons in makeMeColorButton by passing the 
 
     // button icon and true for stroke color or false for fill 
 

 
     strokeBut = makeMeColorButton("./src/stroke.png", 5, true); 
 

 

 
     // Add the fields to the boxs 
 

 
     
 

 
     //theBox.add(brushBut); 
 
     theBox.add(lineBut); 
 
     theBox.add(ellipseBut); 
 
     theBox.add(rectBut); 
 
     theBox.add(strokeBut); 
 
     
 
     buttonPanel.add(theBox); 
 
     FieldPanel.add(theBoxs); 
 
     
 

 
     this.add(buttonPanel, BorderLayout.WEST); 
 
     this.add(FieldPanel, BorderLayout.EAST); 
 
     buttonPanel.setPreferredSize(new Dimension(200,480));   
 
     FieldPanel.setPreferredSize(new Dimension(200,480)); 
 
     // Make the drawing area take up the rest of the frame 
 

 
     // this.add(new DrawingBoard(), BorderLayout.CENTER); 
 
     final DrawingBoard drawPanel = new DrawingBoard(); 
 
     this.add(drawPanel, BorderLayout.CENTER); 
 
     this.getContentPane().setBackground(Color.WHITE); 
 

 
     
 
     
 
     
 
     
 
     
 
     exportAction.addActionListener(new ActionListener() { 
 

 
      public void actionPerformed(ActionEvent arg0) { 
 
       BufferedImage image = new BufferedImage(drawPanel.getWidth(), 
 
         drawPanel.getHeight(), BufferedImage.TYPE_INT_ARGB); 
 
       Graphics2D g = image.createGraphics(); 
 
       drawPanel.paint(g); 
 
       g.dispose(); 
 

 
       JFileChooser fileChooser = new JFileChooser(); 
 
       File theDirectory = new File("C:/Users/Wenda/Desktop"); 
 
       fileChooser.setCurrentDirectory(theDirectory); 
 
       FileNameExtensionFilter pngFilter = new FileNameExtensionFilter(
 
         "PNG file (*.png)", "png"); 
 
       fileChooser.addChoosableFileFilter(pngFilter); 
 
       fileChooser.setFileFilter(pngFilter); 
 

 
       int status = fileChooser.showSaveDialog(Lesson49_1.this); 
 

 
       if (status == JFileChooser.APPROVE_OPTION) { 
 
        try { 
 
         ImageIO.write(image, "png", 
 
           fileChooser.getSelectedFile()); 
 
         JOptionPane.showMessageDialog(null, "Image saved to " 
 
           + fileChooser.getSelectedFile().getName()); 
 
        } catch (Exception ex) { 
 
         ex.printStackTrace(); 
 
        } 
 
       } 
 
      } 
 
     }); 
 
     // Show the frame 
 
     this.setVisible(true); 
 
    } 
 

 
    public JButton makeMeButtons(String iconFile, final int actionNum) { 
 
     JButton theBut = new JButton(); 
 
     Icon butIcon = new ImageIcon(iconFile); 
 
     theBut.setIcon(butIcon); 
 

 
     theBut.addActionListener(new ActionListener() { 
 

 
      public void actionPerformed(ActionEvent e) { 
 
       currentAction = actionNum; 
 
      } 
 
     }); 
 
     return theBut; 
 
    } 
 

 
    // Spits out buttons based on the image supplied and 
 
    // whether a stroke or fill is to be defined 
 

 
    public JButton makeMeColorButton(String iconFile, final int actionNum, 
 
      final boolean stroke) { 
 
     JButton theBut = new JButton(); 
 
     Icon butIcon = new ImageIcon(iconFile); 
 
     theBut.setIcon(butIcon); 
 

 
     theBut.addActionListener(new ActionListener() { 
 

 
      public void actionPerformed(ActionEvent e) { 
 

 
       if (stroke) { 
 

 
        // JColorChooser is a popup that lets you pick a color 
 

 
        strokeColor = JColorChooser.showDialog(null, 
 
          "Pick a Stroke", Color.BLACK); 
 
       } else { 
 
            } 
 
      } 
 
     }); 
 

 
     return theBut; 
 
    } 
 
    public class DrawingBoard extends JComponent { 
 

 
     private static final long serialVersionUID = -4431176095451940075L; 
 

 
     // ArrayLists that contain each shape drawn along with 
 
     // that shapes stroke and fill 
 
     ArrayList<Shape> shapes = new ArrayList<Shape>(); 
 
     ArrayList<Color> shapeStroke = new ArrayList<Color>(); 
 
     
 
     Point drawStart, drawEnd; 
 
     // Monitors events on the drawing area of the frame 
 

 
     public DrawingBoard() { 
 

 
      this.addMouseListener(new MouseAdapter() { 
 

 
       public void mousePressed(MouseEvent e) { 
 

 
        if (currentAction != 1) { 
 

 
         // When the mouse is pressed get x & y position 
 

 
         drawStart = new Point(e.getX(), e.getY()); 
 
         drawEnd = drawStart; 
 
         repaint(); 
 
        } 
 
       } 
 
      
 
       public void mouseReleased(MouseEvent e) { 
 

 
        if (currentAction != 1) { 
 
         Shape aShape = null; 
 
         
 
         if (currentAction == 2) { 
 
          aShape = drawLine(drawStart.x, drawStart.y, 
 
          e.getX(), e.getY()); 
 
          shapes.add(aShape); 
 
          shapeStroke.add(strokeColor); 
 
          drawStart = null; 
 
          drawEnd = null; 
 
          repaint(); 
 
         } else 
 

 
         if (currentAction == 3) { 
 
          aShape = drawEllipse(drawStart.x, drawStart.y, 
 
          e.getX(), e.getY()); 
 
          shapes.add(aShape); 
 
          shapeStroke.add(strokeColor); 
 
          drawStart = null; 
 
          drawEnd = null; 
 
          repaint(); 
 
          new AttributeForm().setVisible(true); 
 
         } else 
 

 
         if (currentAction == 4) { 
 

 
          // Create a new rectangle using x & y coordinates 
 

 
          aShape = drawRectangle(drawStart.x, drawStart.y, 
 
          e.getX(), e.getY()); 
 
          shapes.add(aShape); 
 
          shapeStroke.add(strokeColor); 
 
          drawStart = null; 
 
          drawEnd = null; 
 
          repaint(); 
 
          new EntityForm().setVisible(true); 
 
         } 
 

 
         // Add shapes, fills and colors to there ArrayLists 
 

 
               
 

 
        } 
 

 
       } 
 
      }); 
 
      
 
       this.addMouseListener(new MouseAdapter() { 
 
      @Override 
 
      public void mouseClicked(MouseEvent me) { 
 
       JTextField name = new JTextField(15); 
 
       super.mouseClicked(me); 
 
       for (Shape s : shapes) { 
 

 
        if (s.contains(me.getPoint())) {//check if mouse is clicked within shape 
 

 
         //we can either just print out the object class name 
 
         System.out.println("Clicked a "+s.getClass().getName()); 
 

 
         //or check the shape class we are dealing with using instance of with nested if 
 
         if (s instanceof Rectangle2D) { 
 
          
 
          //create table 
 
          
 
         } 
 
         else if (s instanceof Ellipse2D) { 
 
          
 
          
 
           
 
          
 
          
 
          
 
         } 
 

 
        } 
 
       } 
 
      } 
 
     }); 
 

 
      this.addMouseMotionListener(new MouseMotionAdapter() { 
 

 
       public void mouseDragged(MouseEvent e) { 
 

 
        // If this is a brush have shapes go on the screen quickly 
 

 
        if (currentAction == 1) { 
 

 
         int x = e.getX(); 
 
         int y = e.getY(); 
 

 
         Shape aShape = null; 
 
         shapes.add(aShape); 
 

 
         shapeStroke.add(strokeColor); 
 

 
         // Add the transparency value 
 
        } 
 

 
        // Get the final x & y position after the mouse is dragged 
 

 
        drawEnd = new Point(e.getX(), e.getY()); 
 
        repaint(); 
 
       } 
 
      }); 
 
     } 
 

 
     public void paint(Graphics g) { 
 
      // Class used to define the shapes to be drawn 
 

 
      graphSettings = (Graphics2D) g; 
 

 
      // Antialiasing cleans up the jagged lines and defines rendering 
 
      // rules 
 

 
      graphSettings.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
 
        RenderingHints.VALUE_ANTIALIAS_ON); 
 

 
      // Defines the line width of the stroke 
 

 
      graphSettings.setStroke(new BasicStroke(4)); 
 

 
      // Iterators created to cycle through strokes and fills 
 
      Iterator<Color> strokeCounter = shapeStroke.iterator(); 
 
      for (Shape s : shapes) { 
 
    
 
       // Grabs the next stroke from the color arraylist 
 
       graphSettings.setPaint(strokeCounter.next()); 
 

 
       graphSettings.draw(s); 
 

 
      } 
 

 
      // Guide shape used for drawing 
 
      if (drawStart != null && drawEnd != null) { 
 
       // Makes the guide shape transparent 
 

 
       graphSettings.setComposite(AlphaComposite.getInstance(
 
         AlphaComposite.SRC_OVER, 0.40f)); 
 

 
       // Make guide shape gray for professional look 
 

 
       graphSettings.setPaint(Color.LIGHT_GRAY); 
 

 
       Shape aShape = null; 
 

 
       if (currentAction == 2) { 
 
        aShape = drawLine(drawStart.x, drawStart.y, drawEnd.x, 
 
          drawEnd.y); 
 
       } else 
 

 
       if (currentAction == 3) { 
 
        aShape = drawEllipse(drawStart.x, drawStart.y, drawEnd.x, 
 
          drawEnd.y); 
 
       } else 
 

 
       if (currentAction == 4) { 
 

 
        // Create a new rectangle using x & y coordinates 
 

 
        aShape = drawRectangle(drawStart.x, drawStart.y, drawEnd.x, 
 
          drawEnd.y); 
 
       } 
 

 
       graphSettings.draw(aShape); 
 
      } 
 
     } 
 

 
    
 
     private Rectangle2D.Float drawRectangle(int x1, int y1, int x2, int y2) { 
 
      // Get the top left hand corner for the shape 
 
      // Math.min returns the points closest to 0 
 

 
      int x = Math.min(x1, x2); 
 
      int y = Math.min(y1, y2); 
 

 
      // Gets the difference between the coordinates and 
 

 
      int width = Math.abs(x1 - x2); 
 
      int height = Math.abs(y1 - y2); 
 

 
      return new Rectangle2D.Float(x, y, width, height); 
 
     } 
 

 
      private Ellipse2D.Float drawEllipse(int x1, int y1, int x2, int y2) { 
 
      int x = Math.min(x1, x2); 
 
      int y = Math.min(y1, y2); 
 
      int width = Math.abs(x1 - x2); 
 
      int height = Math.abs(y1 - y2); 
 

 
      return new Ellipse2D.Float(x, y, width, height); 
 
     } 
 

 
     private Line2D.Float drawLine(int x1, int y1, int x2, int y2) { 
 

 
      return new Line2D.Float(x1, y1, x2, y2); 
 
     } 
 
      } 
 
    
 
    } 
 

Может кто-то пожалуйста, помогите мне?

+0

Возможно ли, что объект будет связан со многими объектами? – Anil

+0

Все, что вам нужно сделать, это проверить границы объектов. Скажем, у нас две формы s1 и s2. Если s1.maxRight> s2.minLeft AND (s1.maxbottom> s2.maxbottom ИЛИ s1.minTop

+0

Вы можете попробовать что-то вроде [this] (http://stackoverflow.com/questions/20927189/detecting-collision-of-two-sprites-that-can-rotate/20928531#20928531) – MadProgrammer

ответ

0

Есть два случая.

  1. Основываясь на том, что вы показали, что это, кажется, что если линия связана с вашим эллипсу, она связана только в центре верхней или это может быть в центре стороны, и мы можем что если ваша линия пересекает ваш эллипс в центре стороны, вы можете рассматривать эллипс как прямоугольник. И тогда в Java можно использовать
    Rectangle yourLine = new Rectangle(line.x, line.y, line.width, line.height); Rectangle ellipse = new Rectangle(ellipse.upperLeft.x, ellipse.upperLeft.y, ellipse.width, ellipse.height); boolean isThereAnIntersection = yourLine.intersects(ellipse);

  2. Для общего метода, при работе над сложными формами, вы можете использовать BufferedImage как буфер ваших рисунков затем отображать BufferedImage в методе paint(Graphics g). Используя этот BufferedImage, чтобы нарисовать ваш эллипс и линии, вы можете напрямую проверить, будут ли границы линии рисоваться над цветными пикселями или фоновыми пикселями, что означает, если нарисованы над цветными пикселями, что уже есть объект, нарисованный в месте , поэтому вам, наконец, придется получить объект в зависимости от его местоположения.

+0

Из памяти в интересах использовать ограничивающий прямоугольник формы, который может давать ложные срабатывания для непрямоугольных фигур, но это зависит от вашего определения пересечения. – MadProgrammer

+0

Как я могу определить java, являются ли это цветными пикселями или фоновыми пикселями? – Lana

+0

@LanaM Ваша проблема в другом, вы можете искать «идеальное обнаружение столкновения на пиксель», там много ответивших на вопросы, на которые нужно ответить, вам просто нужно сделать быстрый поиск;) –

 Смежные вопросы

  • Нет связанных вопросов^_^