Что я должен сделать, чтобы позволить общей прямоугольной angular области комплексной плоскости быть видимой на изображении? - PullRequest
0 голосов
/ 11 апреля 2020

Я надеюсь, что у всех все в порядке :) У меня есть программа Java, которая показывает изображение, и мне нужно изменить его, чтобы позволить общей прямоугольной области angular комплексной плоскости быть видимой на изображении. Пользователь может выбрать прямоугольник, перетаскивая мышь. Может ли кто-нибудь помочь мне сделать это? Вот код:

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

 public class Mandelbrot extends JApplet {
 public static void main(String s[]) {
 JFrame frame = new JFrame();
  frame.setTitle("Mandelbrot set");
 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 JApplet applet = new Mandelbrot();
 applet.init();
 frame.getContentPane().add(applet);
 frame.pack();
 frame.setVisible(true);
 }

 public void init() {
 JPanel panel = new MandelbrotPanel();
 getContentPane().add(panel);
 }
 }

 class MandelbrotPanel extends JPanel{
 BufferedImage bi;

 public MandelbrotPanel() {
 int w = 500;
 int h = 500;
 setPreferredSize(new Dimension(w, h));
 setBackground(Color.white);
 bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
 WritableRaster raster = bi.getRaster();
 int[] rgb = new int[3];
 float xmin = -2;
 float ymin = -2;
 float xscale = 4f/w;
 float yscale = 4f/h;
 for (int i = 0; i < h; i++) {
 for (int j = 0; j < w; j++) {
 float cr = xmin + j * xscale;
 float ci = ymin + i * yscale;
 int count = iterCount(cr, ci);
 rgb[0] = (count & 0x07) << 5;
 rgb[1] = ((count >> 3) & 0x07) << 5;
 rgb[2] = ((count >> 6) & 0x07) << 5;
 raster.setPixel(j, i, rgb);
 }
 }
 }

 private int iterCount(float cr, float ci) {
 int max = 512;
 float zr = 0;
 float zi = 0;
 float lengthsq = 0;
 int count = 0;
 while ((lengthsq < 4.0) && (count < max)) {
 float temp = zr * zr - zi * zi + cr;
 zi = 2 * zr * zi + ci;
 zr = temp;
 lengthsq = zr * zr + zi * zi;
 count++;
 }
 return max-count;
 }

 public void paintComponent(Graphics g) {
 super.paintComponent(g);
 g.drawImage(bi, 0, 0, this);
 }
 }

Заранее спасибо:)

1 Ответ

0 голосов
/ 12 апреля 2020

Вам нужно будет отслеживать прямоугольник сложной плоскости, которую вы показываете пользователю. Для этого вы можете использовать класс Rectangle2D.Double в java .awt.geom. Исходный прямоугольник имеет верхний левый угол -2 + 2i, ширину и высоту 4:

Rectangle2D.Double viewRect = new Rectangle2D.Double(-2, 2, 4, 4);

Вам нужно переместить код чертежа за пределы конструктора, чтобы он мог запускаться более одного раза, и отрегулируйте его так, чтобы он учитывал текущее значение viewRect:

 float xmin = viewRect.x;
 float ymin = viewRect.y;
 float xscale = viewRect.width/w;
 float yscale = viewRect.height/h;

Когда вы добавляете методы, чтобы получать уведомления о перетаскивании мышью, вам нужно будет вычислить новый viewRect. Верхний левый угол соответствует комплексному номеру, с которого началось перетаскивание. Поскольку в Java нет класса комплексных чисел, давайте временно использовать Point2D.Double:

    Point2D.Double dragStartComplex = new Point2D.Double(
            viewRect.x + viewRect.width * dragStart.x/w,
            viewRect.y - viewRect.height * dragStart.y/h);

Аналогично вы можете выяснить, на каком комплексном числе закончилось перетаскивание:

    Point2D.Double dragEndComplex = new Point2D.Double(
            viewRect.x + viewRect.width * dragEnd.x/w,
            viewRect.y - viewRect.height * dragEnd.y/h);

Один раз у вас есть углы, вы можете вычислить новый прямоугольник вида. После этого вы будете перекрашивать.

    viewRect.setRect(dragStartPoint.x, dragStartPoint.y, 
            dragEndPoint.x-dragStartPoint.x, dragEndPoint.y-dragStartPoint.y);

Это небольшое упрощение, потому что ничто не гарантирует, что пользователь всегда будет перетаскивать слева направо и сверху вниз. Для поддержки других направлений перетаскивания вам нужно будет перетаскивать координаты, чтобы (viewRect.x, viewRect.y) всегда находился в верхнем левом углу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...