Newton tool
About the code
Additions to the library
		// mouse buttons
		#define BUT_LEFT    (1 << 0)
		#define BUT_RIGHT   (1 << 1)
		class CSystem
		{
		public:
			[...]
			Uint8   buttons;        // true while a button is pressed
			Uint8   buttonsDown;    // true only at the frame the button is pressed
			Uint8   buttonsUp;      // true only at the frame the button is released
			int     mouseX;
			int     mouseY;
				
Goal of the program
The Polynomial class
		p(z) = c0*zn + c1*zn-1 + ... + cn-1*z + cn
				
		class Polynomial
		{
		private:
			std::vector<Complex> coefficients;
		public:
			std::vector<Complex> roots;
				
		int Polynomial::degree()
		{
			return coefficients.size() - 1;
		}
				
		void Polynomial::addRoot(Complex r)
		{
			roots.push_back(r);
			coefficients.resize(roots.size() + 1);
		}
		void Polynomial::remRoot()
		{
			roots.pop_back();
			coefficients.resize(roots.size() + 1);
		}
				
		Complex Polynomial::evaluate(Complex z)
		{
			Complex result = Complex(0, 0);
			Complex zn = Complex(1, 0);
			for (int i = degree(); i >= 0; i--)
			{
				result = result + zn * coefficients[i];
				zn = zn * z;
			}
			return result;
		}
				
		void Polynomial::derivative(Polynomial& result)
		{
			result.coefficients.clear();
			for (int i = 0; i <= degree()-1; i++)
			{
				Complex coef = coefficients[i] * (degree() - i);
				result.coefficients.push_back(coef);
			}
		}
				
Finding the coefficients
		p(z) = c0*zn + c1*zn-1 + ... + cn-1*z + cn
				
		p(z) = (z - r0)(z - r1)...(z - rn-1)
				
		c0 = 1
		c1 = (-r0) + (-r1) + ...
		c2 = (-r0)*(-r1) + (-r0)*(-r2) + ... + (-r1)*(-r2) + (-r1)*(-r3) + ...
		...
		cn = (-r0)*(-r1)*(-r2)...
				
		std::vector<int> idx;
				
		idx[0] < idx[1] < ... < idx[n-1]
				
		idx[0] = 0;
		idx[1] = id[0] + 1;
		idx[2] = id[1] + 1;
		...
				
		idx[0] = 0;
		idx[1] = 1;
		idx[2] = 2;
		idx[3] = 3;
				
		idx[0] = 0;
		idx[1] = 1;
		idx[2] = 2;
		idx[3] = 4;
				
		idx[0] = 0;
		idx[1] = 1;
		idx[2] = 2;
		idx[3] = 5;
				
		idx[0] = 0;
		idx[1] = 1;
		idx[2] = 2;
		idx[3] = n-1;
				
		idx[0] = 0;
		idx[1] = 1;
		idx[2] = 2;
		idx[3] = n;
				
		idx[0] = 0;
		idx[1] = 1;
		idx[2] = 3;
		idx[3] = n;
				
		idx[0] = 0;
		idx[1] = 1;
		idx[2] = 3;
		idx[3] = 4;
				
		idx[0] = 0;
		idx[1] = 1;
		idx[2] = n-2;
		idx[3] = n-1;
				
		idx[0] = 0;
		idx[1] = 1;
		idx[2] = n-2;
		idx[3] = n;
				
		idx[0] = 0;
		idx[1] = 1;
		idx[2] = n-1;
		idx[3] = n;
				
		idx[0] = 0;
		idx[1] = 2;
		idx[2] = n-1;
		idx[3] = n;
				
		idx[0] = 0;
		idx[1] = 2;
		idx[2] = 3;
		idx[3] = 4;
				
Implementation of findCoefficients
		void Polynomial::findCoefficients()
		{
			std::vector<int> idx;
			idx.resize(roots.size() + 1);
				
			coefficients[0] = 1;
				
			for (int i = 1; i <= degree(); i++)
			{
				coefficients[i] = Complex(0, 0);
				int j;
				
				for (j = 0; j < i; j++)
					idx[j] = j;
				
				while(true)
				{
				
					Complex c = Complex(1, 0);
					for (j = 0; j < i; j++)
						c = c * (-roots[idx[j]]);
				
					coefficients[i] = coefficients[i] + c;
				
					j = i - 1;
				
					while(true)
					{
				
						idx[j]++;
				
						if (idx[j] == roots.size() - ((i-1) - j))
						{
							j--;
							if (j < 0)
								break;
						}
				
						else
						{
							for (int k = j + 1; k < i; k++)
								idx[k] = idx[k - 1] + 1;
							break;
						}
					}
				
					if (j < 0)
						break;
				}
				
Progressive drawing
		void drawNewton(int offsetX, int offsetY, std::vector<Color>& palette)
		{
			for (int yy = 0; yy < SCREEN_HEIGHT; yy += 8)
			{
				for (int xx = 0; xx < SCREEN_WIDTH; xx += 8)
				{
				
		static Uint8 pattern[64] =
		{
			 0, 36,  4, 32, 18, 54, 22, 50,
			 2, 38,  6, 34, 16, 52, 20, 48,
			 9, 45, 13, 41, 27, 63, 31, 59,
			11, 47, 15, 43, 25, 61, 29, 57,
			 1, 37,  5, 33, 19, 55, 23, 51,
			 3, 39,  7, 35, 17, 53, 21, 49,
			 8, 44, 12, 40, 26, 62, 30, 58,
			10, 46, 14, 42, 24, 60, 28, 56
		};
		[...]
		while (sys.isQuitRequested() == false)
		{
			// draw the fractal
			if (frameCount < 64)
			{
				drawNewton(pattern[frameCount] % 8,
				           pattern[frameCount] / 8,
				           palette);
				frameCount++;
			}
				
Handling the mouse
		// display and process the events
		gfx.render();
		sys.wait(20);
		sys.processEvents();
		// left mouse button: add a new root
		if (sys.buttonsDown & BUT_LEFT)
		{
			// restart the drawing
			frameCount = 0;
			// choose a random color
			palette[palette.size()-1] = Color(rand() % 256, rand() % 256, rand() % 256);
			palette.push_back(Color(0, 0, 0));
			// add the root
			Complex r;
			r.re = (sys.mouseX - centerX) * zoom;
			r.im = (sys.mouseY - centerY) * zoom;
			p.addRoot(r);
			// recompute the coefficients
			p.findCoefficients();
			p.derivative(dp);
		}
		// right mouse button: remove the last root
		if (sys.buttonsDown & BUT_RIGHT)
		{
			// if there is at least one root
			if (p.roots.size() > 0)
			{
				// restart the drawing
				frameCount = 0;
				// remove the root
				palette.pop_back();
				p.remRoot();
				// recompute the coefficients
				p.findCoefficients();
				p.derivative(dp);
			}
		}
		Download source code
		Download executable for Windows
				 
				 
				