QImage CurveTransform::transform() {
	for(unsigned int i = 0; i < image_width; i++) {
		for(unsigned int j = 0; j < image_height; j++) {
			CartesianPair coords = {i, j};
			drawPixels(convertToPixels(convertToCartesian(convertToPolar(coords))),coords); //Lisp, eat your heart out
		}
	}
	return out_image;	
}
vector geodesicSolidBodyVelocityField::streamfunctionAt
(
        const point& p,
        const Time& t
) const
{
    const dimensionedScalar T = (endTime.value() == -1 ) ? t.endTime() : endTime;
    const scalar u0 = 2 * M_PI * radius.value() / T.value();
    const polarPoint& polarp = convertToPolar(p);
    const scalar lat = polarp.lat();
    const scalar lon = polarp.lon();

    const scalar psi = - u0 * (Foam::sin(lat) * Foam::cos(alpha) - Foam::cos(lon) * Foam::cos(lat) * Foam::sin(alpha));

    return p/mag(p) * psi * radius.value();
}
point geodesicSolidBodyVelocityField::initialPositionOf
(
    const point& p,
    const Time& t
) const
{
    // assume alpha = 0
    
    const dimensionedScalar T = (endTime.value() == -1 ) ? t.endTime() : endTime;
    const scalar u0 = 2 * M_PI * radius.value() / T.value();
    const polarPoint& polarp = convertToPolar(p);
    const scalar lat = polarp.lat();
    scalar lon = polarp.lon();

    lon -= u0/radius.value() * t.value(); 

    const polarPoint departureP(lon, lat, radius.value());
    return departureP.cartesian();
}
/**
 * Find the equilibrium after placing the cylinders in the domain somewhere.
 * Iterates until tolerence is met.
 */
void SwarmCylinders::findEquilibrium()
{
	double dalpha = 2.0 * M_PI / (double) M;

	vector<double> m;

	for (int i = 0; i < M; i++)
	{
		m.push_back(spline.evaluate(i * dalpha) * dalpha); /// assuming constant density charge on boundary
	}

	vector<double> xs;
	vector<double> ys;

	for (int i = 0; i < M; i++)
	{
		xs.push_back(spline.evaluate(((double) i + 0.5) * dalpha));
		ys.push_back(((double) i + 0.5) * dalpha);
	}

	convertToCartesian(xs, ys);

	int nIter = 0;
	bool steadyState = false;
	while (!steadyState)
	{
		vector<double> xNew;
		vector<double> yNew;
		const int xsize = x.size();
		for (int i = 0; i < xsize; i++)
		{
			xNew.push_back(0.0);
			yNew.push_back(0.0);
		}

		for (int i = 0; i < xsize; i++)
		{
			double u = 0.0;
			double v = 0.0;

			for (int j = 0; j < xsize; j++) /// from each body
			{
				if (i != j)
				{
					double norm = sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));
					double factor = factorCylinder / (norm * norm * norm);
					u += (x[i] - x[j]) * factor;
					v += (y[i] - y[j]) * factor;
				}
			}

			for (int j = 0; j < M; j++) /// from boundary
			{
				double norm = sqrt((x[i] - xs[j]) * (x[i] - xs[j]) + (y[i] - ys[j]) * (y[i] - ys[j]));
				double factor = factorBoundary * m[j] / (norm * norm * norm);
				u += (x[i] - xs[j]) * factor;
				v += (y[i] - ys[j]) * factor;
			}

			xNew[i] = x[i] + dt * u;
			yNew[i] = y[i] + dt * v;
		}

		convertToPolar(xNew, yNew);

		for (int i = 0; i < xsize; i++)
		{
			const double rMax = spline.evaluate(yNew[i]) - radius;
			if (rMax < xNew[i])
				xNew[i] = 0.1 * rMax; /// move it toward (0,0)

//			xNew[i] = min(spline.evaluate(yNew[i])-radius, xNew[i]); /// make it sit on the boundary if it is not repelled enough (not exactly correct)

		}

		convertToCartesian(xNew, yNew);

		double maxNorm = 0.0;
		for (int i = 0; i < xsize; i++)
		{
			double norm = sqrt((xNew[i] - x[i]) * (xNew[i] - x[i]) + (yNew[i] - y[i]) * (yNew[i] - y[i])); /// relative difference
			maxNorm = max(norm, maxNorm);
		}

		for (int i = 0; i < xsize; i++)
		{
			x[i] = xNew[i];
			y[i] = yNew[i];
		}

		// TODO Remove this testing shit, writing the positions each iteration

		if (nIter % 10 == 0)
		{
			FILE* fidx;
			FILE* fidy;

			if (nIter == 0)
			{
				fidx = fopen("x.txt", "w");
				fidy = fopen("y.txt", "w");
			}
			else
			{
				fidx = fopen("x.txt", "a");
				fidy = fopen("y.txt", "a");
			}

			const int xsize = x.size();
			for (int i = 0; i < xsize; ++i)
			{
				fprintf(fidx, "%e ", x[i]);
				fprintf(fidy, "%e ", y[i]);
			}

			fprintf(fidx, "\n");
			fprintf(fidy, "\n");

			fclose(fidx);
			fclose(fidy);
		}
		nIter++;

		if (maxNorm <= threshold)
			break;

		if (nIter % 5000 == 0)
			printf("** Norm at iteration %d: %e\n", nIter, maxNorm);

		if (nIter > 50000)
		{
			printf("** Something is wrong, swarm shape is not converging quickly enough... aborting... \n");
			abort();
		}
	}
	printf("** Number of iterations to steady state formation: %d\n", nIter);
}