public class

QuadraticBezierCurveMoveModifier

extends DurationEntityModifier
package org.andengine.entity.modifier;

import org.andengine.entity.IEntity;
import org.andengine.util.modifier.ease.EaseLinear;
import org.andengine.util.modifier.ease.IEaseFunction;

/**
 * (c) 2010 Nicolas Gramlich
 * (c) 2011 Zynga Inc.
 * 
 * @author Nicolas Gramlich
 * @since 23:24:26 - 16.07.2011
 */
public class QuadraticBezierCurveMoveModifier extends DurationEntityModifier {
	// ===========================================================
	// Constants
	// ===========================================================

	// ===========================================================
	// Fields
	// ===========================================================

	private final float mX1;
	private final float mY1;
	private final float mX2;
	private final float mY2;
	private final float mX3;
	private final float mY3;

	private final IEaseFunction mEaseFunction;

	// ===========================================================
	// Constructors
	// ===========================================================

	/**
	 * @param pDuration
	 * @param pX1 x coordinate of the start point.
	 * @param pY1 y coordinate of the start point.
	 * @param pX2 x coordinate of the control point.
	 * @param pY2 y coordinate of the ontrol point.
	 * @param pX3 x coordinate of the end point.
	 * @param pY3 y coordinate of the end point.
	 */
	public QuadraticBezierCurveMoveModifier(final float pDuration, final float pX1, final float pY1, final float pX2, final float pY2, final float pX3, final float pY3) {
		this(pDuration, pX1, pY1, pX2, pY2, pX3, pY3, EaseLinear.getInstance(), null);
	}

	/**
	 * @param pDuration
	 * @param pX1 x coordinate of the start point.
	 * @param pY1 y coordinate of the start point.
	 * @param pX2 x coordinate of the control point.
	 * @param pY2 y coordinate of the ontrol point.
	 * @param pX3 x coordinate of the end point.
	 * @param pY3 y coordinate of the end point.
	 * @param pEaseFunction
	 */
	public QuadraticBezierCurveMoveModifier(final float pDuration, final float pX1, final float pY1, final float pX2, final float pY2, final float pX3, final float pY3, final IEaseFunction pEaseFunction) {
		this(pDuration, pX1, pY1, pX2, pY2, pX3, pY3, pEaseFunction, null);
	}

	/**
	 * @param pDuration
	 * @param pX1 x coordinate of the start point.
	 * @param pY1 y coordinate of the start point.
	 * @param pX2 x coordinate of the control point.
	 * @param pY2 y coordinate of the ontrol point.
	 * @param pX3 x coordinate of the end point.
	 * @param pY3 y coordinate of the end point.
	 * @param pEntityModifierListener
	 */
	public QuadraticBezierCurveMoveModifier(final float pDuration, final float pX1, final float pY1, final float pX2, final float pY2, final float pX3, final float pY3, final IEntityModifierListener pEntityModifierListener) {
		this(pDuration, pX1, pY1, pX2, pY2, pX3, pY3, EaseLinear.getInstance(), pEntityModifierListener);
	}

	/**
	 * @param pDuration
	 * @param pX1 x coordinate of the start point.
	 * @param pY1 y coordinate of the start point.
	 * @param pX2 x coordinate of the control point.
	 * @param pY2 y coordinate of the ontrol point.
	 * @param pX3 x coordinate of the end point.
	 * @param pY3 y coordinate of the end point.
	 * @param pEaseFunction
	 * @param pEntityModifierListener
	 */
	public QuadraticBezierCurveMoveModifier(final float pDuration, final float pX1, final float pY1, final float pX2, final float pY2, final float pX3, final float pY3, final IEaseFunction pEaseFunction, final IEntityModifierListener pEntityModifierListener) {
		super(pDuration, pEntityModifierListener);

		this.mX1 = pX1;
		this.mY1 = pY1;
		this.mX2 = pX2;
		this.mY2 = pY2;
		this.mX3 = pX3;
		this.mY3 = pY3;

		this.mEaseFunction = pEaseFunction;
	}

	@Override
	public QuadraticBezierCurveMoveModifier deepCopy() {
		return new QuadraticBezierCurveMoveModifier(this.mDuration, this.mX1, this.mY1, this.mX2, this.mY2, this.mX3, this.mY3, this.mEaseFunction);
	}

	// ===========================================================
	// Getter & Setter
	// ===========================================================

	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================

	@Override
	protected void onManagedInitialize(final IEntity pEntity) {

	}

	@Override
	protected void onManagedUpdate(final float pSecondsElapsed, final IEntity pEntity) {
		final float percentageDone = this.mEaseFunction.getPercentage(this.getSecondsElapsed(), this.mDuration);

		final float u = 1 - percentageDone;
		final float tt = percentageDone*percentageDone;
		final float uu = u*u;

		final float ut2 = 2 * u * percentageDone;

		/* Formula:
		 * ((1-t)^2 * P1) + (2*(t)*(1-t) * P2) + ((tt) * P3) */
		final float x = (uu * this.mX1) + (ut2 * this.mX2) + (tt * this.mX3);
		final float y = (uu * this.mY1) + (ut2 * this.mY2) + (tt * this.mY3);

		pEntity.setPosition(x, y);
	}

	// ===========================================================
	// Methods
	// ===========================================================

	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================
}