| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * Functions to model constant acceleration as a cubic Bezier | |
| 7 * curve (http://en.wikipedia.org/wiki/Bezier_curve). These functions are | |
| 8 * intended to generate the transition timing function for CSS transitions. | |
| 9 * Please see | |
| 10 * [http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag]. | |
| 11 * | |
| 12 * The main operation of computing a cubic Bezier is split up into multiple | |
| 13 * functions so that, should it be required, more operations and cases can be | |
| 14 * supported in the future. | |
| 15 */ | |
| 16 class BezierPhysics { | |
| 17 static final _ONE_THIRD = 1 / 3; | |
| 18 static final _TWO_THIRDS = 2 / 3; | |
| 19 | |
| 20 /** | |
| 21 * A list [:[x1, y1, x2, y2]:] of the intermediate control points of a cubic | |
| 22 * bezier when the final velocity is zero. This is a special case for which | |
| 23 * these control points are constants. | |
| 24 */ | |
| 25 static final List<num> _FINAL_VELOCITY_ZERO_BEZIER = | |
| 26 const [_ONE_THIRD, _TWO_THIRDS, _TWO_THIRDS, 1]; | |
| 27 | |
| 28 /** | |
| 29 * Given consistent kinematics parameters for constant acceleration, returns | |
| 30 * the intermediate control points of the cubic Bezier curve that models the | |
| 31 * motion. All input values must have correct signs. | |
| 32 * Returns a list [:[x1, y1, x2, y2]:] representing the intermediate control | |
| 33 * points of the cubic Bezier. | |
| 34 */ | |
| 35 static List<num> calculateCubicBezierFromKinematics( | |
| 36 num initialVelocity, num finalVelocity, num totalTime, | |
| 37 num totalDisplacement) { | |
| 38 // Total time must be greater than 0. | |
| 39 assert(!GoogleMath.nearlyEquals(totalTime, 0) && totalTime > 0); | |
| 40 // Total displacement must not be 0. | |
| 41 assert(!GoogleMath.nearlyEquals(totalDisplacement, 0)); | |
| 42 // Parameters must form a consistent constant acceleration model in | |
| 43 // Newtonian kinematics. | |
| 44 assert(GoogleMath.nearlyEquals(totalDisplacement, | |
| 45 (initialVelocity + finalVelocity) * 0.5 * totalTime)); | |
| 46 | |
| 47 if (GoogleMath.nearlyEquals(finalVelocity, 0)) { | |
| 48 return _FINAL_VELOCITY_ZERO_BEZIER; | |
| 49 } | |
| 50 List<num> controlPoint = _tangentLinesToQuadraticBezier( | |
| 51 initialVelocity, finalVelocity, totalTime, totalDisplacement); | |
| 52 controlPoint = _normalizeQuadraticBezier(controlPoint[0], controlPoint[1], | |
| 53 totalTime, totalDisplacement); | |
| 54 return _quadraticToCubic(controlPoint[0], controlPoint[1]); | |
| 55 } | |
| 56 | |
| 57 /** | |
| 58 * Given a quadratic curve crossing points (0, 0) and (x2, y2), calculates the | |
| 59 * intermediate control point (x1, y1) of the equivalent quadratic Bezier | |
| 60 * curve with starting point (0, 0) and ending point (x2, y2). | |
| 61 * [m0] The slope of the line tangent to the curve at (0, 0). | |
| 62 * [m2] The slope of the line tangent to the curve at a different | |
| 63 * point (x2, y2). | |
| 64 * [x2] The x-coordinate of the other point on the curve. | |
| 65 * [y2] The y-coordinate of the other point on the curve. | |
| 66 * Returns a list [:[x1, y1]:] representing the intermediate | |
| 67 * control point of the quadratic Bezier. | |
| 68 */ | |
| 69 static List<num> _tangentLinesToQuadraticBezier( | |
| 70 num m0, num m2, num x2, num y2) { | |
| 71 if (GoogleMath.nearlyEquals(m0, m2)) { | |
| 72 return [0, 0]; | |
| 73 } | |
| 74 num x1 = (y2 - x2 * m2) / (m0 - m2); | |
| 75 num y1 = x1 * m0; | |
| 76 return [x1, y1]; | |
| 77 } | |
| 78 | |
| 79 /** | |
| 80 * Normalizes a quadratic Bezier curve to have end point at (1, 1). | |
| 81 * [x1] The x-coordinate of the intermediate control point. | |
| 82 * [y1] The y-coordinate of the intermediate control point. | |
| 83 * [x2] The x-coordinate of the end point. | |
| 84 * [y2] The y-coordinate of the end point. | |
| 85 * Returns a list [:[x1, y1]:] representing the intermediate control point. | |
| 86 */ | |
| 87 static List<num> _normalizeQuadraticBezier( | |
| 88 num x1, num y1, num x2, num y2) { | |
| 89 // The end point must not lie on any axes. | |
| 90 assert(!GoogleMath.nearlyEquals(x2, 0) && !GoogleMath.nearlyEquals(y2, 0)); | |
| 91 return [x1 / x2, y1 / y2]; | |
| 92 } | |
| 93 | |
| 94 /** | |
| 95 * Converts a quadratic Bezier curve defined by the control points | |
| 96 * (x0, y0) = (0, 0), (x1, y1) = (x, y), and (x2, y2) = (1, 1) into an | |
| 97 * equivalent cubic Bezier curve with four control points. Note that the start | |
| 98 * and end points will be unchanged. | |
| 99 * [x] The x-coordinate of the intermediate control point. | |
| 100 * [y] The y-coordinate of the intermediate control point. | |
| 101 * Returns a list [:[x1, y1, x2, y2]:] containing the two | |
| 102 * intermediate points of the equivalent cubic Bezier curve. | |
| 103 */ | |
| 104 static List<num> _quadraticToCubic(num x, num y) { | |
| 105 // The intermediate control point must have coordinates within the | |
| 106 // interval [0,1]. | |
| 107 assert(x >= 0 && x <= 1 && y >= 0 && y <= 1); | |
| 108 num x1 = x * _TWO_THIRDS; | |
| 109 num y1 = y * _TWO_THIRDS; | |
| 110 num x2 = x1 + _ONE_THIRD; | |
| 111 num y2 = y1 + _ONE_THIRD; | |
| 112 return [x1, y1, x2, y2]; | |
| 113 } | |
| 114 } | |
| OLD | NEW |