Skip to content

Commit 0839166

Browse files
committed
refactor(geometry): Port Point and Bounds classes to Kotlin
This commit modernizes the `Point` and `Bounds` classes by converting them from Java to idiomatic Kotlin. This change improves code conciseness, readability, and null safety. Key changes include: - The `Point` and `Bounds` classes are now written in Kotlin. - `@JvmField` annotations are used on properties to maintain binary compatibility for Java consumers. - New unit tests, `PointTest.kt` and `BoundsTest.kt`, have been added to ensure the correctness of the ported classes.
1 parent ca97b01 commit 0839166

File tree

4 files changed

+196
-50
lines changed

4 files changed

+196
-50
lines changed
Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013 Google Inc.
2+
* Copyright 2025 Google Inc.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -14,48 +14,40 @@
1414
* limitations under the License.
1515
*/
1616

17-
package com.google.maps.android.geometry;
17+
package com.google.maps.android.geometry
1818

1919
/**
2020
* Represents an area in the cartesian plane.
2121
*/
22-
public class Bounds {
23-
public final double minX;
24-
public final double minY;
25-
26-
public final double maxX;
27-
public final double maxY;
28-
29-
public final double midX;
30-
public final double midY;
31-
32-
public Bounds(double minX, double maxX, double minY, double maxY) {
33-
this.minX = minX;
34-
this.minY = minY;
35-
this.maxX = maxX;
36-
this.maxY = maxY;
37-
38-
midX = (minX + maxX) / 2;
39-
midY = (minY + maxY) / 2;
40-
}
41-
42-
public boolean contains(double x, double y) {
43-
return minX <= x && x <= maxX && minY <= y && y <= maxY;
22+
class Bounds(
23+
@JvmField val minX: Double,
24+
@JvmField val maxX: Double,
25+
@JvmField val minY: Double,
26+
@JvmField val maxY: Double
27+
) {
28+
@JvmField
29+
val midX: Double = (minX + maxX) / 2
30+
31+
@JvmField
32+
val midY: Double = (minY + maxY) / 2
33+
34+
fun contains(x: Double, y: Double): Boolean {
35+
return minX <= x && x <= maxX && minY <= y && y <= maxY
4436
}
4537

46-
public boolean contains(Point point) {
47-
return contains(point.x, point.y);
38+
fun contains(point: Point): Boolean {
39+
return contains(point.x, point.y)
4840
}
4941

50-
public boolean intersects(double minX, double maxX, double minY, double maxY) {
51-
return minX < this.maxX && this.minX < maxX && minY < this.maxY && this.minY < maxY;
42+
fun intersects(minX: Double, maxX: Double, minY: Double, maxY: Double): Boolean {
43+
return minX < this.maxX && this.minX < maxX && minY < this.maxY && this.minY < maxY
5244
}
5345

54-
public boolean intersects(Bounds bounds) {
55-
return intersects(bounds.minX, bounds.maxX, bounds.minY, bounds.maxY);
46+
fun intersects(bounds: Bounds): Boolean {
47+
return intersects(bounds.minX, bounds.maxX, bounds.minY, bounds.maxY)
5648
}
5749

58-
public boolean contains(Bounds bounds) {
59-
return bounds.minX >= minX && bounds.maxX <= maxX && bounds.minY >= minY && bounds.maxY <= maxY;
50+
fun contains(bounds: Bounds): Boolean {
51+
return bounds.minX >= minX && bounds.maxX <= maxX && bounds.minY >= minY && bounds.maxY <= maxY
6052
}
61-
}
53+
}
Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 Google Inc.
2+
* Copyright 2025 Google Inc.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -14,25 +14,32 @@
1414
* limitations under the License.
1515
*/
1616

17-
package com.google.maps.android.geometry;
17+
package com.google.maps.android.geometry
1818

19-
import androidx.annotation.NonNull;
19+
open class Point(@JvmField val x: Double, @JvmField val y: Double) {
20+
override fun toString(): String {
21+
return "Point(x=$x, y=$y)"
22+
}
23+
24+
override fun equals(other: Any?): Boolean {
25+
if (this === other) return true
26+
if (javaClass != other?.javaClass) return false
27+
28+
other as Point
2029

21-
public class Point {
22-
public final double x;
23-
public final double y;
30+
if (x != other.x) return false
31+
if (y != other.y) return false
32+
33+
return true
34+
}
2435

25-
public Point(double x, double y) {
26-
this.x = x;
27-
this.y = y;
36+
override fun hashCode(): Int {
37+
var result = x.hashCode()
38+
result = 31 * result + y.hashCode()
39+
return result
2840
}
2941

30-
@NonNull
31-
@Override
32-
public String toString() {
33-
return "Point{" +
34-
"x=" + x +
35-
", y=" + y +
36-
'}';
42+
fun copy(x: Double = this.x, y: Double = this.y): Point {
43+
return Point(x, y)
3744
}
38-
}
45+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2025 Google Inc.
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.google.maps.android.geometry
18+
19+
import org.junit.Assert.assertEquals
20+
import org.junit.Assert.assertFalse
21+
import org.junit.Assert.assertTrue
22+
import org.junit.Test
23+
24+
class BoundsTest {
25+
26+
@Test
27+
fun testInitialization() {
28+
val bounds = Bounds(0.0, 10.0, 0.0, 20.0)
29+
assertEquals(0.0, bounds.minX, 0.0)
30+
assertEquals(10.0, bounds.maxX, 0.0)
31+
assertEquals(0.0, bounds.minY, 0.0)
32+
assertEquals(20.0, bounds.maxY, 0.0)
33+
assertEquals(5.0, bounds.midX, 0.0)
34+
assertEquals(10.0, bounds.midY, 0.0)
35+
}
36+
37+
@Test
38+
fun testContainsPoint() {
39+
val bounds = Bounds(0.0, 10.0, 0.0, 10.0)
40+
assertTrue(bounds.contains(Point(5.0, 5.0)))
41+
assertTrue(bounds.contains(Point(0.0, 0.0)))
42+
assertTrue(bounds.contains(Point(10.0, 10.0)))
43+
assertFalse(bounds.contains(Point(11.0, 5.0)))
44+
assertFalse(bounds.contains(Point(5.0, 11.0)))
45+
}
46+
47+
@Test
48+
fun testContainsCoordinates() {
49+
val bounds = Bounds(0.0, 10.0, 0.0, 10.0)
50+
assertTrue(bounds.contains(5.0, 5.0))
51+
assertTrue(bounds.contains(0.0, 0.0))
52+
assertTrue(bounds.contains(10.0, 10.0))
53+
assertFalse(bounds.contains(11.0, 5.0))
54+
assertFalse(bounds.contains(5.0, 11.0))
55+
}
56+
57+
@Test
58+
fun testIntersectsBounds() {
59+
val bounds1 = Bounds(0.0, 10.0, 0.0, 10.0)
60+
val bounds2 = Bounds(5.0, 15.0, 5.0, 15.0)
61+
val bounds3 = Bounds(11.0, 20.0, 11.0, 20.0)
62+
val bounds4 = Bounds(0.0, 10.0, 11.0, 20.0)
63+
64+
assertTrue(bounds1.intersects(bounds2))
65+
assertFalse(bounds1.intersects(bounds3))
66+
assertFalse(bounds1.intersects(bounds4))
67+
}
68+
69+
@Test
70+
fun testIntersectsCoordinates() {
71+
val bounds = Bounds(0.0, 10.0, 0.0, 10.0)
72+
assertTrue(bounds.intersects(5.0, 15.0, 5.0, 15.0))
73+
assertFalse(bounds.intersects(11.0, 20.0, 11.0, 20.0))
74+
}
75+
76+
@Test
77+
fun testContainsBounds() {
78+
val bounds1 = Bounds(0.0, 10.0, 0.0, 10.0)
79+
val bounds2 = Bounds(2.0, 8.0, 2.0, 8.0)
80+
val bounds3 = Bounds(5.0, 15.0, 5.0, 15.0)
81+
82+
assertTrue(bounds1.contains(bounds2))
83+
assertFalse(bounds1.contains(bounds3))
84+
}
85+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2025 Google Inc.
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.google.maps.android.geometry
18+
19+
import org.junit.Assert.assertEquals
20+
import org.junit.Assert.assertNotEquals
21+
import org.junit.Test
22+
23+
class PointTest {
24+
25+
@Test
26+
fun testInitialization() {
27+
val point = Point(1.0, 2.0)
28+
assertEquals(1.0, point.x, 0.0)
29+
assertEquals(2.0, point.y, 0.0)
30+
}
31+
32+
@Test
33+
fun testToString() {
34+
val point = Point(1.0, 2.0)
35+
assertEquals("Point(x=1.0, y=2.0)", point.toString())
36+
}
37+
38+
@Test
39+
fun testEqualsAndHashCode() {
40+
val point1 = Point(1.0, 2.0)
41+
val point2 = Point(1.0, 2.0)
42+
val point3 = Point(2.0, 1.0)
43+
44+
assertEquals(point1, point2)
45+
assertEquals(point1.hashCode(), point2.hashCode())
46+
47+
assertNotEquals(point1, point3)
48+
assertNotEquals(point1.hashCode(), point3.hashCode())
49+
}
50+
51+
@Test
52+
fun testCopy() {
53+
val original = Point(1.0, 2.0)
54+
val copy = original.copy()
55+
val modifiedCopy = original.copy(y = 3.0)
56+
57+
assertEquals(original, copy)
58+
assertNotEquals(original, modifiedCopy)
59+
assertEquals(1.0, modifiedCopy.x, 0.0)
60+
assertEquals(3.0, modifiedCopy.y, 0.0)
61+
}
62+
}

0 commit comments

Comments
 (0)