1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.cts.view;
18 
19 /**
20  * Represents coordinates where (x, y) = (0, 0) represents the top-left most point.
21  */
22 public class Position {
23     private final float mX;
24     private final float mY;
25 
Position(float x, float y)26     public Position(float x, float y) {
27         mX = x;
28         mY = y;
29     }
30 
getX()31     public float getX() {
32         return mX;
33     }
34 
getY()35     public float getY() {
36         return mY;
37     }
38 
39     /**
40      * @return The vector dot product between {@code this} and another {@link Position}.
41      */
dotProduct(Position other)42     public double dotProduct(Position other) {
43         return (mX * other.mX) + (mY * other.mY);
44     }
45 
46     /**
47      * @return The euclidean distance between {@code this} and the other {@link Position}.
48      */
distanceTo(Position other)49     public double distanceTo(Position other) {
50         return Math.sqrt(Math.pow((mX - other.mX), 2) + Math.pow((mY - other.mY), 2));
51     }
52 
53     /**
54      * Returns the closest double approximation to the smallest angle swept out by an arc from
55      * {@code this} to the other {@link Position}, given the origin of the arc.
56      *
57      * @param origin The {@link Position} to use as the origin of the arc.
58      * @return The angle swept out, in radians within the range {@code [-pi..pi]}. A negative double
59      * indicates that the smallest angle swept out is in the clockwise direction, and a positive
60      * double indicates otherwise.
61      */
arcAngleTo(Position other, Position origin)62     public double arcAngleTo(Position other, Position origin) {
63         // Compute the angle of the polar representation of this and other w.r.t. the arc origin.
64         double originToThisAngle = Math.atan2(origin.mY - mY, mX - origin.mX);
65         double originToOtherAngle = Math.atan2(origin.mY - other.mY, other.mX - origin.mX);
66         double difference = originToOtherAngle - originToThisAngle;
67 
68         // If the difference exceeds PI or is less then -PI, then we should compensate to
69         // bring the value back into the [-pi..pi] range by removing/adding a full revolution.
70         if (difference < -Math.PI) {
71             difference += 2 * Math.PI;
72         } else if (difference > Math.PI){
73             difference -= 2 * Math.PI;
74         }
75         return difference;
76     }
77 
78     /**
79      * Returns the closest double approximation to the angle to the other {@link Position}.
80      *
81      * @return The angle swept out, in radians within the range {@code [-pi..pi]}.
82      */
angleTo(Position other)83     public double angleTo(Position other) {
84         return Math.atan2(other.mY - mY, other.mX - mX);
85     }
86 
87     /**
88      * Defines equality between pairs of {@link Position}s.
89      * <p>
90      * Two Position instances are defined to be equal if their x and y coordinates are equal.
91      */
92     @Override
equals(Object o)93     public boolean equals(Object o) {
94         if (!(o instanceof Position)) {
95             return false;
96         }
97         Position other = (Position) o;
98         return (Float.compare(other.mX, mX) == 0) && (Float.compare(other.mY, mY) == 0);
99     }
100 
101     @Override
hashCode()102     public int hashCode() {
103         int result = 17;
104         result = 31 * result + Float.floatToIntBits(mX);
105         result = 31 * result + Float.floatToIntBits(mY);
106         return result;
107     }
108 }
109