1
votes

I have been doing Mandelbrot set and trying to zoom but zooming patters gets very troubling. When i zoom it zooms perfectly but the image size is reduced to half of the original. Next time I zoom again the pic size increases and tries to skip the viewing window. The code is in c++/opengl. I tried to make my code little clean before posting here.

#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

double dividecubesby  = 700;
double left = -2.0;
double right = 2.0;
double bottom = -2.0;
double top = 2.0;
int maxiteration = 128;
int zoomlevel = 3;
double baseSize = 4.0;
double SizeReal;
double SizeImage;
double xco=0.0;
double yco=0.0;

void whatcoordinate(int x,int y)
{
    int xp=x;
    int yp=y;
    double delta1 = (right-left);
    double tempx;   
    double tempy;
    double delta=0.0;   
    double l = dividecubesby/2;

    delta = delta1/dividecubesby;

    if((xp > l) && (yp < l))
    {
        tempx = xp*delta;
        tempy = yp*delta;

        xco = right - tempx;
        yco = top - tempy;

        if(xco <0)xco=xco*-1;
        if(yco <0)yco=yco*-1;
    }
    else if( (x < l) && (y < l))
    {
        tempx = xp*delta;
        tempy = yp*delta;

        xco = right - tempx;
        yco = top - tempy;

        if(xco >0)xco=xco*-1;
        if(yco <0) yco =yco*-1;
    }
    else if((x < l) && (y > l))
    {
        tempx = xp*delta;
        tempy = yp*delta;

        xco = right - tempx;
        yco = top - tempy;

        if(xco >0)xco=xco*-1;
        if(yco >0)yco=yco*-1;
    }
    else if((x > l) && (y > l))
    {
        tempx = xp*delta;
        tempy = yp*delta;

        xco = right - tempx;
        yco = right - tempy;

        if(xco <0)xco=xco*-1;
        if(yco >0)yco=yco*-1;
    }
}

void keyPressed(unsigned char key, int x, int y)
{
    switch(key)
    {
    case 'z':
        printf("z pressed  x= %d, y= %d \n",x,y);

        whatcoordinate(x,y);

        SizeReal = (pow(2.0, (-zoomlevel)))*baseSize;
        SizeImage = (pow(2.0, (-zoomlevel)))*baseSize;

        baseSize = right-left;

        left   =  xco- (SizeReal/2);
        right  =  xco + (SizeReal/2);
        bottom = yco - (SizeReal/2);
        top    = yco + (SizeReal/2);    
        dividecubesby = dividecubesby+500;      
        maxiteration  = maxiteration+500; 
        zoomlevel=zoomlevel+1;

        glutPostRedisplay();

        break;
    }
}

int mandtest(double Cr, double Ci)
{
    double Zr = 0.0;
    double Zi = 0.0;
    int times = 0;
    double temp;
    Zr = Zr+Cr;
    Zi = Zi+Ci;

    while ((((Zr*Zr)+(Zi*Zi))<=4) && (times < maxiteration))
    {
        temp = (Zr*Zr)-(Zi*Zi);
        Zi = 2*Zr*Zi;

        Zr = temp+Cr;
        Zi = Zi+Ci;                

        times = times+1;  

    }

    return times;
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0f,1.0f,1.0f);
    double deltax = ((right - left)/(dividecubesby-1));//this means length/700 
    double deltay = ((top- bottom)/(dividecubesby-1));// this means length/700

    gluOrtho2D(left,right,bottom,top);
    glBegin(GL_POINTS);

    for(double x= left;x<=right;x += deltax )
    {
        for(double y= bottom; y<=top;y +=  deltay )
        {
            if((mandtest(x,y))==maxiteration)
            {
                glColor3f(1.0f,1.0f,1.0f); 
                glVertex2f(x,y);
            }
            else 
            {
                glColor3f((float)mandtest(x,y)/10,0.0f,(float)mandtest(x,y)/30);
                glVertex2f(x,y);
            }
        }
    }
    glEnd();

    glFlush();
}

void init()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
}

int main(int argc, char ** argv)
{   
    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(dividecubesby,dividecubesby);
    glutCreateWindow("A Simple OpenGL Windows Application with GLUT");
    init();
    glutDisplayFunc(display);
    glutKeyboardFunc(keyPressed);
    glutMainLoop();

    return 0;
}

when executed

1) enter image description here

2)enter image description here

3) enter image description here

2
Please provide cleaner code and a minimal example. Probably the scaling does not depend on the Mandelbrot calculation itsels. - c_k
i have edited some part of code .. i do the scaling by picking a point and adding small distance " SizeReal = (pow(2.0, (-zoomlevel)))*baseSize;" on left right top bottom .. but i have no idea why the image just tries to run away from the normal view :( - solti
It seems like you are zooming in 'Mandelbrot function coordinates' and at the same time your are changing the projection matrix. I would try to forget about Mandelbrot and first try to zoom a filled rectangle with constant color. - c_k
thank you Corijin for the response .. I did with constant color like you said and the result is the same. The whole image gets shrunk into a square like that of image 2 ( for fist z pressed) .. and again expand like that of 3 (second z pressed) but this time with whole window covered. I might have to look closely post as soon i see some anomalies ... this is blowing my mind and image at same time - solti

2 Answers

2
votes

I think you should not change your view transformation using gluOrtho2D(left,right,bottom,top) for every rerender. Just give them (the initial) fixed values. The view will stay the same, as you have in image 1). You should just transform the coordinates you pass to your Mandelbrot function.

And as @genpfault mentions: consider using textures. That's more efficient.

2
votes

The problem was fixed by placing

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

just above gluOrtho2D(left,right,bottom,top); in the display function This is for initialization. This was explained well in chapter 2 of opengl super bible book.

1) enter image description here

2) enter image description here

3) enter image description here