Add toString to curves and correct rounding normalization for angles

This commit is contained in:
Alexander Nozik 2022-09-16 12:59:58 +03:00
parent 2b01b8e316
commit 6decba8e83
No known key found for this signature in database
GPG Key ID: F7FCF2DD25C71357
5 changed files with 22 additions and 16 deletions

View File

@ -10,7 +10,7 @@ val ktorVersion by extra("2.0.3")
allprojects {
group = "center.sciprog"
version = "0.1.0-dev-6"
version = "0.1.0-dev-7"
}
ksciencePublish{

View File

@ -7,6 +7,7 @@ package center.sciprog.maps.coordinates
import kotlin.jvm.JvmInline
import kotlin.math.PI
import kotlin.math.floor
// Taken from KMath dev version, to be used directly in the future
@ -82,11 +83,9 @@ public value class Degrees(public val value: Double) : Angle {
public val Number.degrees: Degrees get() = Degrees(toDouble())
/**
* Normalized angle to (0, 2PI) for radians or (0, 360) for degrees.
* Normalized angle 2 PI range symmetric around [center]. By default, uses (0, 2PI) range.
*/
public fun Angle.normalized(): Angle = when (this) {
is Degrees -> value.mod(360.0).degrees
is Radians -> value.mod(PI * 2).radians
}
public fun Angle.normalized(center: Angle = Angle.pi): Angle =
this - Angle.piTimes2 * floor((radians.value + PI - center.radians.value) / PI/2)
public fun abs(angle: Angle): Angle = if (angle < Angle.zero) -angle else angle

View File

@ -1,7 +1,5 @@
package center.sciprog.maps.coordinates
import kotlin.math.PI
/**
* Geodetic coordinated
*/
@ -9,10 +7,10 @@ public class GeodeticMapCoordinates(
public val latitude: Angle,
longitude: Angle,
) {
public val longitude: Radians = longitude.radians.value.rem(PI / 2).radians
public val longitude: Angle = longitude.normalized(Angle.zero)
init {
require(latitude.radians.value in (-PI / 2)..(PI / 2)) { "Latitude $latitude is not in (-PI/2)..(PI/2)" }
require(latitude in (-Angle.piDiv2)..(Angle.piDiv2)) { "Latitude $latitude is not in (-PI/2)..(PI/2)" }
}
override fun equals(other: Any?): Boolean {

View File

@ -10,11 +10,15 @@ import kotlin.math.*
* @param forward coordinate of a start point with forward direction
* @param backward coordinate of an end point with backward direction
*/
public class GmcCurve internal constructor(
public class GmcCurve(
public val forward: GmcPose,
public val backward: GmcPose,
public val distance: Distance,
)
){
override fun toString(): String {
return "GmcCurve(from: ${forward.coordinates}, to: ${backward.coordinates})"
}
}
public fun GmcCurve.reversed(): GmcCurve = GmcCurve(backward, forward, distance)
@ -222,6 +226,8 @@ public fun GeoEllipsoid.curveBetween(start: Gmc, end: Gmc, precision: Double = 1
val a = equatorRadius
val b = polarRadius
if(start == end) error("Can't compute a curve because start and end coincide at $start")
// get parameters as radians
val phi1 = start.latitude
val lambda1 = start.longitude
@ -232,7 +238,7 @@ public fun GeoEllipsoid.curveBetween(start: Gmc, end: Gmc, precision: Double = 1
val a2 = a.kilometers * a.kilometers
val b2 = b.kilometers * b.kilometers
val a2b2b2 = (a2 - b2) / b2
val omega: Radians = lambda2 - lambda1
val omega: Angle = lambda2 - lambda1
val tanphi1: Double = tan(phi1)
val tanU1 = (1.0 - f) * tanphi1
val U1: Double = atan(tanU1)
@ -256,7 +262,7 @@ public fun GeoEllipsoid.curveBetween(start: Gmc, end: Gmc, precision: Double = 1
var sigma = 0.0
var deltasigma = 0.0
var lambda0: Radians
var lambda0: Angle
var converged = false
for (i in 0..19) {
lambda0 = lambda
@ -326,8 +332,7 @@ public fun GeoEllipsoid.curveBetween(start: Gmc, end: Gmc, precision: Double = 1
alpha1 = 0.0.radians
alpha2 = pi.radians
} else {
alpha1 = Double.NaN.radians
alpha2 = Double.NaN.radians
error("Start and end point coinside.")
}
} else {
// eq. 20

View File

@ -8,5 +8,9 @@ class AngleTest {
fun normalization(){
assertEquals(30.degrees, 390.degrees.normalized())
assertEquals(30.degrees, (-330).degrees.normalized())
assertEquals(200.degrees, 200.degrees.normalized())
assertEquals(30.degrees, 390.degrees.normalized(Angle.zero))
assertEquals(30.degrees, (-330).degrees.normalized(Angle.zero))
assertEquals((-160).degrees, 200.degrees.normalized(Angle.zero))
}
}