Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eddc8dbe authored by George Mount's avatar George Mount
Browse files

Fix ArcMotion path creation in some quadrants.

Bug 27577177

When ArcMotion created paths in some quadrants, the control
points were placed in the wrong place, making a non-circular
arc instead of an arc of a circle.

Change-Id: Ie842524c09385038fb1f991b877b01ee5e740f20
parent dcbd7826
Loading
Loading
Loading
Loading
+19 −8
Original line number Diff line number Diff line
@@ -15,13 +15,13 @@
 */
package android.transition;

import com.android.internal.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Path;
import android.util.AttributeSet;

import com.android.internal.R;

/**
 * A PathMotion that generates a curved path along an arc on an imaginary circle containing
 * the two points. If the horizontal distance between the points is less than the vertical
@@ -207,7 +207,7 @@ public class ArcMotion extends PathMotion {
            ey = (startY + endY) / 2;
        } else {
            float deltaX = endX - startX;
            float deltaY = startY - endY; // Y is inverted compared to diagram above.
            float deltaY = endY - startY;
            // hypotenuse squared.
            float h2 = deltaX * deltaX + deltaY * deltaY;

@@ -219,24 +219,35 @@ public class ArcMotion extends PathMotion {
            float midDist2 = h2 * 0.25f;

            float minimumArcDist2 = 0;
            boolean isQuadrant1Or3 = (deltaX * deltaY) > 0;

            if (Math.abs(deltaX) < Math.abs(deltaY)) {
            if ((Math.abs(deltaX) < Math.abs(deltaY))) {
                // Similar triangles bfa and bde mean that (ab/fb = eb/bd)
                // Therefore, eb = ab * bd / fb
                // ab = hypotenuse
                // bd = hypotenuse/2
                // fb = deltaY
                float eDistY = h2 / (2 * deltaY);
                ey = endY + eDistY;
                if (isQuadrant1Or3) {
                    ey = startY + eDistY;
                    ex = startX;
                } else {
                    ey = endY - eDistY;
                    ex = endX;
                }

                minimumArcDist2 = midDist2 * mMinimumVerticalTangent
                        * mMinimumVerticalTangent;
            } else {
                // Same as above, but flip X & Y
                float eDistX = h2 / (2 * deltaX);
                ex = endX + eDistX;
                if (isQuadrant1Or3) {
                    ex = endX - eDistX;
                    ey = endY;
                } else {
                    ex = startX + eDistX;
                    ey = startY;
                }

                minimumArcDist2 = midDist2 * mMinimumHorizontalTangent
                        * mMinimumHorizontalTangent;