/*!
	@brief Fills the point array with all the points on the curve, starting at
	parameter u' >= u and ending at point lastPt (which is also added). If
	pts is empty, the first point added is at u' = u. Otherwise, the first 
	point added is at u' > u and meets the following condition:
	     u' = argmin_u'(u' - u) AND (cb(u').x != x0 || cb(u').y != y0).
	
	The points in the array are one-pixel thin and connected.
*/
void CubicBezierParams::Rasterize(double u, const Point& endPt, double stepsize, 
							      POINTS& pts, SmartArray<double>* pParamMap)
{
	Point pt;

	int sz = pts.Size();

	// If not the first point, then cb(u) is already in the array
	if (sz > 0) 
		u += stepsize;

	do
	{
		GetCurvePoint(u, &pt.x, &pt.y);

		//pt.Round(); //point must be rounded (uncomment to get integer coordinates)

		// check that current point is not equal to last point
		if (sz == 0 || !pt.RoundedIsEqual(pts[sz - 1])/*pt != pts[sz - 1]*/)  /*uncomment for integer coords*/
		{
			// check if we have two disconnected points. max dist is sqrt(2)
			if (sz > 1 && pt.SqDist(pts[sz - 1]) > 2)
			{
				Rasterize(u - stepsize, pt, stepsize / 2, pts, pParamMap);
				sz = pts.Size(); // update current size
			}
			// avoid having a "thick" set of 3 pts
			else if (sz > 2 && pt.SqDist(pts[sz - 2]) <= 2)
			{
				// Replace the last point with the current point
				pts[sz - 1] = pt;

				if (pParamMap) 
					(*pParamMap)[sz - 1] = u;
			}
			else // first iteration enters here ALWAYS
			{
				// Add a new point to the array
				pts.AddTail(pt);

				if (pParamMap) 
					pParamMap->AddTail(u);

				sz = pts.Size(); // update current size
			}
		}

		u += stepsize;   // step to the next point

		// The curve param u must be in [-1, 1]. Adding the step size should
		// keep it smaller than 1 + max_stepsize, for max_stepsize == 2
		ASSERT(u <= 3);

	} while (!pt.RoundedIsEqual(endPt)/*pt != endPt*/); /*uncomment for integer coords*/
}