refactor lines and segments

This commit is contained in:
Alexander Nozik 2023-04-04 19:33:43 +03:00
parent 025cb58060
commit a0e2ef1afc
4 changed files with 32 additions and 13 deletions

View File

@ -5,15 +5,23 @@
package space.kscience.kmath.geometry package space.kscience.kmath.geometry
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import space.kscience.kmath.operations.DoubleField.pow
/** /**
* A line formed by [base] vector of start and a [direction] vector. Direction vector is not necessarily normalized, * A line formed by [start] vector of start and a [direction] vector. Direction vector is not necessarily normalized,
* but its length does not affect line properties * but its length does not affect line properties
*/ */
public interface Line<out V : Vector> {
public val start: V
public val direction: V
}
@Serializable @Serializable
public data class Line<out V : Vector>(val base: V, val direction: V) @SerialName("Line")
private data class LineImpl<out V : Vector>(override val start: V, override val direction: V): Line<V>
public fun <V : Vector> Line(base: V, direction: V): Line<V> = LineImpl(base, direction)
public typealias Line2D = Line<DoubleVector2D> public typealias Line2D = Line<DoubleVector2D>
public typealias Line3D = Line<DoubleVector3D> public typealias Line3D = Line<DoubleVector3D>
@ -21,8 +29,19 @@ public typealias Line3D = Line<DoubleVector3D>
/** /**
* A directed line segment between [begin] and [end] * A directed line segment between [begin] and [end]
*/ */
public interface LineSegment<out V : Vector> {
public val begin: V
public val end: V
}
/**
* Basic implementation for [LineSegment]
*/
@Serializable @Serializable
public data class LineSegment<out V : Vector>(val begin: V, val end: V) @SerialName("LineSegment")
private data class LineSegmentImpl<out V : Vector>(override val begin: V, override val end: V) : LineSegment<V>
public fun <V : Vector> LineSegment(begin: V, end: V): LineSegment<V> = LineSegmentImpl(begin, end)
public fun <V : Vector> LineSegment<V>.line(algebra: GeometrySpace<V>): Line<V> = with(algebra) { public fun <V : Vector> LineSegment<V>.line(algebra: GeometrySpace<V>): Line<V> = with(algebra) {
Line(begin, end - begin) Line(begin, end - begin)

View File

@ -13,7 +13,7 @@ package space.kscience.kmath.geometry
* @param line line to which vector should be projected * @param line line to which vector should be projected
*/ */
public fun <V : Vector> GeometrySpace<V>.projectToLine(vector: V, line: Line<V>): V = with(line) { public fun <V : Vector> GeometrySpace<V>.projectToLine(vector: V, line: Line<V>): V = with(line) {
base + (direction dot (vector - base)) / (direction dot direction) * direction start + (direction dot (vector - start)) / (direction dot direction) * direction
} }
/** /**

View File

@ -23,7 +23,7 @@ internal data class Tangent(
val lineSegment: LineSegment2D, val lineSegment: LineSegment2D,
val startDirection: Trajectory2D.Direction, val startDirection: Trajectory2D.Direction,
val endDirection: Trajectory2D.Direction = startDirection, val endDirection: Trajectory2D.Direction = startDirection,
) ): LineSegment2D by lineSegment
private class TangentPath(val tangents: List<Tangent>) { private class TangentPath(val tangents: List<Tangent>) {
fun last() = tangents.last() fun last() = tangents.last()
@ -128,7 +128,7 @@ private fun dubinsTangentsToCircles(
endCircle = secondCircle, endCircle = secondCircle,
startObstacle = firstObstacle, startObstacle = firstObstacle,
endObstacle = secondObstacle, endObstacle = secondObstacle,
lineSegment = LineSegment2D( lineSegment = LineSegment(
firstCircle.center + w * r1, firstCircle.center + w * r1,
secondCircle.center + w * r2 secondCircle.center + w * r2
), ),
@ -192,7 +192,7 @@ public class Obstacle(
other, other,
this@Obstacle, this@Obstacle,
this@Obstacle, this@Obstacle,
LineSegment2D( LineSegment(
center + w * r1, center + w * r1,
other.center + w * r2 other.center + w * r2
), ),
@ -245,7 +245,7 @@ public class Obstacle(
circles[i - 1], circles[i - 1],
this, this,
this, this,
LineSegment2D( LineSegment(
tangents[i - 1].lineSegment.end, tangents[i - 1].lineSegment.end,
tangents[i - 1].lineSegment.begin tangents[i - 1].lineSegment.begin
), ),
@ -257,7 +257,7 @@ public class Obstacle(
circles.last(), circles.last(),
this, this,
this, this,
LineSegment2D( LineSegment(
tangents.last().lineSegment.end, tangents.last().lineSegment.end,
tangents.last().lineSegment.begin tangents.last().lineSegment.begin
), ),
@ -493,7 +493,7 @@ internal fun findAllPaths(
initialCircles[i]!!, initialCircles[i]!!,
Obstacle(listOf(initialCircles[i]!!)), Obstacle(listOf(initialCircles[i]!!)),
Obstacle(listOf(initialCircles[i]!!)), Obstacle(listOf(initialCircles[i]!!)),
LineSegment2D(start, start), LineSegment(start, start),
i i
) )
) )
@ -582,7 +582,7 @@ internal fun findAllPaths(
end, end,
Obstacle(end), Obstacle(end),
Obstacle(end), Obstacle(end),
LineSegment2D(finish, finish), LineSegment(finish, finish),
startDirection = lastDirection, startDirection = lastDirection,
endDirection = j endDirection = j
) )

View File

@ -50,7 +50,7 @@ public data class StraightTrajectory2D(
public val bearing: Angle get() = (atan2(end.x - start.x, end.y - start.y).radians).normalized() public val bearing: Angle get() = (atan2(end.x - start.x, end.y - start.y).radians).normalized()
} }
public fun StraightTrajectory2D.toSegment(): LineSegment<Vector2D<Double>> = LineSegment2D(start, end) public fun StraightTrajectory2D.toSegment(): LineSegment<Vector2D<Double>> = LineSegment(start, end)
/** /**
* An arc segment * An arc segment