Skip to content

Commit 1156731

Browse files
committed
refactor(SphericalUtil): Improve readability of computeHeading
This commit refactors the `SphericalUtil` object to improve code clarity and leverage modern Kotlin features. Key changes include: - Introduced private `toRadians()` and `toDegrees()` extension functions for `Double` to replace calls to `Math.toRadians()` and `Math.toDegrees()`. - Converted several methods to more concise single-expression functions. - Improved the readability of the `computeHeading` function by using more descriptive variable names and clearer logic.
1 parent 177bab9 commit 1156731

File tree

1 file changed

+27
-32
lines changed

1 file changed

+27
-32
lines changed

library/src/main/java/com/google/maps/android/SphericalUtil.kt

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ import kotlin.math.sin
3232
import kotlin.math.sqrt
3333
import kotlin.math.tan
3434

35+
private fun Double.toRadians() = this * (PI / 180.0)
36+
private fun Double.toDegrees() = this * (180.0 / PI)
37+
3538
object SphericalUtil {
3639
/**
3740
* Returns the heading from one LatLng to another LatLng. Headings are
@@ -42,16 +45,17 @@ object SphericalUtil {
4245
@JvmStatic
4346
fun computeHeading(from: LatLng, to: LatLng): Double {
4447
// http://williams.best.vwh.net/avform.htm#Crs
45-
val fromLat = Math.toRadians(from.latitude)
46-
val fromLng = Math.toRadians(from.longitude)
47-
val toLat = Math.toRadians(to.latitude)
48-
val toLng = Math.toRadians(to.longitude)
49-
val dLng = toLng - fromLng
50-
val heading = atan2(
51-
sin(dLng) * cos(toLat),
52-
cos(fromLat) * sin(toLat) - sin(fromLat) * cos(toLat) * cos(dLng)
53-
)
54-
return wrap(Math.toDegrees(heading), -180.0, 180.0)
48+
val fromLatRad = from.latitude.toRadians()
49+
val toLatRad = to.latitude.toRadians()
50+
val deltaLngRad = (to.longitude - from.longitude).toRadians()
51+
52+
// Breaking the formula down into Y and X components for atan2().
53+
val y = sin(deltaLngRad) * cos(toLatRad)
54+
val x = cos(fromLatRad) * sin(toLatRad) - sin(fromLatRad) * cos(toLatRad) * cos(deltaLngRad)
55+
56+
val headingRad = atan2(y, x)
57+
58+
return wrap(headingRad.toDegrees(), -180.0, 180.0)
5559
}
5660

5761
/**
@@ -176,29 +180,24 @@ object SphericalUtil {
176180
/**
177181
* Returns distance on the unit sphere; the arguments are in radians.
178182
*/
179-
private fun distanceRadians(lat1: Double, lng1: Double, lat2: Double, lng2: Double): Double {
180-
return arcHav(havDistance(lat1, lat2, lng1 - lng2))
181-
}
183+
private fun distanceRadians(lat1: Double, lng1: Double, lat2: Double, lng2: Double) =
184+
arcHav(havDistance(lat1, lat2, lng1 - lng2))
182185

183186
/**
184187
* Returns the angle between two LatLngs, in radians. This is the same as the distance
185188
* on the unit sphere.
186189
*/
187190
@JvmStatic
188-
fun computeAngleBetween(from: LatLng, to: LatLng): Double {
189-
return distanceRadians(
190-
Math.toRadians(from.latitude), Math.toRadians(from.longitude),
191-
Math.toRadians(to.latitude), Math.toRadians(to.longitude)
192-
)
193-
}
191+
fun computeAngleBetween(from: LatLng, to: LatLng) = distanceRadians(
192+
from.latitude.toRadians(), from.longitude.toRadians(),
193+
to.latitude.toRadians(), to.longitude.toRadians()
194+
)
194195

195196
/**
196197
* Returns the distance between two LatLngs, in meters.
197198
*/
198199
@JvmStatic
199-
fun computeDistanceBetween(from: LatLng, to: LatLng): Double {
200-
return computeAngleBetween(from, to) * EARTH_RADIUS
201-
}
200+
fun computeDistanceBetween(from: LatLng, to: LatLng) = computeAngleBetween(from, to) * EARTH_RADIUS
202201

203202
/**
204203
* Returns the length of the given path, in meters, on Earth.
@@ -230,9 +229,7 @@ object SphericalUtil {
230229
* @return The path's area in square meters.
231230
*/
232231
@JvmStatic
233-
fun computeArea(path: Polygon): Double {
234-
return abs(computeSignedArea(path))
235-
}
232+
fun computeArea(path: Polygon) = abs(computeSignedArea(path))
236233

237234
/**
238235
* Returns the signed area of a closed path on Earth. The sign of the area may be used to
@@ -243,9 +240,7 @@ object SphericalUtil {
243240
* @return The loop's area in square meters.
244241
*/
245242
@JvmStatic
246-
fun computeSignedArea(path: Polygon): Double {
247-
return computeSignedArea(path, EARTH_RADIUS)
248-
}
243+
fun computeSignedArea(path: Polygon) = computeSignedArea(path, EARTH_RADIUS)
249244

250245
/**
251246
* Returns the signed area of a closed path on a sphere of given radius.
@@ -260,13 +255,13 @@ object SphericalUtil {
260255
}
261256
var total = 0.0
262257
val prev = path[size - 1]
263-
var prevTanLat = tan((PI / 2 - Math.toRadians(prev.latitude)) / 2)
264-
var prevLng = Math.toRadians(prev.longitude)
258+
var prevTanLat = tan((PI / 2 - prev.latitude.toRadians()) / 2)
259+
var prevLng = prev.longitude.toRadians()
265260
// For each edge, accumulate the signed area of the triangle formed by the North Pole
266261
// and that edge ("polar triangle").
267262
for (point in path) {
268-
val tanLat = tan((PI / 2 - Math.toRadians(point.latitude)) / 2)
269-
val lng = Math.toRadians(point.longitude)
263+
val tanLat = tan((PI / 2 - point.latitude.toRadians()) / 2)
264+
val lng = point.longitude.toRadians()
270265
total += polarTriangleArea(tanLat, lng, prevTanLat, prevLng)
271266
prevTanLat = tanLat
272267
prevLng = lng

0 commit comments

Comments
 (0)