2014-11-27 5 views
0

Mandelbrot 세트를 사용하여 그래픽 이미지를 생성하는 GUI가 있습니다. 몇 가지 확대/축소 버튼을 구현했지만, 마우스 중심으로 새로운 중심점을 조정하여 마우스 중심으로 내 GUI의 중심을 변경할 수 있기를 원합니다. 아주 어렵다는 것이 증명되었습니다. 어떤 제안? 내 시도는 moveGraph 메서드에서 찾을 수 있습니다.마우스 중심으로 GUI 중심 변경 및 다시 칠하기

미리 감사드립니다.

package assn4_12mgs; 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.image.BufferedImage; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 

public class MandelBrot extends JFrame{ 
    MandelPanel mp; 
    double xMax = 2.26; 
    double xMin = -2.24; 
    double yMax = 2.26; 
    double yMin = -2.24; 
    double yMove, xMove; 

    static double ESCAPE_MODULUS = 2.0; 
    static int MAX_ITERATIONS = 32; 

    public MandelBrot(){ 
     super(); 
     setLayout(new BorderLayout()); 
     setTitle("Graham's Mandelbrot GUI"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setSize(600,700); 
     setResizable(false); 

     mp = new MandelPanel(); 
     mp.addMouseListener(new MouseAdapter() { 
      public void mouseReleased(MouseEvent evt) { 
       MoveGraph(evt); 
      } 
     }); 

     JPanel panel = new JPanel(new FlowLayout()); 
     JButton zoomIn = new JButton("+"); 
     zoomIn.addMouseListener(new MouseAdapter() { 
      public void mouseReleased(MouseEvent evt) { 
       ZoomIn(evt); 
      } 
     }); 

     JButton zoomOut = new JButton("-"); 
     zoomOut.addMouseListener(new MouseAdapter() { 
      public void mouseReleased(MouseEvent evt) { 
       ZoomOut(evt); 
      } 
     }); 
     JButton reset = new JButton("Reset"); 
     reset.addMouseListener(new MouseAdapter() { 
      public void mouseReleased(MouseEvent evt) { 
       reset(evt); 
      } 
     }); 

     panel.add(reset, BorderLayout.WEST); ///How to change positioning? 
     panel.add(zoomOut, BorderLayout.EAST); 
     panel.add(zoomIn, BorderLayout.EAST); 
     add(panel, BorderLayout.SOUTH); 
     add(mp, BorderLayout.NORTH); 
    } 

    private void MoveGraph(MouseEvent evt){ 
     int x = evt.getPoint().x; 
     int y = evt.getPoint().y; 
     xMove = x/100; 
     yMove = y/100; 
     mp.repaint(); 
    } 
    private void ZoomIn(MouseEvent evt){ 
     xMax /= 2; 
     xMin /= 2; 
     yMax /= 2; 
     yMin /= 2; 
     mp.repaint(); 
    } 
    private void ZoomOut(MouseEvent evt){ 
     xMax *= 2; 
     xMin *= 2; 
     yMax *= 2; 
     yMin *= 2; 
     mp.repaint(); 
    } 
    private void reset(MouseEvent evt){ 
     xMax = 2.26; 
     xMin = -2.24; 
     yMax = 2.26; 
     yMin = -2.24; 
     xMove = 0; 
     yMove = 0; 
     mp.repaint(); 
    } 

    public class MandelPanel extends JPanel { 
     public MandelPanel() { 
      setPreferredSize(new Dimension(600,600)); 
     } 

     @Override 
     public void paintComponent(Graphics g) 
     { 
      super.paintComponent(g); 

      // draw here 
      int row, col; 
      ComplexNumber c, z; 
      double xPos, yPos; 
      double modulus = 0; 
      boolean escaped = false; 
      int iterations = 0; 
      int desiredColour; 
      // Calculate the scale factor to go from pixels to actual units 
      int height = mp.getHeight(); // drawingZone is the JPanel drawing area 
      int width = mp.getWidth(); 
      double xScale = (xMax - xMin)/width; // These are min and max values in actual 
      double yScale = (yMax - yMin)/height; // coordinates. 

      Graphics2D g2D = (Graphics2D)g; 

      BufferedImage pretty = new BufferedImage(width, height, 
         BufferedImage.TYPE_3BYTE_BGR); 

      // Iterate through the entire panel, pixel by pixel 
      for (row = 0; row < height; row++) { 
       // Calculate the actual y position 
       yPos = yMax - row * yScale;// - yMove 
       for (col = 0; col < width; col++) { 
        // Calculate the actual x position 
        xPos = xMin + col * xScale;// + xMove; 
        // Create the complex number for this position 
        c = new ComplexNumber(xPos, yPos); 
        z = new ComplexNumber(0, 0); 
        iterations = 0; 
        // Iterate the fractal equation z = z*z + c 
        // until z either escapes or the maximum number of iterations 
        // is reached 
        do { 
         z = (z.multiply(z)).add(c); 
         modulus = z.abs(); 
         escaped = modulus > ESCAPE_MODULUS; 
         iterations++; 
        } while (iterations < MAX_ITERATIONS && !escaped); 
        // Set the colour according to what stopped the above loop 
        if (escaped) { 
         desiredColour = setEscapeColour(iterations); 
        } else { 
         desiredColour = setColour(modulus); 
        } 
        pretty.setRGB(col, row, desiredColour); 

       } // end for 
      } // end for 
      g2D.drawImage(pretty, null, 0, 0); 

      //yMove = 0; 
      //xMove = 0; 
     } 
    } 

    // Sets gray level for escape situation 
    private static int setEscapeColour(int numIterations) { 
     float grayLevel = 0.5F - (float) numIterations/MAX_ITERATIONS; 
     grayLevel = Math.max(grayLevel, 0.1F); 
     return new Color(grayLevel, grayLevel, grayLevel).getRGB(); 
    } // end setEscapeColour 

    // Sets colour level for interior situation 
    // The algorithm used here is *totally* empirical! 
    private static int setColour(double modulus) { 
     float factor = (float) (modulus/ESCAPE_MODULUS); 
     float incr = (float) Math.log10(factor * 5.5); 
     float r = Math.min(Math.abs(10.0F * incr) * factor, 1.0F); 
     float g = Math.min(Math.abs(6.0F * incr) * factor, 1.0F); 
     float b = Math.min(Math.abs(0.5F * factor + incr), 1.0F); 
     return new Color(r, g, b).getRGB(); 
    } // end setColour 

    public static void main(String args[]){ 
     MandelBrot manBrot = new MandelBrot(); 
     manBrot.setVisible(true); 

    } 
} 

답변

0

우리는 그 점을 중심으로 창 계산 (거리의 절반을 위로 아래로, 왼쪽 및 오른쪽), 사용자가 도면의 중심점으로 클릭했는지하는 점을. 참조

   /** 
       * Calculate real coordinates of the point we clicked. 
       */ 
       double xDist = Math.abs(xMax) + Math.abs(xMin); 
       double yDist = Math.abs(yMax) + Math.abs(yMin); 
       double xTr = xDist/600.0 * ((double) e.getX()); 
       double yTr = yDist/700.0 * ((double) e.getY()); 

       /** 
       * Calculate the window coordinates. It is relative to the point where the user clicked. 
       */ 
       xMax = xTr + xDist/2.0; 
       xMin = xTr - xDist/2.0; 
       yMax = yTr + yDist/2.0; 
       yMin = yTr - yDist/2.0; 

** 강령 **

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.image.BufferedImage; 
import javax.swing.JOptionPane; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 

public class MandelBrot 
    extends JFrame 
{ 
    public static class ComplexNumber 
    { 
     double re; 
     double im; 

     public void setRe(double re) 
     { 
      this.re = re; 
     } 

     public double re() 
     { 
      return re; 
     } 

     public void setIm(double im) 
     { 
      this.im = im; 
     } 

     public double im() 
     { 
      return im; 
     } 

     public ComplexNumber(double re, double im) 
     { 
      this.re = re; 
      this.im = im; 
     } 

     public ComplexNumber add(ComplexNumber c) 
     { 
      setRe(re() + c.re()); 
      setIm(im() + c.im()); 
      return this; 
     } 

     public ComplexNumber multiply(ComplexNumber z) 
     { 
      setRe(re()*z.re() - im()*z.im()); 
      setIm(im()*z.re() - re()*z.im()); 
      return this; 
     } 

     public double abs() 
     { 
      return Math.sqrt(re()*re() + im()*im()); 
     } 
    } 

    MandelPanel mp; 
    double xMax = 2.26; 
    double xMin = -2.24; 
    double yMax = 2.26; 
    double yMin = -2.24; 
    double yMove, xMove; 

    static double ESCAPE_MODULUS = 2.0; 
    static int MAX_ITERATIONS = 32; 

    public MandelBrot() 
    { 
     super(); 
     setLayout(new BorderLayout()); 
     setTitle("Graham's Mandelbrot GUI"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setSize(600, 700); 
     setResizable(false); 

     mp = new MandelPanel(); 
     mp.addMouseListener(new MouseAdapter() 
     { 
      public void mouseClicked(MouseEvent e) 
      { 
       JOptionPane.showMessageDialog(
         null, 
         "You clicked on a picture area (x,y): (" + e.getX() + "," + e.getY() + ")" , 
         "Info", 
         JOptionPane.INFORMATION_MESSAGE); 

       double xDist = Math.abs(xMax) + Math.abs(xMin); 
       double yDist = Math.abs(yMax) + Math.abs(yMin); 
       double xTr = xDist/600.0 * ((double) e.getX()); 
       double yTr = yDist/700.0 * ((double) e.getY()); 

       xMax = xTr + xDist/2.0; 
       xMin = xTr - xDist/2.0; 
       yMax = yTr + yDist/2.0; 
       yMin = yTr - yDist/2.0; 
       System.out.format("%f %f %f %f %n", xDist, yDist, xTr, yTr); 
       System.out.format("%f %f %f %f %n", xMin, xMax, yMin, yMax); 

       mp.repaint(); 
      } 
      public void mouseReleased(MouseEvent evt) 
      { 
       MoveGraph(evt); 
      } 
     }); 

     JPanel panel = new JPanel(new FlowLayout()); 
     JButton zoomIn = new JButton("+"); 
     zoomIn.addMouseListener(new MouseAdapter() 
     { 
      public void mouseReleased(MouseEvent evt) 
      { 
       ZoomIn(evt); 
      } 
     }); 

     JButton zoomOut = new JButton("-"); 
     zoomOut.addMouseListener(new MouseAdapter() 
     { 
      public void mouseReleased(MouseEvent evt) 
      { 
       ZoomOut(evt); 
      } 
     }); 
     JButton reset = new JButton("Reset"); 
     reset.addMouseListener(new MouseAdapter() 
     { 
      public void mouseReleased(MouseEvent evt) 
      { 
       reset(evt); 
      } 
     }); 

     panel.add(reset, BorderLayout.WEST); ///How to change positioning? 
     panel.add(zoomOut, BorderLayout.EAST); 
     panel.add(zoomIn, BorderLayout.EAST); 
     add(panel, BorderLayout.SOUTH); 
     add(mp, BorderLayout.NORTH); 
    } 

    private void MoveGraph(MouseEvent evt) 
    { 
     int x = evt.getPoint().x; 
     int y = evt.getPoint().y; 
     xMove = x/100; 
     yMove = y/100; 
     mp.repaint(); 
    } 

    private void ZoomIn(MouseEvent evt) 
    { 
     xMax /= 2; 
     xMin /= 2; 
     yMax /= 2; 
     yMin /= 2; 
     mp.repaint(); 
    } 

    private void ZoomOut(MouseEvent evt) 
    { 
     xMax *= 2; 
     xMin *= 2; 
     yMax *= 2; 
     yMin *= 2; 
     mp.repaint(); 
    } 

    private void reset(MouseEvent evt) 
    { 
     xMax = 2.26; 
     xMin = -2.24; 
     yMax = 2.26; 
     yMin = -2.24; 
     xMove = 0; 
     yMove = 0; 
     mp.repaint(); 
    } 

    public class MandelPanel 
      extends JPanel 
    { 

     public MandelPanel() 
     { 
      setPreferredSize(new Dimension(600, 600)); 
     } 

     @Override 
     public void paintComponent(Graphics g) 
     { 
      super.paintComponent(g); 

      // draw here 
      int row, col; 
      ComplexNumber c, z; 
      double xPos, yPos; 
      double modulus = 0; 
      boolean escaped = false; 
      int iterations = 0; 
      int desiredColour; 
      // Calculate the scale factor to go from pixels to actual units 
      int height = mp.getHeight(); // drawingZone is the JPanel drawing area 
      int width = mp.getWidth(); 
      double xScale = (xMax - xMin)/width; // These are min and max values in actual 
      double yScale = (yMax - yMin)/height; // coordinates. 

      Graphics2D g2D = (Graphics2D) g; 

      BufferedImage pretty = new BufferedImage(width, height, 
        BufferedImage.TYPE_3BYTE_BGR); 

      // Iterate through the entire panel, pixel by pixel 
      for (row = 0; row < height; row++) 
      { 
       // Calculate the actual y position 
       yPos = yMax - row * yScale;// - yMove 
       for (col = 0; col < width; col++) 
       { 
        // Calculate the actual x position 
        xPos = xMin + col * xScale;// + xMove; 
        // Create the complex number for this position 
        c = new ComplexNumber(xPos, yPos); 
        z = new ComplexNumber(0, 0); 
        iterations = 0; 
        // Iterate the fractal equation z = z*z + c 
        // until z either escapes or the maximum number of iterations 
        // is reached 
        do 
        { 
         z = (z.multiply(z)).add(c); 
         modulus = z.abs(); 
         escaped = modulus > ESCAPE_MODULUS; 
         iterations++; 
        } 
        while (iterations < MAX_ITERATIONS && !escaped); 
        // Set the colour according to what stopped the above loop 
        if (escaped) 
        { 
         desiredColour = setEscapeColour(iterations); 
        } 
        else 
        { 
         desiredColour = setColour(modulus); 
        } 
        pretty.setRGB(col, row, desiredColour); 

       } // end for 
      } // end for 
      g2D.drawImage(pretty, null, 0, 0); 

      //yMove = 0; 
      //xMove = 0; 
     } 
    } 

    // Sets gray level for escape situation 
    private static int setEscapeColour(int numIterations) 
    { 
     float grayLevel = 0.5F - (float) numIterations/MAX_ITERATIONS; 
     grayLevel = Math.max(grayLevel, 0.1F); 
     return new Color(grayLevel, grayLevel, grayLevel).getRGB(); 
    } // end setEscapeColour 

    // Sets colour level for interior situation 
    // The algorithm used here is *totally* empirical! 
    private static int setColour(double modulus) 
    { 
     float factor = (float) (modulus/ESCAPE_MODULUS); 
     float incr = (float) Math.log10(factor * 5.5); 
     float r = Math.min(Math.abs(10.0F * incr) * factor, 1.0F); 
     float g = Math.min(Math.abs(6.0F * incr) * factor, 1.0F); 
     float b = Math.min(Math.abs(0.5F * factor + incr), 1.0F); 
     return new Color(r, g, b).getRGB(); 
    } // end setColour 

    public static void main(String args[]) 
    { 
     MandelBrot manBrot = new MandelBrot(); 
     manBrot.setVisible(true); 
    } 
}