Пользовательский Zoom in / out на JPanel не является линейным - PullRequest
0 голосов
/ 10 сентября 2018

Чтобы не тратить ваше время, я сокращу его:

Мой проект : графическое представление множества Мандельброта.

Мой прогресс : завершено, за исключением ошибки в функции увеличения / уменьшения

Ошибка : масштаб увеличения меньше (медленнее), чем масштаб уменьшения


Более короткая версия: как я могу имитировать увеличение / уменьшение коэффициента на jpanel.

В конце небольшая часть jPanel должна быть увеличена до всей jPanel,Каждый пиксель в jPanel представляет целое число, но вам не нужно беспокоиться об отсутствии целых чисел после увеличения.


Более длинная версия (только если вам нужна дополнительная информация):

функция масштабирования в наборе Мандельброта:

public void recalculate(int x, int y, int width, int height, double scale){
    downright=new Complex(upleft.getReal()+stepwidth*(x+width/scale),upleft.getImg()-stepwidth*(y+height/scale));
    upleft=new Complex(upleft.getReal()+stepwidth*(x-width/scale), upleft.getImg()-stepwidth*(y-height/scale));
    stepwidth=(downright.getReal()-upleft.getReal())/width;
    calc(lastrep);
}

Краткая терминология:

  • прямо внизу - комплексное число справа внизупоследний пиксель, который будет нарисован на jpanel
  • вверх, является, следовательно, верхним левым комплексным числом, первый пиксель, который будет нарисован на jpanel
  • , ширина шага - это расстояние между каждымкомплексное число, представленное одним пикселем
  • calc - это, наконец, функция, которая вычисляет каждый цвет для каждого пикселя в соответствии с правилами набора Мандельброта

параметры ширины и высоты - ширина / высота пикселяjpanel, x и y - это координаты увеличения и масштабирования коэффициента увеличения.

Когда я вызываю эту функцию mandelbrot.recalculate(x,y, getWidth(), getHeight(), 10);, это должно увеличивать точку (x, y)так что новое представленное изображение составляет 1/5 фактического изображения.

1/5 должно быть потому, что начало изображения (вверх) составляет 1/10 от количества пикселей полной ширины и высоты, сдвинутых вверх и влево от точки (x, y) иконец изображения (прямо) составляет 1/10 от количества пикселей полной ширины и высоты, смещенных вниз и вправо.

Так что если я вызываю функцию после увеличения, как это: mandelbrot.recalculate(x,y, getWidth(), getHeight(), 0.1); она должна полностью изменить весь процесс, но это не


, это предполагаемое увеличение: Zoom in on Mandelbrotset

1 Ответ

0 голосов
/ 22 сентября 2018

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

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

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

//The new midpoint needs the old stepwith to calculate correctly
Complex newmidpoint = new Complex(upleft.getReal()+x*stepwidth, upleft.getImg()-y*stepwidth);

//zooming in
double distwidth = downright.getReal()-upleft.getReal();
double distheight = upleft.getImg()-downright.getImg();
double newreal = upleft.getReal()+(1/scale)*distwidth;
double newimg = upleft.getImg()-(1/scale)*distheight;
downright=new Complex(newreal, newimg);
stepwidth=(downright.getReal()-upleft.getReal())/width;

//the old midpoint is actually the already zoomed in midpoint, it needs the new stepwidth
Complex oldmidpoint = new Complex(upleft.getReal()+width/2.0*stepwidth,upleft.getImg()-height/2.0*stepwidth);
Complex diffmidpoint = newmidpoint.subtract(oldmidpoint);

upleft=new Complex(upleft.getReal()+diffmidpoint.getReal(),upleft.getImg()+diffmidpoint.getImg());
downright=new Complex(downright.getReal()+diffmidpoint.getReal(), downright.getImg()+diffmidpoint.getImg());
calc(lastrep);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...