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

Commit a28de579 authored by Blazej Magnowski's avatar Blazej Magnowski
Browse files

Improved angles variance and added the angles percentage evaluation

Change-Id: I312529ea89707d27a7ef1a5ffd6d94427eaf6e8f
parent 91be2f88
Loading
Loading
Loading
Loading
+56 −12
Original line number Diff line number Diff line
@@ -32,17 +32,26 @@ import java.util.List;
 * previously calculated angle. Then it calculates the variance of the differences from a stroke.
 * To the differences there is artificially added value 0.0 and the difference between the first
 * angle and PI (angles are in radians). It helps with strokes which have few points and punishes
 * more strokes which are not smooth. This classifier also tries to split the stroke into two parts
 * int the place in which the biggest angle is. It calculates the angle variance of the two parts
 * and sums them up. The reason the classifier is doing this, is because some human swipes at the
 * beginning go for a moment in one direction and then they rapidly change direction for the rest
 * of the stroke (like a tick). The final result is the minimum of angle variance of the whole
 * stroke and the sum of angle variances of the two parts split up.
 * more strokes which are not smooth.
 *
 * This classifier also tries to split the stroke into two parts in the place in which the biggest
 * angle is. It calculates the angle variance of the two parts and sums them up. The reason the
 * classifier is doing this, is because some human swipes at the beginning go for a moment in one
 * direction and then they rapidly change direction for the rest of the stroke (like a tick). The
 * final result is the minimum of angle variance of the whole stroke and the sum of angle variances
 * of the two parts split up. The classifier tries the tick option only if the first part is
 * shorter than the second part.
 *
 * Additionally, the classifier classifies the angles as left angles (those angles which value is
 * in [0.0, PI - ANGLE_DEVIATION) interval), straight angles
 * ([PI - ANGLE_DEVIATION, PI + ANGLE_DEVIATION] interval) and right angles
 * ((PI + ANGLE_DEVIATION, 2 * PI) interval) and then calculates the percentage of angles which are
 * in the same direction (straight angles can be left angels or right angles)
 */
public class AnglesVarianceClassifier extends StrokeClassifier {
public class AnglesClassifier extends StrokeClassifier {
    private HashMap<Stroke, Data> mStrokeMap = new HashMap<>();

    public AnglesVarianceClassifier(ClassifierData classifierData) {
    public AnglesClassifier(ClassifierData classifierData) {
        mClassifierData = classifierData;
    }

@@ -66,10 +75,14 @@ public class AnglesVarianceClassifier extends StrokeClassifier {

    @Override
    public float getFalseTouchEvaluation(int type, Stroke stroke) {
        return AnglesVarianceEvaluator.evaluate(mStrokeMap.get(stroke).getAnglesVariance());
        Data data = mStrokeMap.get(stroke);
        return AnglesVarianceEvaluator.evaluate(data.getAnglesVariance())
                + AnglesPercentageEvaluator.evaluate(data.getAnglesPercentage());
    }

    private static class Data {
        private final float ANGLE_DEVIATION = (float) Math.PI / 20.0f;

        private List<Point> mLastThreePoints = new ArrayList<>();
        private float mFirstAngleVariance;
        private float mPreviousAngle;
@@ -80,6 +93,12 @@ public class AnglesVarianceClassifier extends StrokeClassifier {
        private float mSecondSum;
        private float mCount;
        private float mSecondCount;
        private float mFirstLength;
        private float mLength;
        private float mAnglesCount;
        private float mLeftAngles;
        private float mRightAngles;
        private float mStraightAngles;

        public Data() {
            mFirstAngleVariance = 0.0f;
@@ -88,6 +107,8 @@ public class AnglesVarianceClassifier extends StrokeClassifier {
            mSumSquares = mSecondSumSquares = 0.0f;
            mSum = mSecondSum = 0.0f;
            mCount = mSecondCount = 1.0f;
            mLength = mFirstLength = 0.0f;
            mAnglesCount = mLeftAngles = mRightAngles = mStraightAngles = 0.0f;
        }

        public void addPoint(Point point) {
@@ -95,6 +116,9 @@ public class AnglesVarianceClassifier extends StrokeClassifier {
            // Repetitions are being ignored so that proper angles are calculated.
            if (mLastThreePoints.isEmpty()
                    || !mLastThreePoints.get(mLastThreePoints.size() - 1).equals(point)) {
                if (!mLastThreePoints.isEmpty()) {
                    mLength += mLastThreePoints.get(mLastThreePoints.size() - 1).dist(point);
                }
                mLastThreePoints.add(point);
                if (mLastThreePoints.size() == 4) {
                    mLastThreePoints.remove(0);
@@ -102,6 +126,15 @@ public class AnglesVarianceClassifier extends StrokeClassifier {
                    float angle = mLastThreePoints.get(1).getAngle(mLastThreePoints.get(0),
                            mLastThreePoints.get(2));

                    mAnglesCount++;
                    if (angle < Math.PI - ANGLE_DEVIATION) {
                        mLeftAngles++;
                    } else if (angle <= Math.PI + ANGLE_DEVIATION) {
                        mStraightAngles++;
                    } else {
                        mRightAngles++;
                    }

                    float difference = angle - mPreviousAngle;

                    // If this is the biggest angle of the stroke so then we save the value of
@@ -109,6 +142,7 @@ public class AnglesVarianceClassifier extends StrokeClassifier {
                    // variance of the second part.
                    if (mBiggestAngle < angle) {
                        mBiggestAngle = angle;
                        mFirstLength = mLength;
                        mFirstAngleVariance = getAnglesVariance(mSumSquares, mSum, mCount);
                        mSecondSumSquares = 0.0f;
                        mSecondSum = 0.0f;
@@ -132,9 +166,19 @@ public class AnglesVarianceClassifier extends StrokeClassifier {
        }

        public float getAnglesVariance() {
            return Math.min(getAnglesVariance(mSumSquares, mSum, mCount),
                    mFirstAngleVariance + getAnglesVariance(mSecondSumSquares, mSecondSum,
                            mSecondCount));
            float anglesVariance = getAnglesVariance(mSumSquares, mSum, mCount);
            if (mFirstLength < mLength / 2f) {
                anglesVariance = Math.min(anglesVariance, mFirstAngleVariance
                        + getAnglesVariance(mSecondSumSquares, mSecondSum, mSecondCount));
            }
            return anglesVariance;
        }

        public float getAnglesPercentage() {
            if (mAnglesCount == 0.0f) {
                return 1.0f;
            }
            return (Math.max(mLeftAngles, mRightAngles) + mStraightAngles) / mAnglesCount;
        }
    }
}
 No newline at end of file
+27 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.systemui.classifier;

public class AnglesPercentageEvaluator {
    public static float evaluate(float value) {
        float evaluation = 0.0f;
        if (value < 1.00) evaluation++;
        if (value < 0.95) evaluation++;
        if (value < 0.90) evaluation++;
        return evaluation;
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -69,13 +69,13 @@ public class HumanInteractionClassifier extends Classifier {
        mClassifierData = new ClassifierData(mDpi);
        mHistoryEvaluator = new HistoryEvaluator();

        mStrokeClassifiers.add(new AnglesVarianceClassifier(mClassifierData));
        mStrokeClassifiers.add(new AnglesClassifier(mClassifierData));
        mStrokeClassifiers.add(new SpeedClassifier(mClassifierData));
        mStrokeClassifiers.add(new DurationCountClassifier(mClassifierData));
        mStrokeClassifiers.add(new EndPointRatioClassifier(mClassifierData));
        mStrokeClassifiers.add(new EndPointLengthClassifier(mClassifierData));
        mStrokeClassifiers.add(new AccelerationClassifier(mClassifierData));
        mStrokeClassifiers.add(new SpeedVarianceClassifier(mClassifierData));
        mStrokeClassifiers.add(new SpeedAnglesClassifier(mClassifierData));
        mStrokeClassifiers.add(new LengthCountClassifier(mClassifierData));

        mGestureClassifiers.add(new PointerCountClassifier(mClassifierData));
+7 −3
Original line number Diff line number Diff line
@@ -17,8 +17,11 @@
package com.android.systemui.classifier;

/**
 * A classifier which looks at the ratio between the duration of the stroke and its number of
 * points.
 * A classifier which looks at the ratio between the length of the stroke and its number of
 * points. The number of points is subtracted by 2 because the UP event comes in with some delay
 * and it should not influence the ratio and also strokes which are long and have a small number
 * of points are punished more (these kind of strokes are usually bad ones and they tend to score
 * well in other classifiers).
 */
public class LengthCountClassifier extends StrokeClassifier {
    public LengthCountClassifier(ClassifierData classifierData) {
@@ -26,6 +29,7 @@ public class LengthCountClassifier extends StrokeClassifier {

    @Override
    public float getFalseTouchEvaluation(int type, Stroke stroke) {
        return LengthCountEvaluator.evaluate(stroke.getTotalLength() / stroke.getCount());
        return LengthCountEvaluator.evaluate(stroke.getTotalLength()
                / Math.max(1.0f, stroke.getCount() - 2));
    }
}
 No newline at end of file
+2 −1
Original line number Diff line number Diff line
@@ -23,10 +23,11 @@ package com.android.systemui.classifier;
public class LengthCountEvaluator {
    public static float evaluate(float value) {
        float evaluation = 0.0f;
        if (value < 0.07) evaluation++;
        if (value < 0.09) evaluation++;
        if (value < 0.05) evaluation++;
        if (value < 0.02) evaluation++;
        if (value > 0.6) evaluation++;
        if (value > 0.9) evaluation++;
        if (value > 1.2) evaluation++;
        return evaluation;
    }
Loading