1 /*
2  * Copyright (C) 2024 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 androidx.ink.geometry
18 
19 import androidx.annotation.RestrictTo
20 import androidx.ink.nativeloader.UsedByNative
21 import kotlin.math.cos
22 import kotlin.math.sin
23 
24 /**
25  * A mutable two-dimensional vector, i.e. an (x, y) coordinate pair. It can be used to represent
26  * either:
27  * 1) A two-dimensional offset, i.e. the difference between two points
28  * 2) A point in space, i.e. treating the vector as an offset from the origin
29  *
30  * This object is mutable and is not inherently thread-safe, so callers should apply their own
31  * synchronization logic or use this object from a single thread. See [ImmutableVec] for an
32  * immutable alternative.
33  */
34 public class MutableVec(
35     @set:UsedByNative override var x: Float,
36     @set:UsedByNative override var y: Float,
37 ) : Vec() {
38 
39     public constructor() : this(0F, 0F)
40 
41     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
asImmutablenull42     override fun asImmutable(): ImmutableVec = ImmutableVec(x, y)
43 
44     /** Fills this [MutableVec] with the same values contained in [input]. */
45     public fun populateFrom(input: Vec): MutableVec {
46         x = input.x
47         y = input.y
48         return this
49     }
50 
equalsnull51     override fun equals(other: Any?): Boolean =
52         other === this || (other is Vec && areEquivalent(this, other))
53 
54     // NOMUTANTS -- not testing exact hashCode values, just that equality implies same hashCode
55     override fun hashCode(): Int = hash(this)
56 
57     override fun toString(): String = "Mutable${string(this)}"
58 
59     public companion object {
60         @JvmStatic
61         public fun fromDirectionAndMagnitude(
62             @AngleRadiansFloat direction: Float,
63             magnitude: Float,
64         ): MutableVec {
65             return MutableVec(magnitude * cos(direction), magnitude * sin(direction))
66         }
67     }
68 }
69