Path2D GeometricRecognizer::resample(Path2D points)
	{
		double interval = pathLength(points) / (numPointsInGesture - 1); // interval length
		double D = 0.0;
		Path2D newPoints;

		//--- Store first point since we'll never resample it out of existence
		newPoints.push_back(points.front());
	    for(int i = 1; i < (int)points.size(); i++)
		{
			Point2D currentPoint  = points[i];
			Point2D previousPoint = points[i-1];
			double d = getDistance(previousPoint, currentPoint);
			if ((D + d) >= interval)
			{
				double qx = previousPoint.x + ((interval - D) / d) * (currentPoint.x - previousPoint.x);
				double qy = previousPoint.y + ((interval - D) / d) * (currentPoint.y - previousPoint.y);
				Point2D point(qx, qy);
				newPoints.push_back(point);
				points.insert(points.begin() + i, point);
				D = 0.0;
			}
			else D += d;
		}

		// somtimes we fall a rounding-error short of adding the last point, so add it if so
		if (newPoints.size() == (numPointsInGesture - 1))
		{
			newPoints.push_back(points.back());
		}

		return newPoints;
	}
	/**
	 * Shift the points so that the center is at 0,0.
	 * That way, if everyone centers at the same place, we can measure
	 *  the distance between each pair of points without worrying about
	 *  where each point was originally drawn
	 * If we didn't do this, shapes drawn at the top of the screen
	 *  would have a hard time matching shapes drawn at the bottom
	 *  of the screen
	 */
	Path2D GeometricRecognizer::translateToOrigin(Path2D points)
	{
		Point2D c = centroid(points);
		Path2D newPoints;
		for (Path2DIterator i = points.begin(); i != points.end(); i++)
		{
			Point2D point = *i;
			double qx = point.x - c.x;
			double qy = point.y - c.y;
			newPoints.push_back(Point2D(qx, qy));
		}
		return newPoints;
	}
	Path2D GeometricRecognizer::rotateBy(Path2D points, double rotation) 
	{
		Point2D c     = centroid(points);
		//--- can't name cos; creates compiler error since VC++ can't
		//---  tell the difference between the variable and function
		double cosine = cos(rotation);	
		double sine   = sin(rotation);
		
		Path2D newPoints;
		for (Path2DIterator i = points.begin(); i != points.end(); i++)
		{
			Point2D point = *i;
			double qx = (point.x - c.x) * cosine - (point.y - c.y) * sine   + c.x;
			double qy = (point.x - c.x) * sine   + (point.y - c.y) * cosine + c.y;
			newPoints.push_back(Point2D(qx, qy));
		}
		return newPoints;
	}
	Path2D GeometricRecognizer::scaleToSquare(Path2D points)
	{
		//--- Figure out the smallest box that can contain the path
		DollarRecognizer::Rectangle box = boundingBox(points);
		Path2D newPoints;
		for (Path2DIterator i = points.begin(); i != points.end(); i++)
		{
			Point2D point = *i;
			//--- Scale the points to fit the main box
			//--- So if we wanted everything 100x100 and this was 50x50,
			//---  we'd multiply every point by 2
			double scaledX = point.x * (this->squareSize / box.width);
			double scaledY = point.y * (this->squareSize / box.height);
			//--- Why are we adding them to a new list rather than 
			//---  just scaling them in-place?
			// TODO: try scaling in place (once you know this way works)
			newPoints.push_back(Point2D(scaledX, scaledY));
		}
		return newPoints;
	}