Confetto { protected static long computeBound(float initialPos, float velocity, float acceleration, Long targetTime, Float targetVelocity, int minBound, int maxBound) { if (acceleration != 0) { final int bound = acceleration > 0 ? maxBound : minBound; if (targetTime == null || targetTime < 0) { final double tmp = Math.sqrt( 2 * acceleration * bound - 2 * acceleration * initialPos + velocity * velocity); final double firstTime = (-tmp - velocity) / acceleration; if (firstTime > 0) { return (long) firstTime; } final double secondTime = (tmp - velocity) / acceleration; if (secondTime > 0) { return (long) secondTime; } return Long.MAX_VALUE; } else { final double time = (bound - initialPos - velocity * targetTime - 0.5 * acceleration * targetTime * targetTime + targetVelocity * targetTime) / targetVelocity; return time > 0 ? (long) time : Long.MAX_VALUE; } } else { float actualVelocity = targetTime == null ? velocity : targetVelocity; final int bound = actualVelocity > 0 ? maxBound : minBound; if (actualVelocity != 0) { final double time = (bound - initialPos) / actualVelocity; return time > 0 ? (long) time : Long.MAX_VALUE; } else { return Long.MAX_VALUE; } } }  void prepare(Rect bound); boolean onTouchDown(MotionEvent event); void onTouchMove(MotionEvent event); void onTouchUp(MotionEvent event); abstract int getWidth(); abstract int getHeight(); void reset(); boolean applyUpdate(long passedTime); void draw(Canvas canvas); void setInitialDelay(long val); void setInitialX(float val); void setInitialY(float val); void setInitialVelocityX(float val); void setInitialVelocityY(float val); void setAccelerationX(float val); void setAccelerationY(float val); void setTargetVelocityX(Float val); void setTargetVelocityY(Float val); void setInitialRotation(float val); void setInitialRotationalVelocity(float val); void setRotationalAcceleration(float val); void setTargetRotationalVelocity(Float val); void setTTL(long val); void setFadeOut(Interpolator fadeOutInterpolator);  }
@Test public void test_computeBound_noAcceleration() { long time = Confetto.computeBound(0f, 0.01f, 0f, null, null, -10000, 100); assertEquals(10000, time); time = Confetto.computeBound(0f, -0.01f, 0f, null, null, -100, 10000); assertEquals(10000, time); time = Confetto.computeBound(10f, 0.01f, 0f, null, null, -10000, 100); assertEquals(9000, time); time = Confetto.computeBound(10f, -0.01f, 0f, null, null, -100, 10000); assertEquals(11000, time); time = Confetto.computeBound(0f, 0.01f, 0f, null, 0.02f, -10000, 100); assertEquals(10000, time); time = Confetto.computeBound(0f, -0.01f, 0f, null, 0.02f, -100, 10000); assertEquals(10000, time); time = Confetto.computeBound(0f, 0.01f, 0f, 0L, -0.01f, -100, 10000); assertEquals(10000, time); time = Confetto.computeBound(-100f, 0.01f, 0f, null, null, -50, 100); assertEquals(20000, time); }
@Test public void test_computeBound_withAcceleration() { long time = Confetto.computeBound(0f, 0f, 0.01f, null, null, -10000, 100); assertEquals(141, time); time = Confetto.computeBound(0f, 0f, -0.01f, null, null, -100, 10000); assertEquals(141, time); time = Confetto.computeBound(10f, 0.01f, 0.01f, null, null, -10000, 100); assertEquals(133, time); time = Confetto.computeBound(-10f, -0.01f, -0.01f, null, null, -100, 10000); assertEquals(133, time); }
@Test public void test_computeBound_withAccelerationAndTargetVelocity() { long time = Confetto.computeBound(0f, 0f, 0.01f, 3L, 0.03f, -10000, 100); assertEquals(3334, time); time = Confetto.computeBound(0f, 0f, -0.01f, 3L, -0.03f, -100, 10000); assertEquals(3334, time); time = Confetto.computeBound(10f, 0.01f, 0.01f, 3L, 0.04f, -10000, 100); assertEquals(2251, time); time = Confetto.computeBound(10f, -0.01f, -0.01f, 3L, -0.04f, -100, 10000); assertEquals(2251, time); }