0.3.1-dev-11 #510

Merged
altavir merged 80 commits from dev into master 2023-04-05 18:46:36 +03:00
4 changed files with 143 additions and 80 deletions
Showing only changes of commit c342c5cd78 - Show all commits

View File

@ -18,45 +18,5 @@ public data class Circle2D(
public val radius: Double public val radius: Double
) )
public enum class DubinsRoutes {
RSR, RSL, LSR, LSL
}
public fun Circle2D.tangentsToCircle(other: Circle2D): Map<DubinsRoutes, LineSegment<DoubleVector2D>> {
val R1 = this.radius
val R2 = other.radius
val line = LineSegment(this.center, other.center)
val d = line.begin.distanceTo(line.end)
val angle1 = atan2(other.center.x - this.center.x, other.center.y - this.center.y)
var r: Double
var angle2: Double
val routes = mapOf(
DubinsRoutes.RSR to Pair(R1, R2),
DubinsRoutes.RSL to Pair(R1, -R2),
DubinsRoutes.LSR to Pair(-R1, R2),
DubinsRoutes.LSL to Pair(-R1, -R2))
val segments = mutableMapOf<DubinsRoutes, LineSegment<DoubleVector2D>>()
for ((route, r1r2) in routes) {
val r1 = r1r2.first
val r2 = r1r2.second
r = if (r1.sign == r2.sign) {
r1.absoluteValue - r2.absoluteValue
} else {
r1.absoluteValue + r2.absoluteValue
}
val L = (d * d - r * r).pow(0.5)
angle2 = if (r1.absoluteValue > r2.absoluteValue) {
angle1 + r1.sign * atan2(r.absoluteValue, L)
} else {
angle1 - r2.sign * atan2(r.absoluteValue, L)
}
val W = Euclidean2DSpace.vector(-cos(angle2), sin(angle2))
segments[route] = LineSegment(
Euclidean2DSpace.add(this.center, Euclidean2DSpace.scale(W, r1)),
Euclidean2DSpace.add(other.center, Euclidean2DSpace.scale(W, r2))
)
}
return segments
}
public val Circle2D.circumference: Double get() = radius * 2 * PI public val Circle2D.circumference: Double get() = radius * 2 * PI

View File

@ -3,43 +3,43 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.geometry //package space.kscience.kmath.geometry
//
import space.kscience.kmath.geometry.Euclidean2DSpace.equalLineSegments //import space.kscience.kmath.geometry.Euclidean2DSpace.equalLineSegments
import space.kscience.kmath.geometry.Euclidean2DSpace.vector //import space.kscience.kmath.geometry.Euclidean2DSpace.vector
import kotlin.test.Test //import kotlin.test.Test
import kotlin.test.assertEquals //import kotlin.test.assertEquals
import kotlin.test.assertTrue //import kotlin.test.assertTrue
//
class TangentTest { //class TangentTest {
@Test // @Test
fun tangent() { // fun tangent() {
val c1 = Circle2D(vector(0.0, 0.0), 1.0) // val c1 = Circle2D(vector(0.0, 0.0), 1.0)
val c2 = Circle2D(vector(4.0, 0.0), 1.0) // val c2 = Circle2D(vector(4.0, 0.0), 1.0)
val routes = arrayListOf<DubinsRoutes>( // val routes = arrayListOf<DubinsRoutes>(
DubinsRoutes.RSR, // DubinsRoutes.RSR,
DubinsRoutes.RSL, // DubinsRoutes.RSL,
DubinsRoutes.LSR, // DubinsRoutes.LSR,
DubinsRoutes.LSL // DubinsRoutes.LSL
) // )
val segments = arrayListOf<LineSegment<DoubleVector2D>>( // val segments = arrayListOf<LineSegment<DoubleVector2D>>(
LineSegment<DoubleVector2D>(begin = vector(0.0, 1.0), // LineSegment<DoubleVector2D>(begin = vector(0.0, 1.0),
end = vector(4.0, 1.0)), // end = vector(4.0, 1.0)),
LineSegment<DoubleVector2D>(begin = vector(0.5, 0.8660254), // LineSegment<DoubleVector2D>(begin = vector(0.5, 0.8660254),
end = vector(3.5, -0.8660254)), // end = vector(3.5, -0.8660254)),
LineSegment<DoubleVector2D>(begin = vector(0.5, -0.8660254), // LineSegment<DoubleVector2D>(begin = vector(0.5, -0.8660254),
end = vector(3.5, 0.8660254)), // end = vector(3.5, 0.8660254)),
LineSegment<DoubleVector2D>(begin = vector(0.0, -1.0), // LineSegment<DoubleVector2D>(begin = vector(0.0, -1.0),
end = vector(4.0, -1.0)) // end = vector(4.0, -1.0))
) // )
//
val tangentMap = c1.tangentsToCircle(c2) // val tangentMap = c1.tangentsToCircle(c2)
val tangentMapKeys = tangentMap.keys.toList() // val tangentMapKeys = tangentMap.keys.toList()
val tangentMapValues = tangentMap.values.toList() // val tangentMapValues = tangentMap.values.toList()
//
assertEquals(routes, tangentMapKeys) // assertEquals(routes, tangentMapKeys)
for (i in segments.indices) { // for (i in segments.indices) {
assertTrue(equalLineSegments(segments[i], tangentMapValues[i])) // assertTrue(equalLineSegments(segments[i], tangentMapValues[i]))
} // }
} // }
} //}

View File

@ -0,0 +1,55 @@
/*
* Copyright 2018-2023 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.trajectory
import space.kscience.kmath.geometry.Circle2D
import space.kscience.kmath.geometry.DoubleVector2D
import space.kscience.kmath.geometry.Euclidean2DSpace
import space.kscience.kmath.geometry.Euclidean2DSpace.distanceTo
import space.kscience.kmath.geometry.LineSegment
import kotlin.math.*
public enum class DubinsRoutes {
RSR, RSL, LSR, LSL
}
public fun Circle2D.tangentsToCircle(other: Circle2D): Map<DubinsRoutes, LineSegment<DoubleVector2D>> {
val R1 = this.radius
val R2 = other.radius
val line = LineSegment(this.center, other.center)
val d = line.begin.distanceTo(line.end)
val angle1 = atan2(other.center.x - this.center.x, other.center.y - this.center.y)
var r: Double
var angle2: Double
val routes = mapOf(
DubinsRoutes.RSR to Pair(R1, R2),
DubinsRoutes.RSL to Pair(R1, -R2),
DubinsRoutes.LSR to Pair(-R1, R2),
DubinsRoutes.LSL to Pair(-R1, -R2)
)
val segments = mutableMapOf<DubinsRoutes, LineSegment<DoubleVector2D>>()
for ((route, r1r2) in routes) {
val r1 = r1r2.first
val r2 = r1r2.second
r = if (r1.sign == r2.sign) {
r1.absoluteValue - r2.absoluteValue
} else {
r1.absoluteValue + r2.absoluteValue
}
val L = (d * d - r * r).pow(0.5)
angle2 = if (r1.absoluteValue > r2.absoluteValue) {
angle1 + r1.sign * atan2(r.absoluteValue, L)
} else {
angle1 - r2.sign * atan2(r.absoluteValue, L)
}
val W = Euclidean2DSpace.vector(-cos(angle2), sin(angle2))
segments[route] = LineSegment(
Euclidean2DSpace.add(this.center, Euclidean2DSpace.scale(W, r1)),
Euclidean2DSpace.add(other.center, Euclidean2DSpace.scale(W, r2))
)
}
return segments
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2018-2023 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.trajectory
import space.kscience.kmath.geometry.Circle2D
import space.kscience.kmath.geometry.DoubleVector2D
import space.kscience.kmath.geometry.Euclidean2DSpace.equalLineSegments
import space.kscience.kmath.geometry.Euclidean2DSpace.vector
import space.kscience.kmath.geometry.LineSegment
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class TangentTest {
@Test
fun tangent() {
val c1 = Circle2D(vector(0.0, 0.0), 1.0)
val c2 = Circle2D(vector(4.0, 0.0), 1.0)
val routes = arrayListOf<DubinsRoutes>(
DubinsRoutes.RSR,
DubinsRoutes.RSL,
DubinsRoutes.LSR,
DubinsRoutes.LSL
)
val segments = arrayListOf<LineSegment<DoubleVector2D>>(
LineSegment<DoubleVector2D>(begin = vector(0.0, 1.0),
end = vector(4.0, 1.0)),
LineSegment<DoubleVector2D>(begin = vector(0.5, 0.8660254),
end = vector(3.5, -0.8660254)),
LineSegment<DoubleVector2D>(begin = vector(0.5, -0.8660254),
end = vector(3.5, 0.8660254)),
LineSegment<DoubleVector2D>(begin = vector(0.0, -1.0),
end = vector(4.0, -1.0))
)
val tangentMap = c1.tangentsToCircle(c2)
val tangentMapKeys = tangentMap.keys.toList()
val tangentMapValues = tangentMap.values.toList()
assertEquals(routes, tangentMapKeys)
for (i in segments.indices) {
assertTrue(equalLineSegments(segments[i], tangentMapValues[i]))
}
}
}