Как увеличить точку курсора в наборе Мандельброта? - PullRequest
0 голосов
/ 22 апреля 2019

В настоящее время я пытаюсь реализовать функцию масштабирования для кода Мандельброта, над которым я работаю.Идея состоит в том, чтобы увеличить / уменьшить, где я щелкнул левой / правой кнопкой мыши.До сих пор всякий раз, когда я нажимаю на экран, фрактал действительно увеличивается. Проблема в том, что фрактал отображается не в начале координат, другими словами, он не увеличивается в точке, которую я хочу.Я надеялся, что здесь я смогу получить как обзор кода, так и концептуальное понимание того, как увеличить точку в целом.

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

MandelBrot.Frag

vec2 normalizedFragPos = (gl_FragCoord.xy/windowSize); //normalize fragment position

dvec2 scaledFragPos = normalizedFragPos*aspectRatio;

scaledFragPos -= aspectRatio/2; //Render the fractal at center of window

scaledFragPos /= scale; //Factor to zoom in or out coordinates.

scaledFragPos -= translation; //Translate coordinate
//Escape Algorithm Below

На своем дескрипторе левого щелчка я подумал, что мне следует преобразовать позицию курсора в тот же диапазон координат, что и в диапазоне Мандельброта.Поэтому я сделал то же самое, что и в фрагментном шейдере:

Window.cpp

float x_coord{ float(GET_X_LPARAM(informaton_long))/size.x }; // normalized mouse x-coordinate
float y_coord{ float(GET_Y_LPARAM(informaton_long))/size.y }; // normalized mouse y-coordinate

x_coord *= aspectRatio[0]; //move point based of relative position to length of window.
y_coord *= aspectRatio[1]; //move point based of relative position to width of window.
x_coord /= scale; //Scale point to match previous zoom factor
y_coord /= scale; //Scale point to match previous zoom factor
translation[0] = x_coord;
translation[1] = y_coord;
//increment scale
scale += .15f;

1 Ответ

0 голосов
/ 22 апреля 2019

Позволяет применить некоторую алгебру. Ваш шейдер выполняет следующее преобразование:

mandelbrotCoord = aspectRatio * (gl_FragCoord / windowSize - 0.5) / scale - translation

Когда мы увеличиваем mouseCoord, мы хотим изменить scale и настроить translation таким образом, чтобы madelbrotCoord под мышкой оставался прежним. Для этого сначала вычислим mandelbrotCoord под мышью по старой шкале:

mandelbrotCoord = aspectRatio * (mouseCoord / windowSize - 0.5) / scale - translation

Затем измените масштаб (который должен быть изменен экспоненциально, кстати):

scale *= 1.1;

Тогда решите для нового перевода:

translation = aspectRatio * (mouseCoord / windowSize - 0.5) / scale - mandelbrotCoord

Также обратите внимание, что ваша система, вероятно, сообщает о координате мыши с координатой y, увеличивающейся вниз, тогда как OpenGL имеет координату окна y, увеличивающуюся вверх (если вы не переопределите ее с помощью glClipControl). Поэтому вам, вероятно, потребуется перевернуть y координату mouseCoord.

mouseCoord[1] = windowSize[1] - mouseCoord[1];

Для лучшего результата я бы также отрегулировал координаты мыши, чтобы они были посередине пикселя (+0,5, +0,5).

Собираем все вместе:

float mouseCoord[] = {
    GET_X_LPARAM(informaton_long) + 0.5,
    GET_Y_LPARAM(informaton_long) + 0.5
};
mouseCoord[1] = size[1] - mouseCoord[1];

float anchor[] = {
    aspectRatio[0] * (mouseCoord[0] / size[0] - 0.5) / scale - translation[0],
    aspectRatio[1] * (mouseCoord[1] / size[1] - 0.5) / scale - translation[1]
};

scale *= 1.1;

translation[0] = aspectRatio[0] * (mouseCoord[0] / size[0] - 0.5) / scale - anchor[0];
translation[1] = aspectRatio[1] * (mouseCoord[1] / size[1] - 0.5) / scale - anchor[1];

Примечание: некоторые из приведенных выше математических операций могут быть отменены. Однако, если вы хотите реализовать правильные функции панорамирования и масштабирования (когда вы можете изменять масштаб колесом мыши во время панорамирования), вам нужно будет сохранить начальные значения mandelbrotCoord того места, где началось панорамирование, а затем повторно использовать его при последующем движении. и события колеса, пока мышь не будет отпущена. Удивительно большое количество зрителей понимают эту часть неправильно!

...