All pastes #191106 Raw Edit

mandelbrot

public cpp v1 · immutable
·published 2006-10-04 17:26 UTC
rendered paste body
//	9.29.06//	mandelbrot.cpp//	QT/OpenGL implementation of Mandelbrot set// Load in our mandelbrot.h#include "mandelbrot.h"///////////////////////////////////////////////////////////////////////	Name:	MandelbrotWidget::MandelbrotWidget()//	Notes:	Called at the beginning to setup variables/////////////////////////////////////////////////////////////////////MandelbrotWidget::MandelbrotWidget(){	h = 0;	w = 0;	// Zoom factor (e.g. 1=1x, 2=2x, etc.)	zoom = 1;	// Placement of zoom 	moveX = -0.5;	moveY = 0;		// Max number of iterations to determine escape	MaxIter = 100;}///////////////////////////////////////////////////////////////////////	Name:	MandelbrotWidget::MandelbrotWidget()//	Notes:	Called at the beginning to setup CUSTOM varibles/////////////////////////////////////////////////////////////////////MandelbrotWidget::MandelbrotWidget(double z, double mx, double my, int maxit){	// Zoom factor (e.g. 1=1x, 2=2x, etc.)	zoom = z;	// Placement of zoom 	moveX = mx;	moveY = my;		// Max number of iterations to determine escape	MaxIter = maxit;}///////////////////////////////////////////////////////////////////////	Name:	MandelbrotWidget::initializeGL()//	Notes:	Called at the beginning to initialize GL specs/////////////////////////////////////////////////////////////////////void MandelbrotWidget::initializeGL(){	// Set clear (background) color to white	// RGBA = Red,Green,Blue,Alpha (blending between old and new color at pixel location)	glClearColor(1.0, 1.0, 1.0, 0.0);		// Set shade model to basic flat not needed since we are drawing points, not lines or polygons	// glShadeModel(GL_FLAT);	}///////////////////////////////////////////////////////////////////////	Name:		MandelbrotWidget::resizeGL()//	Notes:	Called upon everytime there a resize event/////////////////////////////////////////////////////////////////////void MandelbrotWidget::resizeGL(int width, int height ){	// ------------------------------------------------------	// Debugging information, print out screen size 	w = width;	h = height;	cout << "resize " << w << "x" << h << endl;	// ------------------------------------------------------	// Change viewport to match resize	glViewport(0, 0, width, height);		// Change matrix mode to affect projection	glMatrixMode(GL_PROJECTION);	// Clear the matrix by loading identity matrix	glLoadIdentity();		// Specify coordinate system (min x, max x, min y, max y, min z, max z) 	// For mandelbrot, we are only concerned with the circle of radio 2.	gluOrtho2D(0.0, width, 0.0, height);		// gluOrtho2D(-2.0, 2.0, -2.0, 2.0);		// Change matrix mode to affect modelview	glMatrixMode(GL_MODELVIEW);	// Update drawing		updateGL();	}///////////////////////////////////////////////////////////////////////	Name:	MandelbrotWidget::paintGL()//	Notes:	Called upon everytime there is a [re]paint event//			needed./////////////////////////////////////////////////////////////////////void MandelbrotWidget::paintGL(){	// Clear the window to clear (background) color	glClear(GL_COLOR_BUFFER_BIT);	// Paint points (as oppose to a shaded polygon)	glBegin(GL_POINTS);	// Draw mandelbrot	DrawMandel();}///////////////////////////////////////////////////////////////////////	Name:	MandelbrotWidget::mousePressEvent()//	Notes: 	Called upon whenever the mouse button is pressed/////////////////////////////////////////////////////////////////////void MandelbrotWidget::mousePressEvent(QMouseEvent *event){	// Calculate which way to spin	if (event->button() == LeftButton)	{		cout << "left click\n";		// Zoom in		// event->x() and event->y()		// double CImag = (y-h/2) / (0.5*zoom*h)+moveY;		// double CReal = 1.5*(x-w/2) / (0.5*zoom*w)+moveX;		zoom = zoom + 1;		moveY = (event->y()-h/2) / (0.5*zoom*h)+moveY;		moveX = 1.5*(event->x()-w/2) / (0.5*zoom*w)+moveX;				}	else if (event->button() == RightButton)	{		cout << "right click\n";		// Zoom out			}	else if (event->button() == MidButton)	{		cout << "middle click\n";		// Reset		zoom = 1;		moveX = -0.5;		moveY = 0;	}	// Update	updateGL();	}///////////////////////////////////////////////////////////////////////	Name:	MandelbrotWidget::Drawmandel()//	Notes:	Draws mandelbrot based on currnet width/height /////////////////////////////////////////////////////////////////////void MandelbrotWidget::DrawMandel(){	// Cycle through every pixel determining whether Z escapes at that point	for (int y = 0; y < h; y++)	{		// We must convert every pixel location (x,y) to it's repsective coordinates on the complex plane w/ circle radius 2		// Example:	On a 100x100 screen, pixel location (50,50) is (0,0i) on the complex plane		//		on a 100x100 screen, pixel location (50,100) is (0,2i) on th complex plane		// Method:	Measure fraction of screen covered (so pixel 50w of a 100w screen is 1/2 screen) and		//		apply that to complex plane (1/2 of screen is equal to 0 on the complex plane of -2 to 2).				// Imaginary porition of C		// float CImag = (y-h/2) / (0.5*zoom*h)+moveY;		float CImag = 2 -((y/(float)h)*4);				for (int x = 0; x < w; x++)		{			// Real portion of C			// float CReal = 1.5*(x-w/2) / (0.5*zoom*w)+moveX;			float CReal = -2 + (x/(float)w)*4;												// Define Z initially to C			float ZReal = CReal;			float ZImag = CImag;			// Squre the two values of Z (real and imaginary)			float ZRealSquared = ZReal * ZReal;			float ZImagSquared = ZImag * ZImag;						// Iteration counter			int i = 0;						// Loop until MaxIterations or |Z| escapes radius of 2			// Recall that |Z| = sqrt(Real^2+Imag^2) and Z^2 = Real^2 + Imag^2			while ( (i < MaxIter) && (sqrt(ZRealSquared + ZImagSquared) < 2)  )			{				// Calculate new Z (real and imaginary)				ZReal = ZRealSquared - ZImagSquared + CReal;				ZImag = 2*ZReal * ZImag + CImag;								// Square the two values of Z (real and imaginary)				ZRealSquared = ZReal * ZReal;				ZImagSquared = ZImag * ZImag;								// Increase counter				i++;			}					// Paint pixel			// Variate color choices			float f1 = 0.5 + 0.5*cos((float)i*0.1);			float f2 = 0.5 + 0.5*cos((float)(i+16)*0.1);			float f3 = 0.5 + 0.5*cos((float)(i+32)*0.1);						// Setup openGL color (RGB)			glColor3f(f1,f2,f3);							if (i == MaxIter)			{				glColor3f(0.0,0.0,1.0);			}					// Draw vertex (pixel)			glVertex2f(x, y);						// ------------------------------------------------------			// Debugging information, print out screen size 			// cout << "complex pos (" << CReal << "," << CImag << ") complete";			// ------------------------------------------------------			}	}	// End painting	glEnd();	// Execute the previous commands immediately	glFlush();}