2012-12-31 44 views
5

Tôi bắt đầu tạo một bộ xem fractal cho mandelbrot. Tôi đang gặp phải rất nhiều vấn đề khi phóng to hình ảnh fractal. Nếu bạn cố gắng thu phóng, người xem sẽ chỉ đóng ở trung tâm. Tôi đã làm nhiều nhất có thể để hiểu được tình trạng tiến thoái lưỡng nan này. Làm thế nào tôi có thể phóng to trên fractal của tôi theo cách mà khi tôi phóng to, nó sẽ phóng to ở trung tâm của màn hình, và không phải là trung tâm của fractal?Phóng to trên bộ fractal của Mandelbrot trong Java

import java.awt.*; 
import java.awt.image.BufferedImage; 
import javax.swing.*; 
import java.awt.event.*; 



public class Mandelbrot extends JFrame implements ActionListener { 

    private JPanel ctrlPanel; 
    private JPanel btnPanel; 
    private int numIter = 50; 
    private double zoom = 130; 
    private double zoomIncrease = 100; 
    private int colorIter = 20; 
    private BufferedImage I; 
    private double zx, zy, cx, cy, temp; 
    private int xMove, yMove = 0; 
    private JButton[] ctrlBtns = new JButton[9]; 
    private Color themeColor = new Color(150,180,200); 

    public Mandelbrot() { 
     super("Mandelbrot Set"); 
     setBounds(100, 100, 800, 600); 
     setResizable(false); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     plotPoints(); 

     Container contentPane = getContentPane(); 

     contentPane.setLayout(null); 




     ctrlPanel = new JPanel(); 
     ctrlPanel.setBounds(600,0,200,600); 
     ctrlPanel.setBackground(themeColor); 
     ctrlPanel.setLayout(null); 

     btnPanel = new JPanel(); 
     btnPanel.setBounds(0,200,200,200); 
     btnPanel.setLayout(new GridLayout(3,3)); 
     btnPanel.setBackground(themeColor); 

     ctrlBtns[1] = new JButton("up"); 
     ctrlBtns[7] = new JButton("down"); 
     ctrlBtns[3] = new JButton ("left"); 
     ctrlBtns[5] = new JButton("right"); 
     ctrlBtns[2] = new JButton("+"); 
     ctrlBtns[0] = new JButton("-"); 
     ctrlBtns[8] = new JButton(">"); 
     ctrlBtns[6] = new JButton("<"); 
     ctrlBtns[4] = new JButton(); 

     contentPane.add(ctrlPanel); 
     contentPane.add(new imgPanel()); 
     ctrlPanel.add(btnPanel); 

     for (int x = 0; x<ctrlBtns.length;x++){ 
      btnPanel.add(ctrlBtns[x]); 
      ctrlBtns[x].addActionListener(this); 
     } 

     validate(); 

    } 

    public class imgPanel extends JPanel{ 
     public imgPanel(){ 
      setBounds(0,0,600,600); 

     } 

     @Override 
     public void paint (Graphics g){ 
      super.paint(g); 
      g.drawImage(I, 0, 0, this); 
     } 
    } 

    public void plotPoints(){ 
     I = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB); 
     for (int y = 0; y < getHeight(); y++) { 
      for (int x = 0; x < getWidth(); x++) { 
       zx = zy = 0; 
       cx = (x - 320+xMove)/zoom; 
       cy = (y - 290+yMove)/zoom; 
       int iter = numIter; 
       while (zx * zx + zy * zy < 4 && iter > 0) { 
        temp = zx * zx - zy * zy + cx; 
        zy = 2 * zx * zy + cy; 
        zx = temp; 
        iter--; 
       } 
       I.setRGB(x, y, iter | (iter << colorIter)); 
      } 
     } 
    } 

    public void actionPerformed(ActionEvent ae){ 
     String event = ae.getActionCommand(); 

     switch (event){ 
     case "up": 
      yMove-=100; 
      break; 
     case "down": 
      yMove+=100; 
      break; 
     case "left": 
      xMove-=100; 
      break; 
     case "right": 
      xMove+=100; 
      break; 
     case "+": 
      zoom+=zoomIncrease; 
      zoomIncrease+=100; 
      break; 
     case "-": 
      zoom-=zoomIncrease; 
      zoomIncrease-=100; 
      break; 
     case ">": 
      colorIter++; 
      break; 
     case "<": 
      colorIter--; 
      break; 
     } 



     plotPoints(); 
     validate(); 
     repaint(); 
    } 




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

Trả lời

2

tôi đã có thể khắc phục vấn đề này bằng cách có một sự thay đổi theo chiều ngang hoặc dọc thêm mỗi khi tôi phóng to

Do đó, thay vì phải:.

case "+": //zooming in 
zoom+=zoomIncrease; 
zoomIncrease+=100; 
break; 

bây giờ tôi sẽ có

case "+": 
initialZoom = zoom; 
zoom+=zoomIncrease; 
zoomIncrease*=2; 
xMove*=2; 
yMove*=2; 
break; 

điều này về cơ bản sẽ di chuyển hình ảnh đã được vẽ bằng cách nhân chuyển động của nó trên trục x và y với hệ số thu phóng đã tăng (là hai).

+0

Vui lòng [chấp nhận] (http://meta.stackexchange.com/a/65088/155831) câu trả lời khi bạn có cơ hội. Vui mừng bạn đã nhận nó được sắp xếp. :) –

+2

Nhân xMove bằng cách phóng to, để sau này bạn có thể chia bằng cách thu phóng, về cơ bản sẽ hoạt động, nhưng có vẻ như đó là một cách quá phức tạp để thực hiện điều đó. Trên thực tế, kết quả không chính xác về mặt toán học: thu phóng bắt đầu ở 130 và zoomIncrease bắt đầu ở mức 100 và khi bạn thêm những thứ đó lại với nhau, nó không tăng gấp đôi chính xác, do đó tăng gấp đôi xMove sẽ không chính xác. Hãy nhớ rằng, trong tất cả các mã hóa, đơn giản là luôn luôn tốt hơn. Đơn giản hóa và làm cho thuật toán này chính xác, bằng cách loại bỏ zoomIncrease và chỉ đơn giản là sử dụng 'zoom * = 2; ' – AgilePro

5

Tập hợp Mandelbrot tồn tại trong mặt phẳng toán học có toạ độ tự nhiên. Bạn "xem" điều này với một BufferedImage tôi sử dụng "xem cổng" tọa độ. Đó là tất cả trong việc lập bản đồ giữa chúng. Bạn đã gắn nhãn tọa độ khung nhìn là x và y và tọa độ "thực" vào không gian Mandelbrot dưới dạng cx và cy. Đây là các công thức:

 cx = (x - 320+xMove)/zoom; 
     cy = (y - 290+yMove)/zoom; 

Để phóng to và thu nhỏ một điểm "thực" cụ thể, bạn muốn lượng dịch chuyển của bạn không đổi khi bạn phóng to. Vấn đề là số lượng chuyển dịch đang được thu nhỏ bởi số lượng zoom. Nhớ cx và cy là tọa độ thực trong mặt phẳng Mandelbrot và x & y là tọa độ khung nhìn. Vì vậy, khi nhìn vào giữa khung nhìn, khi bạn thay đổi zoom, bạn muốn cx & cy để giữ nguyên.

tôi đoán là bạn muốn một cái gì đó như:

cx = ((x - 320)/zoom) + xMove; 
    cy = ((y - 290)/zoom) + yMove; 

Điều này sẽ làm cho "phong trào" trong mặt phẳng Mandelbrot vẫn phụ thuộc vào số lượng zoom. Tôi giả sử rằng 320 và 290 có liên quan đến kích thước khung nhìn và cung cấp cho bạn một số không ở giữa chế độ xem.

Bạn sẽ muốn số tiền xMove & yMove thay đổi trên một tổ hợp phím không phải là số tiền cố định (100) mà là số tiền tùy thuộc vào mức thu phóng. Khi bạn phóng to rất nhiều, bạn muốn lượng chuyển động trong mặt phẳng Mandelbrot thực nhỏ hơn cho mỗi lần nhấn phím.