public final GravityAction init(float gravity, float fromY, float toY, int bounces, float bounciness) throws IllegalArgumentException {
		if (gravity <= 0) {
			throw new IllegalArgumentException("gravity must be positive");
		}
		if (fromY > toY) {
			throw new IllegalArgumentException("fromY cannot be > toY");
		}
		if (bounces < 0 || bounces > 20) {
			throw new IllegalArgumentException("bounces should be between 0 and 20");
		}
		if (bounciness < 0f || bounciness > 1f) {
			throw new IllegalArgumentException("bounciness should be between 0 and 1");
		}
		this.gravity = gravity;
		this.toY = toY;

		// Calculate durations and heights.
		{
			intervals = 1 + 2 * bounces;
			float distance = toY - fromY;
			heights[0] = fromY;
			durations[0] = calculateDuration(distance, gravity);
			for (int i = 1; i < intervals; i += 2) {
				distance *= bounciness;
				heights[i] = heights[i + 1] = toY - distance;
				durations[i] = durations[i + 1] = calculateDuration(distance, gravity);
			}
		}
		// Calculate total durations.
		{
			float runningTotalDuration = 0;
			for (int i = 0; i < intervals; ++i) {
				totalDurations[i] = runningTotalDuration += durations[i];
			}
			duration = runningTotalDuration;
		}

		elapsedTime = 0;
		
		return this;
	}