Я пишу C программу для рендеринга набора Мандельброта, и в настоящее время я пытаюсь выяснить, как правильно увеличить масштаб.
Я хочу, чтобы масштабирование было в состоянии следовать за указателем мыши на экране - так, чтобы фрактал увеличивался в положение курсора.
У меня есть окно, определяемое как:
# define WIDTH 800
# define HEIGHT 600
Мои Re_max, Re_min, Im_Max, Im_Min
определены и инициализированы следующим образом:
man->re_max = 2.0;
man->re_min = -2.0;
man->im_max = 2.0;
man->im_min = -2.0;
Значение интерполяции (подробнее об этом позже) определяется и инициализируется следующим образом:
pos->interp = 1.0;
Чтобы отобразить координаты пикселя в центре экрана, I Я использую функцию позиционирования:
void position(int x, int y, t_mandel *man)
{
double *s_x;
double *s_y;
s_x = &man->pos->shift_x;
s_y = &man->pos->shift_y;
man->c_re = (x / (WIDTH / (man->re_max - man->re_min)) + man->re_min) + *s_x;
man->c_im =(y / (HEIGHT / (man->im_max - man->re_min)) + man->im_min) + *s_y;
man->c_im *= 0.8;
}
Для увеличения я сначала получаю координаты указателя мыши и сопоставляю их с видимой областью, заданной прямоугольником, определенным (Re_Max, Re_Min, Im_Max, Im_Min
), используя это функция, где x и y - координаты указателя на экране:
int mouse_move(int x, int y, void *p)
{
t_fract *fract;
t_mandel *man;
fract = (t_fract *)p;
man = fract->mandel;
fract->mouse->Re = x / (WIDTH / (man->re_max - man->re_min)) + man->re_min;
fract->mouse->Im = y / (HEIGHT / (man->im_max - man->re_min)) + man->im_min;
return (0);
}
Эта функция вызывается при регистрации прокрутки колесика мыши. Фактическое масштабирование достигается с помощью этой функции:
void zoom_control(int key, t_fract *fract)
{
double *interp;
interp = &fract->mandel->pos->interp;
if (key == 5) // zoom in
{
*interp = 1.0 / 1.03;
apply_zoom(fract->mandel, fract->mouse->Re, fract->mouse->Im, *interp);
}
else if (key == 4) // zoom out
{
*interp = 1.0 * 1.03;
apply_zoom(fract->mandel, fract->mouse->Re, fract->mouse->Im, *interp);
}
}
, которая вызывает это:
void apply_zoom(t_mandel *man, double m_re, double m_im, double interp)
{
man->re_min = interpolate(m_re, man->re_min, interp);
man->im_min = interpolate(m_im, man->im_min, interp);
man->re_max = interpolate(m_re, man->re_max, interp);
man->im_max = interpolate(m_im, man->im_max, interp);
}
У меня есть простая функция интерполяции для переопределения прямоугольника, ограничивающего область:
double interpolate(double start, double end, double interp)
{
return (start + ((end - start) * interp));
}
Итак, проблема в следующем:
Мой код отображает фрактал следующим образом - Мандельброт установлен
Но когда я пытаюсь увеличить, как описано с помощью мыши, вместо этого из-за того, что вы идете хорошо «внутрь», он просто искажает, как этот , изображение просто как бы сваливается на себя вместо того, чтобы фактически погрузиться во фрактал.
Я был бы очень признателен за помощь с этим, так как Я застрял на нем некоторое время.
Если бы вы могли также объяснить реальную математику ваших решений, я был бы очень рад!
Спасибо!