Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4dad7ae118 | ||
|
|
b89ab0622d | ||
|
|
793d96f354 | ||
|
|
34235d54d8 | ||
|
|
fe457034d5 | ||
|
|
b00dc481f8 | ||
|
|
608f4a6617 |
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalUuidApi::class)
|
||||
|
||||
package proposals.v1
|
||||
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.uuid.ExperimentalUuidApi
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
|
||||
/**
|
||||
* Abstract vertex that holds only an identifier.
|
||||
* It can be used for accessing properties of some vertex of some polytopic construction.
|
||||
*/
|
||||
public class AbstractVertex internal constructor(public val id: Uuid = Uuid.random()) {
|
||||
override fun toString(): String = "AbstractVertex#${id.toHexString()}"
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AbstractVertex) return false
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract edge that holds only an identifier.
|
||||
* It can be used for accessing properties of some edge of some polytopic construction.
|
||||
*/
|
||||
public class AbstractEdge internal constructor(public val id: Uuid = Uuid.random()) {
|
||||
override fun toString(): String = "AbstractEdge#${id.toHexString()}"
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AbstractEdge) return false
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract polygon that holds only an identifier.
|
||||
* It can be used for accessing properties of some polygon of some polytopic construction.
|
||||
*/
|
||||
public class AbstractPolygon internal constructor(public val id: Uuid = Uuid.random()) {
|
||||
override fun toString(): String = "AbstractPolygon#${id.toHexString()}"
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AbstractPolygon) return false
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract polyhedron that holds only an identifier.
|
||||
* It can be used for accessing properties of some polyhedron of some polytopic construction.
|
||||
*/
|
||||
public class AbstractPolyhedron internal constructor(public val id: Uuid = Uuid.random()) {
|
||||
override fun toString(): String = "AbstractPolyhedron#${id.toHexString()}"
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AbstractPolyhedron) return false
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract polytope that holds only an identifier.
|
||||
* It can be used for accessing properties of some polytope of some polytopic construction.
|
||||
*/
|
||||
public class AbstractPolytope internal constructor(public val id: Uuid = Uuid.random()) {
|
||||
override fun toString(): String = "AbstractPolytope#${id.toHexString()}"
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AbstractPolytope) return false
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
}
|
||||
|
||||
public typealias AbstractPolytopicConstruction2D<Vector> = PolytopicConstruction2D<Vector, AbstractVertex, AbstractEdge, AbstractPolygon>
|
||||
public typealias MutableAbstractPolytopicConstruction2D<Vector> = MutablePolytopicConstruction2D<Vector, AbstractVertex, AbstractEdge, AbstractPolygon>
|
||||
|
||||
public typealias AbstractPolytopicConstruction3D<Vector> = PolytopicConstruction3D<Vector, AbstractVertex, AbstractEdge, AbstractPolygon, AbstractPolyhedron>
|
||||
public typealias MutableAbstractPolytopicConstruction3D<Vector> = MutablePolytopicConstruction3D<Vector, AbstractVertex, AbstractEdge, AbstractPolygon, AbstractPolyhedron>
|
||||
|
||||
public typealias AbstractPolytopicConstruction<Vector> = PolytopicConstruction<Vector, AbstractVertex, AbstractPolytope>
|
||||
public typealias MutableAbstractPolytopicConstruction<Vector> = MutablePolytopicConstruction<Vector, AbstractVertex, AbstractPolytope>
|
||||
|
||||
/**
|
||||
* Builder of [AbstractPolytopicConstruction2D].
|
||||
*/
|
||||
public inline fun <Vector> AbstractPolytopicConstruction2D(
|
||||
block: MutableAbstractPolytopicConstruction2D<Vector>.() -> Unit
|
||||
): AbstractPolytopicConstruction2D<Vector> {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return MutableAbstractPolytopicConstruction2DImpl<Vector>().apply(block)
|
||||
}
|
||||
|
||||
@Suppress("EqualsOrHashCode")
|
||||
@PublishedApi
|
||||
internal class MutableAbstractPolytopicConstruction2DImpl<Vector> : MutableAbstractPolytopicConstruction2D<Vector> {
|
||||
private class ActualVertex<Vector>(
|
||||
val vertex: AbstractVertex,
|
||||
val position: Vector,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean = this === other
|
||||
}
|
||||
|
||||
private class ActualEdge<Vector>(
|
||||
val edge: AbstractEdge,
|
||||
val start: ActualVertex<Vector>,
|
||||
val end: ActualVertex<Vector>,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean = this === other
|
||||
}
|
||||
|
||||
private class ActualPolygon<Vector>(
|
||||
val polygon: AbstractPolygon,
|
||||
val vertices: Set<ActualVertex<Vector>>,
|
||||
val edges: Set<ActualEdge<Vector>>,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean = this === other
|
||||
}
|
||||
|
||||
private val _vertices: MutableMap<AbstractVertex, ActualVertex<Vector>> = mutableMapOf()
|
||||
override val vertices: Set<AbstractVertex> get() = _vertices.keys
|
||||
private val _edges: MutableMap<AbstractEdge, ActualEdge<Vector>> = mutableMapOf()
|
||||
override val edges: Set<AbstractEdge> get() = _edges.keys
|
||||
private val _polygons: MutableMap<AbstractPolygon, ActualPolygon<Vector>> = mutableMapOf()
|
||||
override val polygons: Set<AbstractPolygon> = _polygons.keys
|
||||
|
||||
override val AbstractVertex.position: Vector get() = (_vertices[this] ?: error("No such vertex in the construction")).position
|
||||
override fun addVertex(position: Vector): AbstractVertex {
|
||||
val abstractVertex = AbstractVertex()
|
||||
val actualVertex = ActualVertex(
|
||||
vertex = abstractVertex,
|
||||
position = position,
|
||||
)
|
||||
_vertices[abstractVertex] = actualVertex
|
||||
return abstractVertex
|
||||
}
|
||||
override fun AbstractVertex.remove() {
|
||||
val actualVertex = _vertices[this] ?: return
|
||||
val abstractEdges = _edges.keys
|
||||
for (abstractEdge in abstractEdges) {
|
||||
val actualEdge = _edges[abstractEdge]!!
|
||||
if (actualVertex == actualEdge.start || actualVertex == actualEdge.end) _edges.remove(abstractEdge)
|
||||
}
|
||||
val abstractPolygons = _polygons.keys
|
||||
for (abstractPolygon in abstractPolygons) {
|
||||
val actualPolygon = _polygons[abstractPolygon]!!
|
||||
if (actualVertex in actualPolygon.vertices) _polygons.remove(abstractPolygon)
|
||||
}
|
||||
_vertices.remove(this)
|
||||
}
|
||||
|
||||
override val AbstractEdge.start: AbstractVertex get() = (_edges[this] ?: error("No such edge in the construction")).start.vertex
|
||||
override val AbstractEdge.end: AbstractVertex get() = (_edges[this] ?: error("No such edge in the construction")).end.vertex
|
||||
override fun addEdge(start: AbstractVertex, end: AbstractVertex): AbstractEdge {
|
||||
val abstractEdge = AbstractEdge()
|
||||
val actualEdge = ActualEdge(
|
||||
edge = abstractEdge,
|
||||
start = _vertices[start] ?: error("No such vertex in the construction"),
|
||||
end = _vertices[end] ?: error("No such vertex in the construction"),
|
||||
)
|
||||
_edges[abstractEdge] = actualEdge
|
||||
return abstractEdge
|
||||
}
|
||||
override fun AbstractEdge.remove() {
|
||||
val actualEdge = _edges[this] ?: return
|
||||
val abstractPolygons = _polygons.keys
|
||||
for (abstractPolygon in abstractPolygons) {
|
||||
val actualPolygon = _polygons[abstractPolygon]!!
|
||||
if (actualEdge in actualPolygon.edges) _polygons.remove(abstractPolygon)
|
||||
}
|
||||
_edges.remove(this)
|
||||
}
|
||||
|
||||
override val AbstractPolygon.vertices: Set<AbstractVertex>
|
||||
get() = (_polygons[this] ?: error("No such polygon in the construction")).vertices.mapTo(mutableSetOf()) { it.vertex }
|
||||
override val AbstractPolygon.edges: Set<AbstractEdge>
|
||||
get() = (_polygons[this] ?: error("No such polygon in the construction")).edges.mapTo(mutableSetOf()) { it.edge }
|
||||
override fun addPolygon(vertices: Set<AbstractVertex>, edges: Set<AbstractEdge>): AbstractPolygon {
|
||||
val abstractPolygon = AbstractPolygon()
|
||||
val actualPolygon = ActualPolygon(
|
||||
polygon = abstractPolygon,
|
||||
vertices = vertices.mapTo(mutableSetOf()) { _vertices[it] ?: error("No such vertex in the construction") },
|
||||
edges = edges.mapTo(mutableSetOf()) { _edges[it] ?: error("No such edge in the construction") },
|
||||
)
|
||||
_polygons[abstractPolygon] = actualPolygon
|
||||
return abstractPolygon
|
||||
}
|
||||
override fun AbstractPolygon.remove() {
|
||||
_polygons.remove(this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder of [AbstractPolytopicConstruction3D].
|
||||
*/
|
||||
public inline fun <Vector> AbstractPolytopicConstruction3D(
|
||||
block: MutableAbstractPolytopicConstruction3D<Vector>.() -> Unit
|
||||
): AbstractPolytopicConstruction3D<Vector> {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return MutableAbstractPolytopicConstruction3DImpl<Vector>().apply(block)
|
||||
}
|
||||
|
||||
@Suppress("EqualsOrHashCode")
|
||||
@PublishedApi
|
||||
internal class MutableAbstractPolytopicConstruction3DImpl<Vector> : MutableAbstractPolytopicConstruction3D<Vector> {
|
||||
private class ActualVertex<Vector>(
|
||||
val vertex: AbstractVertex,
|
||||
val position: Vector,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean = this === other
|
||||
}
|
||||
|
||||
private class ActualEdge<Vector>(
|
||||
val edge: AbstractEdge,
|
||||
val start: ActualVertex<Vector>,
|
||||
val end: ActualVertex<Vector>,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean = this === other
|
||||
}
|
||||
|
||||
private class ActualPolygon<Vector>(
|
||||
val polygon: AbstractPolygon,
|
||||
val vertices: Set<ActualVertex<Vector>>,
|
||||
val edges: Set<ActualEdge<Vector>>,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean = this === other
|
||||
}
|
||||
|
||||
private class ActualPolyhedron<Vector>(
|
||||
val polyhedron: AbstractPolyhedron,
|
||||
val vertices: Set<ActualVertex<Vector>>,
|
||||
val edges: Set<ActualEdge<Vector>>,
|
||||
val faces: Set<ActualPolygon<Vector>>,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean = this === other
|
||||
}
|
||||
|
||||
private val _vertices: MutableMap<AbstractVertex, ActualVertex<Vector>> = mutableMapOf()
|
||||
override val vertices: Set<AbstractVertex> get() = _vertices.keys
|
||||
private val _edges: MutableMap<AbstractEdge, ActualEdge<Vector>> = mutableMapOf()
|
||||
override val edges: Set<AbstractEdge> get() = _edges.keys
|
||||
private val _polygons: MutableMap<AbstractPolygon, ActualPolygon<Vector>> = mutableMapOf()
|
||||
override val polygons: Set<AbstractPolygon> get() = _polygons.keys
|
||||
private val _polyhedra: MutableMap<AbstractPolyhedron, ActualPolyhedron<Vector>> = mutableMapOf()
|
||||
override val polyhedra: Set<AbstractPolyhedron> get() = _polyhedra.keys
|
||||
|
||||
override val AbstractVertex.position: Vector get() = (_vertices[this] ?: error("No such vertex in the construction")).position
|
||||
override fun addVertex(position: Vector): AbstractVertex {
|
||||
val abstractVertex = AbstractVertex()
|
||||
val actualVertex = ActualVertex(
|
||||
vertex = abstractVertex,
|
||||
position = position,
|
||||
)
|
||||
_vertices[abstractVertex] = actualVertex
|
||||
return abstractVertex
|
||||
}
|
||||
override fun AbstractVertex.remove() {
|
||||
val actualVertex = _vertices[this] ?: return
|
||||
val abstractEdges = _edges.keys
|
||||
for (abstractEdge in abstractEdges) {
|
||||
val actualEdge = _edges[abstractEdge]!!
|
||||
if (actualVertex == actualEdge.start || actualVertex == actualEdge.end) _edges.remove(abstractEdge)
|
||||
}
|
||||
val abstractPolygons = _polygons.keys
|
||||
for (abstractPolygon in abstractPolygons) {
|
||||
val actualPolygon = _polygons[abstractPolygon]!!
|
||||
if (actualVertex in actualPolygon.vertices) _polygons.remove(abstractPolygon)
|
||||
}
|
||||
val abstractPolyhedra = _polyhedra.keys
|
||||
for (abstractPolyhedron in abstractPolyhedra) {
|
||||
val actualPolyhedron = _polyhedra[abstractPolyhedron]!!
|
||||
if (actualVertex in actualPolyhedron.vertices) _polyhedra.remove(abstractPolyhedron)
|
||||
}
|
||||
_vertices.remove(this)
|
||||
}
|
||||
|
||||
override val AbstractEdge.start: AbstractVertex get() = (_edges[this] ?: error("No such edge in the construction")).start.vertex
|
||||
override val AbstractEdge.end: AbstractVertex get() = (_edges[this] ?: error("No such edge in the construction")).end.vertex
|
||||
override fun addEdge(start: AbstractVertex, end: AbstractVertex): AbstractEdge {
|
||||
val abstractEdge = AbstractEdge()
|
||||
val actualEdge = ActualEdge(
|
||||
edge = abstractEdge,
|
||||
start = _vertices[start] ?: error("No such vertex in the construction"),
|
||||
end = _vertices[end] ?: error("No such vertex in the construction"),
|
||||
)
|
||||
_edges[abstractEdge] = actualEdge
|
||||
return abstractEdge
|
||||
}
|
||||
override fun AbstractEdge.remove() {
|
||||
val actualEdge = _edges[this] ?: return
|
||||
val abstractPolygons = _polygons.keys
|
||||
for (abstractPolygon in abstractPolygons) {
|
||||
val actualPolygon = _polygons[abstractPolygon]!!
|
||||
if (actualEdge in actualPolygon.edges) _polygons.remove(abstractPolygon)
|
||||
}
|
||||
val abstractPolyhedra = _polyhedra.keys
|
||||
for (abstractPolyhedron in abstractPolyhedra) {
|
||||
val actualPolyhedron = _polyhedra[abstractPolyhedron]!!
|
||||
if (actualEdge in actualPolyhedron.edges) _polyhedra.remove(abstractPolyhedron)
|
||||
}
|
||||
_edges.remove(this)
|
||||
}
|
||||
|
||||
override val AbstractPolygon.vertices: Set<AbstractVertex>
|
||||
get() = (_polygons[this] ?: error("No such polygon in the construction")).vertices.mapTo(mutableSetOf()) { it.vertex }
|
||||
override val AbstractPolygon.edges: Set<AbstractEdge>
|
||||
get() = (_polygons[this] ?: error("No such polygon in the construction")).edges.mapTo(mutableSetOf()) { it.edge }
|
||||
override fun addPolygon(vertices: Set<AbstractVertex>, edges: Set<AbstractEdge>): AbstractPolygon {
|
||||
val abstractPolygon = AbstractPolygon()
|
||||
val actualPolygon = ActualPolygon(
|
||||
polygon = abstractPolygon,
|
||||
vertices = vertices.mapTo(mutableSetOf()) { _vertices[it] ?: error("No such vertex in the construction") },
|
||||
edges = edges.mapTo(mutableSetOf()) { _edges[it] ?: error("No such edge in the construction") },
|
||||
)
|
||||
_polygons[abstractPolygon] = actualPolygon
|
||||
return abstractPolygon
|
||||
}
|
||||
override fun AbstractPolygon.remove() {
|
||||
val actualPolygon = _polygons[this] ?: return
|
||||
val abstractPolyhedra = _polyhedra.keys
|
||||
for (abstractPolyhedron in abstractPolyhedra) {
|
||||
val actualPolyhedron = _polyhedra[abstractPolyhedron]!!
|
||||
if (actualPolygon in actualPolyhedron.faces) _polyhedra.remove(abstractPolyhedron)
|
||||
}
|
||||
_polygons.remove(this)
|
||||
}
|
||||
|
||||
override val AbstractPolyhedron.vertices: Set<AbstractVertex>
|
||||
get() = (_polyhedra[this] ?: error("No such polyhedron in the construction")).vertices.mapTo(mutableSetOf()) { it.vertex }
|
||||
override val AbstractPolyhedron.edges: Set<AbstractEdge>
|
||||
get() = (_polyhedra[this] ?: error("No such polyhedron in the construction")).edges.mapTo(mutableSetOf()) { it.edge }
|
||||
override val AbstractPolyhedron.faces: Set<AbstractPolygon>
|
||||
get() = (_polyhedra[this] ?: error("No such polyhedron in the construction")).faces.mapTo(mutableSetOf()) { it.polygon }
|
||||
override fun addPolyhedron(
|
||||
vertices: Set<AbstractVertex>,
|
||||
edges: Set<AbstractEdge>,
|
||||
faces: Set<AbstractPolygon>
|
||||
): AbstractPolyhedron {
|
||||
val abstractPolyhedron = AbstractPolyhedron()
|
||||
val actualPolyhedron = ActualPolyhedron(
|
||||
polyhedron = abstractPolyhedron,
|
||||
vertices = vertices.mapTo(mutableSetOf()) { _vertices[it] ?: error("No such vertex in the construction") },
|
||||
edges = edges.mapTo(mutableSetOf()) { _edges[it] ?: error("No such edge in the construction") },
|
||||
faces = faces.mapTo(mutableSetOf()) { _polygons[it] ?: error("No such polygon in the construction") },
|
||||
)
|
||||
_polyhedra[abstractPolyhedron] = actualPolyhedron
|
||||
return abstractPolyhedron
|
||||
}
|
||||
override fun AbstractPolyhedron.remove() {
|
||||
_polyhedra.remove(this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for [AbstractPolytopicConstruction].
|
||||
*/
|
||||
public inline fun <Vector> AbstractPolytopicConstruction(
|
||||
dimension: Int,
|
||||
block: MutableAbstractPolytopicConstruction<Vector>.() -> Unit
|
||||
): AbstractPolytopicConstruction<Vector> {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return MutableAbstractPolytopicConstructionImpl<Vector>(dimension).apply(block)
|
||||
}
|
||||
|
||||
@Suppress("EqualsOrHashCode")
|
||||
@PublishedApi
|
||||
internal class MutableAbstractPolytopicConstructionImpl<Vector>(
|
||||
override val dimension: Int,
|
||||
) : MutableAbstractPolytopicConstruction<Vector> {
|
||||
private class ActualVertex<Vector>(
|
||||
val vertex: AbstractVertex,
|
||||
correspondingAbstractPolytope: AbstractPolytope,
|
||||
val position: Vector,
|
||||
) {
|
||||
val correspondingPolytope: ActualPolytope<Vector> =
|
||||
ActualPolytope(
|
||||
polytope = correspondingAbstractPolytope,
|
||||
correspondingVertex = this,
|
||||
dimension = 0,
|
||||
vertices = setOf(this),
|
||||
faces = emptyList()
|
||||
)
|
||||
override fun equals(other: Any?): Boolean = this === other
|
||||
}
|
||||
|
||||
private class ActualPolytope<Vector>(
|
||||
val polytope: AbstractPolytope,
|
||||
val correspondingVertex: ActualVertex<Vector>?,
|
||||
val dimension: Int,
|
||||
val vertices: Set<ActualVertex<Vector>>,
|
||||
val faces: List<Set<ActualPolytope<Vector>>>
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean = this === other
|
||||
}
|
||||
|
||||
private val _vertices: MutableMap<AbstractVertex, ActualVertex<Vector>> = mutableMapOf()
|
||||
override val vertices: Set<AbstractVertex> get() = _vertices.keys
|
||||
private val _polytopes: List<MutableMap<AbstractPolytope, ActualPolytope<Vector>>> = List(dimension + 1) { mutableMapOf() }
|
||||
override val polytopes: List<Set<AbstractPolytope>> get() = _polytopes.map { it.keys }
|
||||
private val allPolytopes: MutableMap<AbstractPolytope, ActualPolytope<Vector>> = mutableMapOf()
|
||||
|
||||
override val AbstractVertex.position: Vector get() = (_vertices[this] ?: error("No such vertex in the construction")).position
|
||||
override fun AbstractVertex.asPolytope(): AbstractPolytope =
|
||||
(_vertices[this] ?: error("No such vertex in the construction")).correspondingPolytope.polytope
|
||||
override fun addVertex(position: Vector): AbstractVertex {
|
||||
val abstractVertex = AbstractVertex()
|
||||
val actualVertex = ActualVertex(
|
||||
vertex = abstractVertex,
|
||||
correspondingAbstractPolytope = AbstractPolytope(),
|
||||
position = position,
|
||||
)
|
||||
_vertices[abstractVertex] = actualVertex
|
||||
_polytopes[0][actualVertex.correspondingPolytope.polytope] = actualVertex.correspondingPolytope
|
||||
allPolytopes[actualVertex.correspondingPolytope.polytope] = actualVertex.correspondingPolytope
|
||||
return abstractVertex
|
||||
}
|
||||
override fun AbstractVertex.remove() {
|
||||
val actualVertex = _vertices[this] ?: return
|
||||
_polytopes.forEach {
|
||||
val abstractPolytopes = it.keys
|
||||
for (abstractPolytope in abstractPolytopes) {
|
||||
val actualPolytope = it[abstractPolytope]!!
|
||||
if (actualVertex in actualPolytope.vertices) it.remove(abstractPolytope)
|
||||
}
|
||||
}
|
||||
_vertices.remove(this)
|
||||
}
|
||||
|
||||
override val AbstractPolytope.dimension: Int
|
||||
get() = (allPolytopes[this] ?: error("No such polytope in the construction")).dimension
|
||||
override val AbstractPolytope.vertices: Set<AbstractVertex>
|
||||
get() = (allPolytopes[this] ?: error("No such polytope in the construction")).vertices.mapTo(mutableSetOf()) { it.vertex }
|
||||
override val AbstractPolytope.faces: List<Set<AbstractPolytope>>
|
||||
get() = (allPolytopes[this] ?: error("No such polytope in the construction")).faces.map { facesOfDimension -> facesOfDimension.mapTo(mutableSetOf()) { it.polytope } }
|
||||
override fun addPolytope(
|
||||
dimension: Int,
|
||||
vertices: Set<AbstractVertex>,
|
||||
faces: List<Set<AbstractPolytope>>
|
||||
): AbstractPolytope {
|
||||
require(dimension > 0) { "0-dimensional polytopes should created via 'addVertex' method" }
|
||||
val abstractPolytope = AbstractPolytope()
|
||||
val actualPolytope = ActualPolytope(
|
||||
polytope = abstractPolytope,
|
||||
correspondingVertex = null,
|
||||
dimension = dimension,
|
||||
vertices = vertices.mapTo(mutableSetOf()) { _vertices[it] ?: error("No such vertex in the construction") },
|
||||
faces = faces.mapIndexed { dim, faces -> faces.mapTo(mutableSetOf()) { _polytopes[dim][it] ?: error("No such polytope in the construction") } },
|
||||
)
|
||||
_polytopes[dimension][abstractPolytope] = actualPolytope
|
||||
allPolytopes[abstractPolytope] = actualPolytope
|
||||
return abstractPolytope
|
||||
}
|
||||
override fun AbstractPolytope.remove() {
|
||||
val thisActualPolytope = allPolytopes[this] ?: return
|
||||
for (dim in thisActualPolytope.dimension + 1 .. this@MutableAbstractPolytopicConstructionImpl.dimension) {
|
||||
val abstractPolytopes = _polytopes[dim].keys
|
||||
for (abstractPolytope in abstractPolytopes) {
|
||||
val actualPolytope = _polytopes[dim][abstractPolytope]!!
|
||||
if (thisActualPolytope in actualPolytope.faces[thisActualPolytope.dimension]) {
|
||||
_polytopes[dim].remove(abstractPolytope)
|
||||
allPolytopes.remove(abstractPolytope)
|
||||
}
|
||||
}
|
||||
}
|
||||
_polytopes[thisActualPolytope.dimension].remove(this)
|
||||
allPolytopes.remove(this)
|
||||
thisActualPolytope.correspondingVertex?.also { _vertices.remove(it.vertex) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v1
|
||||
|
||||
|
||||
/**
|
||||
* The polytopic construction.
|
||||
*/
|
||||
public interface PolytopicConstruction<Vector, Vertex, Polytope> {
|
||||
/**
|
||||
* Dimension of the polytopic construction.
|
||||
*/
|
||||
public val dimension: Int
|
||||
/**
|
||||
* Contains all the polytopes in the construction.
|
||||
* Each index `i` corresponds to set of all polytopes of dimension `i`.
|
||||
* Its size is [dimension]` + 1`.
|
||||
*/
|
||||
public val polytopes: List<Set<Polytope>>
|
||||
/**
|
||||
* Contains all the vertices in the construction.
|
||||
* Actually, it is the first set in the [polytopes] list but with right type.
|
||||
*/
|
||||
public val vertices: Set<Vertex>
|
||||
/**
|
||||
* Dimension of the polytope in the construction.
|
||||
*/
|
||||
public val Polytope.dimension: Int
|
||||
/**
|
||||
* Contains all the faces of [this] polytope.
|
||||
* Each index `i` corresponds to set of all faces of dimension `i`.
|
||||
* Its size is `dimension` (where `dimension` is the polytope's dimension).
|
||||
*/
|
||||
public val Polytope.faces: List<Set<Polytope>>
|
||||
/**
|
||||
* Contains all the vertices in [this] polytope.
|
||||
* Actually, it is the first set in the [faces] list but with right type.
|
||||
*/
|
||||
public val Polytope.vertices: Set<Vertex>
|
||||
/**
|
||||
* Position of [this] vertex in Euclidean space.
|
||||
*/
|
||||
public val Vertex.position: Vector
|
||||
/**
|
||||
* Returns 0-dimensional polytope associated with the vertex.
|
||||
*/
|
||||
public fun Vertex.asPolytope(): Polytope
|
||||
}
|
||||
|
||||
/**
|
||||
* The mutable polytopic construction.
|
||||
*/
|
||||
public interface MutablePolytopicConstruction<Vector, Vertex, Polytope> : PolytopicConstruction<Vector, Vertex, Polytope> {
|
||||
/**
|
||||
* Creates new vertex with provided position.
|
||||
*/
|
||||
public fun addVertex(position: Vector): Vertex
|
||||
/**
|
||||
* Creates new polytope by its dimension, its faces, and its vertices.
|
||||
*/
|
||||
public fun addPolytope(
|
||||
dimension: Int,
|
||||
vertices: Set<Vertex>,
|
||||
faces: List<Set<Polytope>>,
|
||||
): Polytope
|
||||
/**
|
||||
* Removes the vertex.
|
||||
* Also removes all polytopes that contain the vertex.
|
||||
*/
|
||||
public fun Vertex.remove()
|
||||
/**
|
||||
* Removes the polytope.
|
||||
* Also removes all polytopes that contain the polytope.
|
||||
*/
|
||||
public fun Polytope.remove()
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v1
|
||||
|
||||
|
||||
/**
|
||||
* The 2D polytopic construction.
|
||||
*/
|
||||
public interface PolytopicConstruction2D<Vector, Vertex, Edge, Polygon> {
|
||||
/**
|
||||
* Contains all the vertices in the construction.
|
||||
*/
|
||||
public val vertices: Set<Vertex>
|
||||
/**
|
||||
* Contains all the edges in the construction.
|
||||
*/
|
||||
public val edges: Set<Edge>
|
||||
/**
|
||||
* Contains all the polygons in the construction.
|
||||
*/
|
||||
public val polygons: Set<Polygon>
|
||||
|
||||
/**
|
||||
* Returns position of the vertex.
|
||||
*/
|
||||
public val Vertex.position: Vector
|
||||
|
||||
/**
|
||||
* Returns start vertex of the edge. It is just some one vertex of the edge.
|
||||
*/
|
||||
public val Edge.start: Vertex
|
||||
/**
|
||||
* Returns end vertex of the edge. It is just some one vertex of the edge.
|
||||
*/
|
||||
public val Edge.end: Vertex
|
||||
|
||||
/**
|
||||
* Returns all vertices of the polygon.
|
||||
*/
|
||||
public val Polygon.vertices: Set<Vertex>
|
||||
/**
|
||||
* Returns all edges of the polytope.
|
||||
*/
|
||||
public val Polygon.edges: Set<Edge>
|
||||
}
|
||||
|
||||
/**
|
||||
* The 2D mutable polytopic construction.
|
||||
*/
|
||||
public interface MutablePolytopicConstruction2D<Vector, Vertex, Edge, Polygon> : PolytopicConstruction2D<Vector, Vertex, Edge, Polygon> {
|
||||
/**
|
||||
* Creates new vertex with provided position.
|
||||
*/
|
||||
public fun addVertex(position: Vector): Vertex
|
||||
/**
|
||||
* Creates new edge with provided ends.
|
||||
*/
|
||||
public fun addEdge(start: Vertex, end: Vertex): Edge
|
||||
/**
|
||||
* Creates new polygon with provided vertices and edges.
|
||||
*/
|
||||
public fun addPolygon(vertices: Set<Vertex>, edges: Set<Edge>): Polygon
|
||||
|
||||
/**
|
||||
* Removes the vertex.
|
||||
* Also removes all edges and polygons that contain the vertex.
|
||||
*/
|
||||
public fun Vertex.remove()
|
||||
/**
|
||||
* Removes the edge.
|
||||
* Also removes all polygons that contain the edge.
|
||||
*/
|
||||
public fun Edge.remove()
|
||||
/**
|
||||
* Removes the polygon.
|
||||
*/
|
||||
public fun Polygon.remove()
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v1
|
||||
|
||||
|
||||
/**
|
||||
* The 3D polytopic construction.
|
||||
*/
|
||||
public interface PolytopicConstruction3D<Vector, Vertex, Edge, Polygon, Polyhedron> {
|
||||
/**
|
||||
* Contains all the vertices in the construction.
|
||||
*/
|
||||
public val vertices: Set<Vertex>
|
||||
/**
|
||||
* Contains all the edges in the construction.
|
||||
*/
|
||||
public val edges: Set<Edge>
|
||||
/**
|
||||
* Contains all the polygons in the construction.
|
||||
*/
|
||||
public val polygons: Set<Polygon>
|
||||
/**
|
||||
* Contains all the polyhedra in the construction.
|
||||
*/
|
||||
public val polyhedra: Set<Polyhedron>
|
||||
|
||||
/**
|
||||
* Returns position of the vertex.
|
||||
*/
|
||||
public val Vertex.position: Vector
|
||||
|
||||
/**
|
||||
* Returns start vertex of the edge. It is just some one vertex of the edge.
|
||||
*/
|
||||
public val Edge.start: Vertex
|
||||
/**
|
||||
* Returns end vertex of the edge. It is just some one vertex of the edge.
|
||||
*/
|
||||
public val Edge.end: Vertex
|
||||
|
||||
/**
|
||||
* Returns all vertices of the polygon.
|
||||
*/
|
||||
public val Polygon.vertices: Set<Vertex>
|
||||
/**
|
||||
* Returns all edges of the polytope.
|
||||
*/
|
||||
public val Polygon.edges: Set<Edge>
|
||||
|
||||
/**
|
||||
* Returns all vertices of the polyhedron.
|
||||
*/
|
||||
public val Polyhedron.vertices: Set<Vertex>
|
||||
/**
|
||||
* Returns all edges of the polyhedron.
|
||||
*/
|
||||
public val Polyhedron.edges: Set<Edge>
|
||||
/**
|
||||
* Returns all faces of the polyhedron.
|
||||
*/
|
||||
public val Polyhedron.faces: Set<Polygon>
|
||||
}
|
||||
|
||||
public interface MutablePolytopicConstruction3D<Vector, Vertex, Edge, Polygon, Polyhedron> : PolytopicConstruction3D<Vector, Vertex, Edge, Polygon, Polyhedron> {
|
||||
/**
|
||||
* Creates new vertex with provided position.
|
||||
*/
|
||||
public fun addVertex(position: Vector): Vertex
|
||||
/**
|
||||
* Creates new edge with provided ends.
|
||||
*/
|
||||
public fun addEdge(start: Vertex, end: Vertex): Edge
|
||||
/**
|
||||
* Creates new polygon with provided vertices and edges.
|
||||
*/
|
||||
public fun addPolygon(vertices: Set<Vertex>, edges: Set<Edge>): Polygon
|
||||
/**
|
||||
* Creates new polyhedron with provided vertices, edges, and faces.
|
||||
*/
|
||||
public fun addPolyhedron(vertices: Set<Vertex>, edges: Set<Edge>, faces: Set<Polygon>): Polyhedron
|
||||
|
||||
/**
|
||||
* Removes the vertex.
|
||||
* Also removes all edges, polygons, and polyhedra that contain the vertex.
|
||||
*/
|
||||
public fun Vertex.remove()
|
||||
/**
|
||||
* Removes the edge.
|
||||
* Also removes all polygons and polyhedra that contain the edge.
|
||||
*/
|
||||
public fun Edge.remove()
|
||||
/**
|
||||
* Removes the polygon.
|
||||
* Also removes all polyhedra that contain the edge.
|
||||
*/
|
||||
public fun Polygon.remove()
|
||||
/**
|
||||
* Removes the polyhedra.
|
||||
*/
|
||||
public fun Polyhedron.remove()
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v1
|
||||
|
||||
import space.kscience.kmath.geometry.GeometrySpace
|
||||
import space.kscience.kmath.geometry.projectAlong
|
||||
|
||||
|
||||
/**
|
||||
* Projects the [projectedPolytopicConstruction] along [normal] onto hyperplane normal to the [normal]
|
||||
* and going through [base] and adds projection results to [targetPolytopicConstruction].
|
||||
*/
|
||||
public fun <V: Any, PVertex, PPolytope, TVertex, TPolytope> GeometrySpace<V, *>.projectAlong(
|
||||
projectedPolytopicConstruction: PolytopicConstruction<V, PVertex, PPolytope>,
|
||||
targetPolytopicConstruction: MutablePolytopicConstruction<V, TVertex, TPolytope>,
|
||||
normal: V,
|
||||
base: V,
|
||||
) {
|
||||
require(targetPolytopicConstruction.dimension >= projectedPolytopicConstruction.dimension - 1)
|
||||
with(projectedPolytopicConstruction) {
|
||||
with(targetPolytopicConstruction) {
|
||||
val newVertices: Map<PVertex, TVertex> = projectedPolytopicConstruction.vertices.associateWith { vertex ->
|
||||
addVertex(projectAlong(vertex.position, normal, base))
|
||||
}
|
||||
val newPolytopes: MutableList<Map<PPolytope, TPolytope>> =
|
||||
mutableListOf(
|
||||
buildMap {
|
||||
for ((pVertex, tVertex) in newVertices) put(pVertex.asPolytope(), tVertex.asPolytope())
|
||||
}
|
||||
)
|
||||
for (dim in 1 ..< projectedPolytopicConstruction.dimension)
|
||||
newPolytopes += buildMap {
|
||||
for (pPolytope in projectedPolytopicConstruction.polytopes[dim]) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val tVertices = pPolytope.vertices.mapTo(mutableSetOf()) { newVertices[it] as TVertex }
|
||||
val tFaces: MutableList<Set<TPolytope>> = mutableListOf()
|
||||
for (subdim in 0 ..< dim)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
tFaces += pPolytope.faces[subdim].mapTo(mutableSetOf()) { newPolytopes[subdim][it] as TPolytope }
|
||||
put(
|
||||
pPolytope,
|
||||
addPolytope(
|
||||
dimension = dim,
|
||||
vertices = tVertices,
|
||||
faces = tFaces,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects the [polytopicConstruction3D] along [normal] onto hyperplane normal to the [normal] and going through [base].
|
||||
* Result is a new [AbstractPolytopicConstruction2D].
|
||||
*/
|
||||
public fun <
|
||||
V: Any,
|
||||
PVertex,
|
||||
PEdge,
|
||||
PPolygon,
|
||||
> GeometrySpace<V, *>.projectAlongToAbstractPolytopicConstruction2D(
|
||||
polytopicConstruction3D: PolytopicConstruction3D<V, PVertex, PEdge, PPolygon, *>,
|
||||
normal: V,
|
||||
base: V,
|
||||
): AbstractPolytopicConstruction2D<V> = with(polytopicConstruction3D) {
|
||||
AbstractPolytopicConstruction2D {
|
||||
val newVertices = polytopicConstruction3D.vertices.associateWith { vertex ->
|
||||
addVertex(projectAlong(vertex.position, normal, base))
|
||||
}
|
||||
val newEdges = polytopicConstruction3D.edges.associateWith { edge ->
|
||||
addEdge(newVertices[edge.start]!!, newVertices[edge.end]!!)
|
||||
}
|
||||
polytopicConstruction3D.polygons.forEach { polygon ->
|
||||
addPolygon(
|
||||
vertices = polygon.vertices.mapTo(mutableSetOf()) { newVertices[it]!! },
|
||||
edges = polygon.edges.mapTo(mutableSetOf()) { newEdges[it]!! }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns vertex of [polytopicConstruction] nearest to the [point].
|
||||
*/
|
||||
public fun <
|
||||
Vector: Any,
|
||||
Vertex
|
||||
> GeometrySpace<Vector, *>.nearestVertexOfTo(
|
||||
polytopicConstruction: PolytopicConstruction<Vector, Vertex, *>,
|
||||
point: Vector,
|
||||
): Vertex =
|
||||
with(polytopicConstruction) { vertices.minBy { it.position.distanceTo(point) } }
|
||||
|
||||
/**
|
||||
* Removes vertex of [polytopicConstruction] nearest to the [point].
|
||||
*/
|
||||
public fun <
|
||||
Vector: Any,
|
||||
Vertex
|
||||
> GeometrySpace<Vector, *>.removeNearestVertexOfTo(
|
||||
polytopicConstruction: MutablePolytopicConstruction<Vector, Vertex, *>,
|
||||
point: Vector,
|
||||
) {
|
||||
val vertexToRemove = nearestVertexOfTo(polytopicConstruction, point)
|
||||
with(polytopicConstruction) { vertexToRemove.remove() }
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalUuidApi::class)
|
||||
|
||||
package proposals.v2.v1
|
||||
|
||||
import kotlin.uuid.ExperimentalUuidApi
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
|
||||
public class AbstractVertex<Vector> internal constructor(
|
||||
private val construction: AbstractPolytopicConstruction<Vector>,
|
||||
override val position: Vector
|
||||
) : MutablePolytopicConstruction.Vertex<Vector, AbstractVertex<Vector>, AbstractPolytope<Vector>> {
|
||||
public val id: Uuid = Uuid.random()
|
||||
|
||||
private val correspondingPolytope = AbstractPolytope(
|
||||
construction = construction,
|
||||
correspondingVertex = this,
|
||||
dimension = 0,
|
||||
vertices = setOf(this),
|
||||
faces = emptyList(),
|
||||
)
|
||||
override fun asPolytope(): AbstractPolytope<Vector> = correspondingPolytope
|
||||
override fun remove() {
|
||||
construction._polytopes.forEach { polytopes -> polytopes.removeAll { this in it.vertices } }
|
||||
construction._vertices.remove(this)
|
||||
}
|
||||
|
||||
override fun toString(): String = "AbstractVertex#${id.toHexString()} at $position"
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AbstractVertex<*>) return false
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
}
|
||||
|
||||
public class AbstractPolytope<Vector> internal constructor(
|
||||
private val construction: AbstractPolytopicConstruction<Vector>,
|
||||
private val correspondingVertex: AbstractVertex<Vector>?,
|
||||
override val dimension: Int,
|
||||
override val vertices: Set<AbstractVertex<Vector>>,
|
||||
override val faces: List<Set<AbstractPolytope<Vector>>>,
|
||||
) : MutablePolytopicConstruction.Polytope<Vector, AbstractVertex<Vector>, AbstractPolytope<Vector>> {
|
||||
public val id: Uuid = Uuid.random()
|
||||
|
||||
override fun remove() {
|
||||
construction._polytopes[dimension].remove(this)
|
||||
for (i in dimension + 1 .. construction.dimension)
|
||||
construction._polytopes[i].removeAll { this in it.faces[dimension] }
|
||||
correspondingVertex?.also { construction._vertices.remove(it) }
|
||||
}
|
||||
|
||||
override fun toString(): String = "AbstractPolytope#${id.toHexString()}"
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AbstractPolytope<*>) return false
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
}
|
||||
|
||||
public class AbstractPolytopicConstruction<Vector>(
|
||||
override val dimension: Int,
|
||||
) : MutablePolytopicConstruction<Vector, AbstractVertex<Vector>, AbstractPolytope<Vector>> {
|
||||
internal val _vertices: MutableSet<AbstractVertex<Vector>> = mutableSetOf()
|
||||
override val vertices: Set<AbstractVertex<Vector>> get() = _vertices
|
||||
|
||||
internal val _polytopes: List<MutableSet<AbstractPolytope<Vector>>> = List(dimension + 1) { mutableSetOf() }
|
||||
override val polytopes: List<Set<AbstractPolytope<Vector>>> get() = _polytopes
|
||||
|
||||
override fun addVertex(position: Vector): AbstractVertex<Vector> {
|
||||
val vertex = AbstractVertex(
|
||||
construction = this,
|
||||
position = position,
|
||||
)
|
||||
_vertices.add(vertex)
|
||||
_polytopes[0].add(vertex.asPolytope())
|
||||
return vertex
|
||||
}
|
||||
override fun addPolytope(
|
||||
dimension: Int,
|
||||
vertices: Set<AbstractVertex<Vector>>,
|
||||
faces: List<Set<AbstractPolytope<Vector>>>
|
||||
): AbstractPolytope<Vector> {
|
||||
require(dimension > 0)
|
||||
val polytope = AbstractPolytope(
|
||||
construction = this,
|
||||
correspondingVertex = null,
|
||||
dimension = dimension,
|
||||
vertices = vertices,
|
||||
faces = faces,
|
||||
)
|
||||
_polytopes[dimension].add(polytope)
|
||||
return polytope
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalUuidApi::class)
|
||||
|
||||
package proposals.v2.v1
|
||||
|
||||
import kotlin.uuid.ExperimentalUuidApi
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
|
||||
public class AbstractVertex2D<Vector> internal constructor(
|
||||
private val construction: AbstractPolytopicConstruction2D<Vector>,
|
||||
override val position: Vector
|
||||
) : MutablePolytopicConstruction2D.Vertex<Vector> {
|
||||
public val id: Uuid = Uuid.random()
|
||||
|
||||
override fun remove() {
|
||||
construction._vertices.remove(this)
|
||||
construction._edges.removeAll { this == it.start || this == it.end }
|
||||
construction._polygons.removeAll { this in it.vertices }
|
||||
}
|
||||
|
||||
override fun toString(): String = "AbstractVertex2D#${id.toHexString()} at $position"
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AbstractVertex2D<*>) return false
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
}
|
||||
|
||||
public class AbstractEdge2D<Vector> internal constructor(
|
||||
private val construction: AbstractPolytopicConstruction2D<Vector>,
|
||||
override val start: AbstractVertex2D<Vector>,
|
||||
override val end: AbstractVertex2D<Vector>,
|
||||
) : MutablePolytopicConstruction2D.Edge<Vector, AbstractVertex2D<Vector>> {
|
||||
public val id: Uuid = Uuid.random()
|
||||
|
||||
override fun remove() {
|
||||
construction._edges.remove(this)
|
||||
construction._polygons.removeAll { this in it.edges }
|
||||
}
|
||||
|
||||
override fun toString(): String = "AbstractEdge2D#${id.toHexString()}"
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AbstractEdge2D<*>) return false
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
}
|
||||
|
||||
public class AbstractPolygon2D<Vector> internal constructor(
|
||||
private val construction: AbstractPolytopicConstruction2D<Vector>,
|
||||
override val vertices: Set<AbstractVertex2D<Vector>>,
|
||||
override val edges: Set<AbstractEdge2D<Vector>>,
|
||||
) : MutablePolytopicConstruction2D.Polygon<Vector, AbstractVertex2D<Vector>, AbstractEdge2D<Vector>> {
|
||||
public val id: Uuid = Uuid.random()
|
||||
|
||||
override fun remove() {
|
||||
construction._polygons.remove(this)
|
||||
}
|
||||
|
||||
override fun toString(): String = "AbstractEdge2D#${id.toHexString()}"
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AbstractEdge2D<*>) return false
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
}
|
||||
|
||||
public class AbstractPolytopicConstruction2D<Vector> : MutablePolytopicConstruction2D<Vector, AbstractVertex2D<Vector>, AbstractEdge2D<Vector>, AbstractPolygon2D<Vector>> {
|
||||
internal val _vertices: MutableSet<AbstractVertex2D<Vector>> = mutableSetOf()
|
||||
override val vertices: Set<AbstractVertex2D<Vector>> get() = _vertices
|
||||
|
||||
internal val _edges: MutableSet<AbstractEdge2D<Vector>> = mutableSetOf()
|
||||
override val edges: Set<AbstractEdge2D<Vector>> get() = _edges
|
||||
|
||||
internal val _polygons: MutableSet<AbstractPolygon2D<Vector>> = mutableSetOf()
|
||||
override val polygons: Set<AbstractPolygon2D<Vector>> get() = _polygons
|
||||
|
||||
override fun addVertex(position: Vector): AbstractVertex2D<Vector> {
|
||||
val vertex = AbstractVertex2D(
|
||||
construction = this,
|
||||
position = position,
|
||||
)
|
||||
_vertices.add(vertex)
|
||||
return vertex
|
||||
}
|
||||
|
||||
override fun addEdge(start: AbstractVertex2D<Vector>, end: AbstractVertex2D<Vector>): AbstractEdge2D<Vector> {
|
||||
val edge = AbstractEdge2D(
|
||||
construction = this,
|
||||
start = start,
|
||||
end = end,
|
||||
)
|
||||
_edges.add(edge)
|
||||
return edge
|
||||
}
|
||||
|
||||
override fun addPolygon(
|
||||
vertices: Set<AbstractVertex2D<Vector>>,
|
||||
edges: Set<AbstractEdge2D<Vector>>
|
||||
): AbstractPolygon2D<Vector> {
|
||||
val polygon = AbstractPolygon2D(
|
||||
construction = this,
|
||||
vertices = vertices,
|
||||
edges = edges,
|
||||
)
|
||||
_polygons.add(polygon)
|
||||
return polygon
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalUuidApi::class)
|
||||
|
||||
package proposals.v2.v1
|
||||
|
||||
import kotlin.uuid.ExperimentalUuidApi
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
|
||||
public class AbstractVertex3D<Vector> internal constructor(
|
||||
private val construction: AbstractPolytopicConstruction3D<Vector>,
|
||||
override val position: Vector
|
||||
) : MutablePolytopicConstruction3D.Vertex<Vector> {
|
||||
public val id: Uuid = Uuid.random()
|
||||
|
||||
override fun remove() {
|
||||
construction._vertices.remove(this)
|
||||
construction._edges.removeAll { this == it.start || this == it.end }
|
||||
construction._polygons.removeAll { this in it.vertices }
|
||||
construction._polyhedra.removeAll { this in it.vertices }
|
||||
}
|
||||
|
||||
override fun toString(): String = "AbstractVertex3D#${id.toHexString()} at $position"
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AbstractVertex3D<*>) return false
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
}
|
||||
|
||||
public class AbstractEdge3D<Vector> internal constructor(
|
||||
private val construction: AbstractPolytopicConstruction3D<Vector>,
|
||||
override val start: AbstractVertex3D<Vector>,
|
||||
override val end: AbstractVertex3D<Vector>,
|
||||
) : MutablePolytopicConstruction3D.Edge<Vector, AbstractVertex3D<Vector>> {
|
||||
public val id: Uuid = Uuid.random()
|
||||
|
||||
override fun remove() {
|
||||
construction._edges.remove(this)
|
||||
construction._polygons.removeAll { this in it.edges }
|
||||
construction._polyhedra.removeAll { this in it.edges }
|
||||
}
|
||||
|
||||
override fun toString(): String = "AbstractEdge3D#${id.toHexString()}"
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AbstractEdge3D<*>) return false
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
}
|
||||
|
||||
public class AbstractPolygon3D<Vector> internal constructor(
|
||||
private val construction: AbstractPolytopicConstruction3D<Vector>,
|
||||
override val vertices: Set<AbstractVertex3D<Vector>>,
|
||||
override val edges: Set<AbstractEdge3D<Vector>>,
|
||||
) : MutablePolytopicConstruction3D.Polygon<Vector, AbstractVertex3D<Vector>, AbstractEdge3D<Vector>> {
|
||||
public val id: Uuid = Uuid.random()
|
||||
|
||||
override fun remove() {
|
||||
construction._polygons.remove(this)
|
||||
construction._polyhedra.removeAll { this in it.faces }
|
||||
}
|
||||
|
||||
override fun toString(): String = "AbstractEdge3D#${id.toHexString()}"
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AbstractEdge3D<*>) return false
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
}
|
||||
|
||||
public class AbstractPolyhedron3D<Vector> internal constructor(
|
||||
private val construction: AbstractPolytopicConstruction3D<Vector>,
|
||||
override val vertices: Set<AbstractVertex3D<Vector>>,
|
||||
override val edges: Set<AbstractEdge3D<Vector>>,
|
||||
override val faces: Set<AbstractPolygon3D<Vector>>,
|
||||
) : MutablePolytopicConstruction3D.Polyhedron<Vector, AbstractVertex3D<Vector>, AbstractEdge3D<Vector>, AbstractPolygon3D<Vector>> {
|
||||
public val id: Uuid = Uuid.random()
|
||||
|
||||
override fun remove() {
|
||||
construction._polyhedra.remove(this)
|
||||
}
|
||||
|
||||
override fun toString(): String = "AbstractEdge3D#${id.toHexString()}"
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AbstractEdge3D<*>) return false
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
}
|
||||
|
||||
public class AbstractPolytopicConstruction3D<Vector> : MutablePolytopicConstruction3D<Vector, AbstractVertex3D<Vector>, AbstractEdge3D<Vector>, AbstractPolygon3D<Vector>, AbstractPolyhedron3D<Vector>> {
|
||||
internal val _vertices: MutableSet<AbstractVertex3D<Vector>> = mutableSetOf()
|
||||
override val vertices: Set<AbstractVertex3D<Vector>> get() = _vertices
|
||||
|
||||
internal val _edges: MutableSet<AbstractEdge3D<Vector>> = mutableSetOf()
|
||||
override val edges: Set<AbstractEdge3D<Vector>> get() = _edges
|
||||
|
||||
internal val _polygons: MutableSet<AbstractPolygon3D<Vector>> = mutableSetOf()
|
||||
override val polygons: Set<AbstractPolygon3D<Vector>> get() = _polygons
|
||||
|
||||
internal val _polyhedra: MutableSet<AbstractPolyhedron3D<Vector>> = mutableSetOf()
|
||||
override val polyhedra: Set<AbstractPolyhedron3D<Vector>> get() = _polyhedra
|
||||
|
||||
override fun addVertex(position: Vector): AbstractVertex3D<Vector> {
|
||||
val vertex = AbstractVertex3D(
|
||||
construction = this,
|
||||
position = position,
|
||||
)
|
||||
_vertices.add(vertex)
|
||||
return vertex
|
||||
}
|
||||
|
||||
override fun addEdge(start: AbstractVertex3D<Vector>, end: AbstractVertex3D<Vector>): AbstractEdge3D<Vector> {
|
||||
val edge = AbstractEdge3D(
|
||||
construction = this,
|
||||
start = start,
|
||||
end = end,
|
||||
)
|
||||
_edges.add(edge)
|
||||
return edge
|
||||
}
|
||||
|
||||
override fun addPolygon(
|
||||
vertices: Set<AbstractVertex3D<Vector>>,
|
||||
edges: Set<AbstractEdge3D<Vector>>
|
||||
): AbstractPolygon3D<Vector> {
|
||||
val polygon = AbstractPolygon3D(
|
||||
construction = this,
|
||||
vertices = vertices,
|
||||
edges = edges,
|
||||
)
|
||||
_polygons.add(polygon)
|
||||
return polygon
|
||||
}
|
||||
|
||||
override fun addPolyhedron(
|
||||
vertices: Set<AbstractVertex3D<Vector>>,
|
||||
edges: Set<AbstractEdge3D<Vector>>,
|
||||
faces: Set<AbstractPolygon3D<Vector>>
|
||||
): AbstractPolyhedron3D<Vector> {
|
||||
val polyhedron = AbstractPolyhedron3D(
|
||||
construction = this,
|
||||
vertices = vertices,
|
||||
edges = edges,
|
||||
faces = faces,
|
||||
)
|
||||
_polyhedra.add(polyhedron)
|
||||
return polyhedron
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v2.v1
|
||||
|
||||
|
||||
public interface PolytopicConstruction<
|
||||
out Vector,
|
||||
out VertexType: PolytopicConstruction.Vertex<Vector, VertexType, PolytopeType>,
|
||||
out PolytopeType: PolytopicConstruction.Polytope<Vector, VertexType, PolytopeType>,
|
||||
> {
|
||||
public val dimension: Int
|
||||
public val vertices: Set<VertexType>
|
||||
public val polytopes: List<Set<PolytopeType>>
|
||||
|
||||
public interface Vertex<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector, VertexType, PolytopeType>,
|
||||
out PolytopeType: Polytope<Vector, VertexType, PolytopeType>,
|
||||
> {
|
||||
public val position: Vector
|
||||
public fun asPolytope(): PolytopeType
|
||||
}
|
||||
|
||||
public interface Polytope<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector, VertexType, PolytopeType>,
|
||||
out PolytopeType: Polytope<Vector, VertexType, PolytopeType>,
|
||||
> {
|
||||
public val dimension: Int
|
||||
public val vertices: Set<VertexType>
|
||||
public val faces: List<Set<PolytopeType>>
|
||||
}
|
||||
}
|
||||
|
||||
public interface MutablePolytopicConstruction<
|
||||
Vector,
|
||||
VertexType: MutablePolytopicConstruction.Vertex<Vector, VertexType, PolytopeType>,
|
||||
PolytopeType: MutablePolytopicConstruction.Polytope<Vector, VertexType, PolytopeType>,
|
||||
> : PolytopicConstruction<Vector, VertexType, PolytopeType> {
|
||||
public fun addVertex(position: Vector): VertexType
|
||||
public fun addPolytope(
|
||||
dimension: Int,
|
||||
vertices: Set<VertexType>,
|
||||
faces: List<Set<PolytopeType>>,
|
||||
): PolytopeType
|
||||
|
||||
public interface Vertex<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector, VertexType, PolytopeType>,
|
||||
out PolytopeType: Polytope<Vector, VertexType, PolytopeType>,
|
||||
> : PolytopicConstruction.Vertex<Vector, VertexType, PolytopeType> {
|
||||
public fun remove()
|
||||
}
|
||||
|
||||
public interface Polytope<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector, VertexType, PolytopeType>,
|
||||
out PolytopeType: Polytope<Vector, VertexType, PolytopeType>,
|
||||
> : PolytopicConstruction.Polytope<Vector, VertexType, PolytopeType> {
|
||||
public fun remove()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v2.v1
|
||||
|
||||
|
||||
public interface PolytopicConstruction2D<
|
||||
out Vector,
|
||||
out VertexType: PolytopicConstruction2D.Vertex<Vector>,
|
||||
out EdgeType: PolytopicConstruction2D.Edge<Vector, VertexType>,
|
||||
out PolygonType: PolytopicConstruction2D.Polygon<Vector, VertexType, EdgeType>,
|
||||
> {
|
||||
public val vertices: Set<VertexType>
|
||||
public val edges: Set<EdgeType>
|
||||
public val polygons: Set<PolygonType>
|
||||
|
||||
public interface Vertex<
|
||||
out Vector,
|
||||
> {
|
||||
public val position: Vector
|
||||
}
|
||||
|
||||
public interface Edge<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector>,
|
||||
> {
|
||||
public val start: VertexType
|
||||
public val end: VertexType
|
||||
}
|
||||
|
||||
public interface Polygon<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector>,
|
||||
out EdgeType: Edge<Vector, VertexType>,
|
||||
> {
|
||||
public val vertices: Set<VertexType>
|
||||
public val edges: Set<EdgeType>
|
||||
}
|
||||
}
|
||||
|
||||
public interface MutablePolytopicConstruction2D<
|
||||
Vector,
|
||||
VertexType: MutablePolytopicConstruction2D.Vertex<Vector>,
|
||||
EdgeType: MutablePolytopicConstruction2D.Edge<Vector, VertexType>,
|
||||
out PolygonType: MutablePolytopicConstruction2D.Polygon<Vector, VertexType, EdgeType>,
|
||||
> : PolytopicConstruction2D<Vector, VertexType, EdgeType, PolygonType> {
|
||||
public fun addVertex(position: Vector): VertexType
|
||||
public fun addEdge(
|
||||
start: VertexType,
|
||||
end: VertexType,
|
||||
): EdgeType
|
||||
public fun addPolygon(
|
||||
vertices: Set<VertexType>,
|
||||
edges: Set<EdgeType>,
|
||||
): PolygonType
|
||||
|
||||
public interface Vertex<
|
||||
out Vector,
|
||||
> : PolytopicConstruction2D.Vertex<Vector> {
|
||||
public fun remove()
|
||||
}
|
||||
|
||||
public interface Edge<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector>,
|
||||
> : PolytopicConstruction2D.Edge<Vector, VertexType> {
|
||||
public fun remove()
|
||||
}
|
||||
|
||||
public interface Polygon<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector>,
|
||||
out EdgeType: Edge<Vector, VertexType>,
|
||||
> : PolytopicConstruction2D.Polygon<Vector, VertexType, EdgeType> {
|
||||
public fun remove()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v2.v1
|
||||
|
||||
|
||||
public interface PolytopicConstruction3D<
|
||||
out Vector,
|
||||
out VertexType: PolytopicConstruction3D.Vertex<Vector>,
|
||||
out EdgeType: PolytopicConstruction3D.Edge<Vector, VertexType>,
|
||||
out PolygonType: PolytopicConstruction3D.Polygon<Vector, VertexType, EdgeType>,
|
||||
out PolyhedronType: PolytopicConstruction3D.Polyhedron<Vector, VertexType, EdgeType, PolygonType>,
|
||||
> {
|
||||
public val vertices: Set<VertexType>
|
||||
public val edges: Set<EdgeType>
|
||||
public val polygons: Set<PolygonType>
|
||||
public val polyhedra: Set<PolyhedronType>
|
||||
|
||||
public interface Vertex<
|
||||
out Vector,
|
||||
> {
|
||||
public val position: Vector
|
||||
}
|
||||
|
||||
public interface Edge<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector>,
|
||||
> {
|
||||
public val start: VertexType
|
||||
public val end: VertexType
|
||||
}
|
||||
|
||||
public interface Polygon<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector>,
|
||||
out EdgeType: Edge<Vector, VertexType>,
|
||||
> {
|
||||
public val vertices: Set<VertexType>
|
||||
public val edges: Set<EdgeType>
|
||||
}
|
||||
|
||||
public interface Polyhedron<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector>,
|
||||
out EdgeType: Edge<Vector, VertexType>,
|
||||
out PolygonType: Polygon<Vector, VertexType, EdgeType>,
|
||||
> {
|
||||
public val vertices: Set<VertexType>
|
||||
public val edges: Set<EdgeType>
|
||||
public val faces: Set<PolygonType>
|
||||
}
|
||||
}
|
||||
|
||||
public interface MutablePolytopicConstruction3D<
|
||||
Vector,
|
||||
VertexType: MutablePolytopicConstruction3D.Vertex<Vector>,
|
||||
EdgeType: MutablePolytopicConstruction3D.Edge<Vector, VertexType>,
|
||||
PolygonType: MutablePolytopicConstruction3D.Polygon<Vector, VertexType, EdgeType>,
|
||||
out PolyhedronType: MutablePolytopicConstruction3D.Polyhedron<Vector, VertexType, EdgeType, PolygonType>,
|
||||
> : PolytopicConstruction3D<Vector, VertexType, EdgeType, PolygonType, PolyhedronType> {
|
||||
public fun addVertex(position: Vector): VertexType
|
||||
public fun addEdge(
|
||||
start: VertexType,
|
||||
end: VertexType,
|
||||
): EdgeType
|
||||
public fun addPolygon(
|
||||
vertices: Set<VertexType>,
|
||||
edges: Set<EdgeType>,
|
||||
): PolygonType
|
||||
public fun addPolyhedron(
|
||||
vertices: Set<VertexType>,
|
||||
edges: Set<EdgeType>,
|
||||
faces: Set<PolygonType>,
|
||||
): PolyhedronType
|
||||
|
||||
public interface Vertex<
|
||||
out Vector,
|
||||
> : PolytopicConstruction3D.Vertex<Vector> {
|
||||
public fun remove()
|
||||
}
|
||||
|
||||
public interface Edge<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector>,
|
||||
> : PolytopicConstruction3D.Edge<Vector, VertexType> {
|
||||
public fun remove()
|
||||
}
|
||||
|
||||
public interface Polygon<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector>,
|
||||
out EdgeType: Edge<Vector, VertexType>,
|
||||
> : PolytopicConstruction3D.Polygon<Vector, VertexType, EdgeType> {
|
||||
public fun remove()
|
||||
}
|
||||
|
||||
public interface Polyhedron<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector>,
|
||||
out EdgeType: Edge<Vector, VertexType>,
|
||||
out PolygonType: Polygon<Vector, VertexType, EdgeType>,
|
||||
> : PolytopicConstruction3D.Polyhedron<Vector, VertexType, EdgeType, PolygonType> {
|
||||
public fun remove()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v2.v1
|
||||
|
||||
import space.kscience.kmath.geometry.GeometrySpace
|
||||
import space.kscience.kmath.geometry.projectAlong
|
||||
|
||||
|
||||
public fun <
|
||||
V: Any,
|
||||
PVertex : PolytopicConstruction.Vertex<V, PVertex, PPolytope>,
|
||||
PPolytope : PolytopicConstruction.Polytope<V, PVertex, PPolytope>,
|
||||
TVertex : MutablePolytopicConstruction.Vertex<V, TVertex, TPolytope>,
|
||||
TPolytope : MutablePolytopicConstruction.Polytope<V, TVertex, TPolytope>
|
||||
> GeometrySpace<V, *>.projectAlong(
|
||||
projectedPolytopicConstruction: PolytopicConstruction<V, PVertex, PPolytope>,
|
||||
targetPolytopicConstruction: MutablePolytopicConstruction<V, TVertex, TPolytope>,
|
||||
normal: V,
|
||||
base: V,
|
||||
) {
|
||||
require(targetPolytopicConstruction.dimension >= projectedPolytopicConstruction.dimension - 1)
|
||||
with(targetPolytopicConstruction) {
|
||||
val newVertices: Map<PVertex, TVertex> = projectedPolytopicConstruction.vertices.associateWith { vertex ->
|
||||
addVertex(projectAlong(vertex.position, normal, base))
|
||||
}
|
||||
val newPolytopes: MutableList<Map<PPolytope, TPolytope>> =
|
||||
mutableListOf(
|
||||
buildMap {
|
||||
for ((pVertex, tVertex) in newVertices) put(pVertex.asPolytope(), tVertex.asPolytope())
|
||||
}
|
||||
)
|
||||
for (dim in 1 ..< projectedPolytopicConstruction.dimension)
|
||||
newPolytopes += buildMap {
|
||||
for (pPolytope in projectedPolytopicConstruction.polytopes[dim]) {
|
||||
val tVertices = pPolytope.vertices.mapTo(mutableSetOf()) { newVertices[it]!! }
|
||||
val tFaces: MutableList<Set<TPolytope>> = mutableListOf()
|
||||
for (subdim in 0 ..< dim)
|
||||
tFaces += pPolytope.faces[subdim].mapTo(mutableSetOf()) { newPolytopes[subdim][it]!! }
|
||||
put(
|
||||
pPolytope,
|
||||
addPolytope(
|
||||
dimension = dim,
|
||||
vertices = tVertices,
|
||||
faces = tFaces,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun <
|
||||
V: Any,
|
||||
PVertex : PolytopicConstruction3D.Vertex<V>,
|
||||
PEdge : PolytopicConstruction3D.Edge<V, PVertex>,
|
||||
PPolygon : PolytopicConstruction3D.Polygon<V, PVertex, PEdge>,
|
||||
> GeometrySpace<V, *>.projectAlongToAbstractPolytopicConstruction2D(
|
||||
polytopicConstruction3D: PolytopicConstruction3D<V, PVertex, PEdge, PPolygon, *>,
|
||||
normal: V,
|
||||
base: V,
|
||||
): AbstractPolytopicConstruction2D<V> = AbstractPolytopicConstruction2D<V>().apply {
|
||||
val newVertices = polytopicConstruction3D.vertices.associateWith { vertex ->
|
||||
addVertex(projectAlong(vertex.position, normal, base))
|
||||
}
|
||||
val newEdges = polytopicConstruction3D.edges.associateWith { edge ->
|
||||
addEdge(newVertices[edge.start]!!, newVertices[edge.end]!!)
|
||||
}
|
||||
polytopicConstruction3D.polygons.forEach { polygon ->
|
||||
addPolygon(
|
||||
vertices = polygon.vertices.mapTo(mutableSetOf()) { newVertices[it]!! },
|
||||
edges = polygon.edges.mapTo(mutableSetOf()) { newEdges[it]!! }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
public fun <
|
||||
Vector: Any,
|
||||
VertexType: PolytopicConstruction.Vertex<Vector, VertexType, *>
|
||||
> GeometrySpace<Vector, *>.nearestVertexOfTo(
|
||||
polytopicConstruction: PolytopicConstruction<Vector, VertexType, *>,
|
||||
point: Vector,
|
||||
): VertexType =
|
||||
polytopicConstruction.vertices.minBy { it.position.distanceTo(point) }
|
||||
|
||||
public fun <
|
||||
Vector: Any,
|
||||
VertexType: MutablePolytopicConstruction.Vertex<Vector, VertexType, *>
|
||||
> GeometrySpace<Vector, *>.removeNearestVertexOfTo(
|
||||
polytopicConstruction: MutablePolytopicConstruction<Vector, VertexType, *>,
|
||||
point: Vector,
|
||||
) {
|
||||
nearestVertexOfTo(polytopicConstruction, point).remove()
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v2.v2
|
||||
|
||||
import kotlin.experimental.ExperimentalTypeInference
|
||||
|
||||
|
||||
public interface PolytopicConstruction<out V> {
|
||||
public val dimension: Int
|
||||
|
||||
public val vertices: Set<Vertex<V>>
|
||||
public val polytopes: List<Set<Polytope<V>>>
|
||||
|
||||
public interface Vertex<out V> {
|
||||
public val position: V
|
||||
public fun asPolytope(): Polytope<V>
|
||||
}
|
||||
|
||||
public interface Polytope<out V> {
|
||||
public val dimension: Int
|
||||
public val vertices: Set<Vertex<V>>
|
||||
public val faces: List<Set<Polytope<V>>>
|
||||
}
|
||||
}
|
||||
|
||||
public interface MutablePolytopicConstruction<V> : PolytopicConstruction<V> {
|
||||
override val vertices: Set<Vertex<V>>
|
||||
override val polytopes: List<Set<Polytope<V>>>
|
||||
|
||||
public fun addVertex(position: V): Vertex<V>
|
||||
public fun addPolytope(dimension: Int, vertices: Set<Vertex<V>>, faces: List<Set<Polytope<V>>>): Polytope<V>
|
||||
|
||||
public interface Vertex<V> : PolytopicConstruction.Vertex<V> {
|
||||
override fun asPolytope(): Polytope<V>
|
||||
|
||||
public fun remove()
|
||||
}
|
||||
|
||||
public interface Polytope<V> : PolytopicConstruction.Polytope<V> {
|
||||
override val vertices: Set<Vertex<V>>
|
||||
override val faces: List<Set<Polytope<V>>>
|
||||
|
||||
public fun remove()
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTypeInference::class)
|
||||
public inline fun <V> PolytopicConstruction(
|
||||
dimension: Int,
|
||||
@BuilderInference block: MutablePolytopicConstruction<V>.() -> Unit
|
||||
): PolytopicConstruction<V> =
|
||||
MutablePolytopicConstructionImpl<V>(dimension).apply(block)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@PublishedApi
|
||||
internal class MutablePolytopicConstructionImpl<V> @PublishedApi internal constructor(
|
||||
override val dimension: Int,
|
||||
): MutablePolytopicConstruction<V> {
|
||||
override val vertices: MutableSet<Vertex<V>> = mutableSetOf()
|
||||
override val polytopes: List<MutableSet<Polytope<V>>> = List(dimension + 1) { mutableSetOf() }
|
||||
|
||||
override fun addVertex(position: V): Vertex<V> {
|
||||
val vertex = Vertex(
|
||||
construction = this,
|
||||
position = position,
|
||||
)
|
||||
vertices.add(vertex)
|
||||
polytopes[0].add(vertex.correspondingPolytope)
|
||||
return vertex
|
||||
}
|
||||
|
||||
override fun addPolytope(
|
||||
dimension: Int,
|
||||
vertices: Set<MutablePolytopicConstruction.Vertex<V>>,
|
||||
faces: List<Set<MutablePolytopicConstruction.Polytope<V>>>
|
||||
): Polytope<V> {
|
||||
check(dimension > 0)
|
||||
check(vertices.all { it is Vertex<V> } && faces.all { dimFaces -> dimFaces.all { it is Polytope<V> } })
|
||||
val polytope = Polytope(
|
||||
construction = this,
|
||||
correspondingVertex = null,
|
||||
dimension = dimension,
|
||||
vertices = vertices as Set<Vertex<V>>,
|
||||
faces = faces as List<Set<Polytope<V>>>,
|
||||
)
|
||||
polytopes[dimension].add(polytope)
|
||||
return polytope
|
||||
}
|
||||
|
||||
class Vertex<V>(
|
||||
val construction: MutablePolytopicConstructionImpl<V>,
|
||||
override val position: V,
|
||||
) : MutablePolytopicConstruction.Vertex<V> {
|
||||
val correspondingPolytope: Polytope<V> =
|
||||
Polytope(
|
||||
construction = construction,
|
||||
correspondingVertex = this,
|
||||
dimension = 0,
|
||||
vertices = setOf(this),
|
||||
faces = emptyList(),
|
||||
)
|
||||
override fun asPolytope(): MutablePolytopicConstruction.Polytope<V> = correspondingPolytope
|
||||
override fun remove() {
|
||||
construction.polytopes.forEach { dimPolytopes -> dimPolytopes.removeAll { this in it.vertices } }
|
||||
construction.vertices.remove(this)
|
||||
}
|
||||
}
|
||||
|
||||
class Polytope<V>(
|
||||
val construction: MutablePolytopicConstructionImpl<V>,
|
||||
val correspondingVertex: Vertex<V>?,
|
||||
override val dimension: Int,
|
||||
override val vertices: Set<Vertex<V>>,
|
||||
override val faces: List<Set<Polytope<V>>>,
|
||||
) : MutablePolytopicConstruction.Polytope<V> {
|
||||
override fun remove() {
|
||||
construction.polytopes.drop(dimension + 1).forEach { dimPolytopes -> dimPolytopes.removeAll { this in it.faces[dimension] } }
|
||||
construction.polytopes[dimension].remove(this)
|
||||
correspondingVertex?.also { construction.vertices.remove(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v2.v2
|
||||
|
||||
import kotlin.experimental.ExperimentalTypeInference
|
||||
|
||||
|
||||
public interface PolytopicConstruction2D<out V> {
|
||||
public val vertices: Set<Vertex<V>>
|
||||
public val edges: Set<Edge<V>>
|
||||
public val polygons: Set<Polygon<V>>
|
||||
|
||||
public interface Vertex<out V> {
|
||||
public val position: V
|
||||
}
|
||||
|
||||
public interface Edge<out V> {
|
||||
public val start: Vertex<V>
|
||||
public val end: Vertex<V>
|
||||
}
|
||||
|
||||
public interface Polygon<out V> {
|
||||
public val vertices: Set<Vertex<V>>
|
||||
public val edges: Set<Edge<V>>
|
||||
}
|
||||
}
|
||||
|
||||
public interface MutablePolytopicConstruction2D<V> : PolytopicConstruction2D<V> {
|
||||
override val vertices: Set<Vertex<V>>
|
||||
override val edges: Set<Edge<V>>
|
||||
override val polygons: Set<Polygon<V>>
|
||||
|
||||
public fun addVertex(position: V): Vertex<V>
|
||||
public fun addEdge(start: Vertex<V>, end: Vertex<V>): Edge<V>
|
||||
public fun addPolygon(vertices: Set<Vertex<V>>, edges: Set<Edge<V>>): Polygon<V>
|
||||
|
||||
public interface Vertex<V> : PolytopicConstruction2D.Vertex<V> {
|
||||
public fun remove()
|
||||
}
|
||||
|
||||
public interface Edge<V> : PolytopicConstruction2D.Edge<V> {
|
||||
override val start: Vertex<V>
|
||||
override val end: Vertex<V>
|
||||
|
||||
public fun remove()
|
||||
}
|
||||
|
||||
public interface Polygon<V> : PolytopicConstruction2D.Polygon<V> {
|
||||
override val vertices: Set<Vertex<V>>
|
||||
override val edges: Set<Edge<V>>
|
||||
|
||||
public fun remove()
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTypeInference::class)
|
||||
public inline fun <V> PolytopicConstruction2D(@BuilderInference block: MutablePolytopicConstruction2D<V>.() -> Unit): PolytopicConstruction2D<V> =
|
||||
MutablePolytopicConstruction2DImpl<V>().apply(block)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@PublishedApi
|
||||
internal class MutablePolytopicConstruction2DImpl<V> : MutablePolytopicConstruction2D<V> {
|
||||
override val vertices: MutableSet<Vertex<V>> = mutableSetOf()
|
||||
override val edges: MutableSet<Edge<V>> = mutableSetOf()
|
||||
override val polygons: MutableSet<Polygon<V>> = mutableSetOf()
|
||||
|
||||
override fun addVertex(position: V): Vertex<V> =
|
||||
Vertex(this, position).also { vertices.add(it) }
|
||||
|
||||
override fun addEdge(
|
||||
start: MutablePolytopicConstruction2D.Vertex<V>,
|
||||
end: MutablePolytopicConstruction2D.Vertex<V>
|
||||
): Edge<V> {
|
||||
check(start is Vertex<V> && start.construction === this && end is Vertex<V> && end.construction === this) { "Cannot add edge to polytopic construction with vertices not from the construction" }
|
||||
val edge = Edge(this, start, end)
|
||||
edges.add(edge)
|
||||
return edge
|
||||
}
|
||||
|
||||
override fun addPolygon(
|
||||
vertices: Set<MutablePolytopicConstruction2D.Vertex<V>>,
|
||||
edges: Set<MutablePolytopicConstruction2D.Edge<V>>
|
||||
): MutablePolytopicConstruction2D.Polygon<V> {
|
||||
check(vertices.all { it is Vertex<V> && it.construction === this } && edges.all { it is Edge<V> && it.construction === this })
|
||||
val polygon = Polygon(this, vertices as Set<Vertex<V>>, edges as Set<Edge<V>>)
|
||||
polygons.add(polygon)
|
||||
return polygon
|
||||
}
|
||||
|
||||
class Vertex<V>(
|
||||
val construction: MutablePolytopicConstruction2DImpl<V>,
|
||||
override val position: V,
|
||||
) : MutablePolytopicConstruction2D.Vertex<V> {
|
||||
val usedInEdges: MutableSet<Edge<V>> = mutableSetOf()
|
||||
val usedInPolygons: MutableSet<Polygon<V>> = mutableSetOf()
|
||||
|
||||
override fun remove() {
|
||||
construction.vertices.remove(this)
|
||||
construction.edges.removeAll { it in usedInEdges }
|
||||
construction.polygons.removeAll { it in usedInPolygons }
|
||||
}
|
||||
}
|
||||
|
||||
class Edge<V>(
|
||||
val construction: MutablePolytopicConstruction2DImpl<V>,
|
||||
override val start: Vertex<V>,
|
||||
override val end: Vertex<V>,
|
||||
) : MutablePolytopicConstruction2D.Edge<V> {
|
||||
val usedInPolygons: MutableSet<Polygon<V>> = mutableSetOf()
|
||||
|
||||
override fun remove() {
|
||||
construction.edges.remove(this)
|
||||
construction.polygons.removeAll { it in usedInPolygons }
|
||||
}
|
||||
}
|
||||
|
||||
class Polygon<V>(
|
||||
val construction: MutablePolytopicConstruction2DImpl<V>,
|
||||
override val vertices: Set<Vertex<V>>,
|
||||
override val edges: Set<Edge<V>>,
|
||||
) : MutablePolytopicConstruction2D.Polygon<V> {
|
||||
|
||||
override fun remove() {
|
||||
construction.polygons.remove(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v2.v2
|
||||
|
||||
import kotlin.experimental.ExperimentalTypeInference
|
||||
|
||||
|
||||
public interface PolytopicConstruction3D<out V> {
|
||||
public val vertices: Set<Vertex<V>>
|
||||
public val edges: Set<Edge<V>>
|
||||
public val polygons: Set<Polygon<V>>
|
||||
public val polyhedra: Set<Polyhedron<V>>
|
||||
|
||||
public interface Vertex<out V> {
|
||||
public val position: V
|
||||
}
|
||||
|
||||
public interface Edge<out V> {
|
||||
public val start: Vertex<V>
|
||||
public val end: Vertex<V>
|
||||
}
|
||||
|
||||
public interface Polygon<out V> {
|
||||
public val vertices: Set<Vertex<V>>
|
||||
public val edges: Set<Edge<V>>
|
||||
}
|
||||
|
||||
public interface Polyhedron<out V> {
|
||||
public val vertices: Set<Vertex<V>>
|
||||
public val edges: Set<Edge<V>>
|
||||
public val faces: Set<Polygon<V>>
|
||||
}
|
||||
}
|
||||
|
||||
public interface MutablePolytopicConstruction3D<V> : PolytopicConstruction3D<V> {
|
||||
override val vertices: Set<Vertex<V>>
|
||||
override val edges: Set<Edge<V>>
|
||||
override val polygons: Set<Polygon<V>>
|
||||
override val polyhedra: Set<Polyhedron<V>>
|
||||
|
||||
public fun addVertex(position: V): Vertex<V>
|
||||
public fun addEdge(start: Vertex<V>, end: Vertex<V>): Edge<V>
|
||||
public fun addPolygon(vertices: Set<Vertex<V>>, edges: Set<Edge<V>>): Polygon<V>
|
||||
public fun addPolyhedron(vertices: Set<Vertex<V>>, edges: Set<Edge<V>>, faces: Set<Polygon<V>>): Polyhedron<V>
|
||||
|
||||
public interface Vertex<V> : PolytopicConstruction3D.Vertex<V> {
|
||||
public fun remove()
|
||||
}
|
||||
|
||||
public interface Edge<V> : PolytopicConstruction3D.Edge<V> {
|
||||
override val start: Vertex<V>
|
||||
override val end: Vertex<V>
|
||||
|
||||
public fun remove()
|
||||
}
|
||||
|
||||
public interface Polygon<V> : PolytopicConstruction3D.Polygon<V> {
|
||||
override val vertices: Set<Vertex<V>>
|
||||
override val edges: Set<Edge<V>>
|
||||
|
||||
public fun remove()
|
||||
}
|
||||
|
||||
public interface Polyhedron<V> : PolytopicConstruction3D.Polyhedron<V> {
|
||||
override val vertices: Set<Vertex<V>>
|
||||
override val edges: Set<Edge<V>>
|
||||
override val faces: Set<Polygon<V>>
|
||||
|
||||
public fun remove()
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTypeInference::class)
|
||||
public inline fun <V> PolytopicConstruction3D(@BuilderInference block: MutablePolytopicConstruction3D<V>.() -> Unit): PolytopicConstruction3D<V> =
|
||||
MutablePolytopicConstruction3DImpl<V>().apply(block)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@PublishedApi
|
||||
internal class MutablePolytopicConstruction3DImpl<V> : MutablePolytopicConstruction3D<V> {
|
||||
override val vertices: MutableSet<Vertex<V>> = mutableSetOf()
|
||||
override val edges: MutableSet<Edge<V>> = mutableSetOf()
|
||||
override val polygons: MutableSet<Polygon<V>> = mutableSetOf()
|
||||
override val polyhedra: MutableSet<Polyhedron<V>> = mutableSetOf()
|
||||
|
||||
override fun addVertex(position: V): Vertex<V> =
|
||||
Vertex(this, position).also { vertices.add(it) }
|
||||
|
||||
override fun addEdge(
|
||||
start: MutablePolytopicConstruction3D.Vertex<V>,
|
||||
end: MutablePolytopicConstruction3D.Vertex<V>
|
||||
): Edge<V> {
|
||||
check(start is Vertex<V> && start.construction === this && end is Vertex<V> && end.construction === this) { "Cannot add edge to polytopic construction with vertices not from the construction" }
|
||||
val edge = Edge(this, start, end)
|
||||
edges.add(edge)
|
||||
return edge
|
||||
}
|
||||
|
||||
override fun addPolygon(
|
||||
vertices: Set<MutablePolytopicConstruction3D.Vertex<V>>,
|
||||
edges: Set<MutablePolytopicConstruction3D.Edge<V>>
|
||||
): MutablePolytopicConstruction3D.Polygon<V> {
|
||||
check(vertices.all { it is Vertex<V> && it.construction === this } && edges.all { it is Edge<V> && it.construction === this })
|
||||
val polygon = Polygon(this, vertices as Set<Vertex<V>>, edges as Set<Edge<V>>)
|
||||
polygons.add(polygon)
|
||||
return polygon
|
||||
}
|
||||
|
||||
override fun addPolyhedron(
|
||||
vertices: Set<MutablePolytopicConstruction3D.Vertex<V>>,
|
||||
edges: Set<MutablePolytopicConstruction3D.Edge<V>>,
|
||||
faces: Set<MutablePolytopicConstruction3D.Polygon<V>>
|
||||
): MutablePolytopicConstruction3D.Polyhedron<V> {
|
||||
check(vertices.all { it is Vertex<V> && it.construction === this } && edges.all { it is Edge<V> && it.construction === this } && faces.all { it is Polygon<V> && it.construction === this })
|
||||
val polyhedron = Polyhedron(this, vertices as Set<Vertex<V>>, edges as Set<Edge<V>>, faces as Set<Polygon<V>>)
|
||||
polyhedra.add(polyhedron)
|
||||
return polyhedron
|
||||
}
|
||||
|
||||
class Vertex<V>(
|
||||
val construction: MutablePolytopicConstruction3DImpl<V>,
|
||||
override val position: V,
|
||||
) : MutablePolytopicConstruction3D.Vertex<V> {
|
||||
val usedInEdges: MutableSet<Edge<V>> = mutableSetOf()
|
||||
val usedInPolygons: MutableSet<Polygon<V>> = mutableSetOf()
|
||||
val usedInPolyhedra: MutableSet<Polyhedron<V>> = mutableSetOf()
|
||||
|
||||
override fun remove() {
|
||||
construction.vertices.remove(this)
|
||||
construction.edges.removeAll { it in usedInEdges }
|
||||
construction.polygons.removeAll { it in usedInPolygons }
|
||||
construction.polyhedra.removeAll { it in usedInPolyhedra }
|
||||
}
|
||||
}
|
||||
|
||||
class Edge<V>(
|
||||
val construction: MutablePolytopicConstruction3DImpl<V>,
|
||||
override val start: Vertex<V>,
|
||||
override val end: Vertex<V>
|
||||
) : MutablePolytopicConstruction3D.Edge<V> {
|
||||
val usedInPolygons: MutableSet<Polygon<V>> = mutableSetOf()
|
||||
val usedInPolyhedra: MutableSet<Polyhedron<V>> = mutableSetOf()
|
||||
|
||||
override fun remove() {
|
||||
construction.edges.remove(this)
|
||||
construction.polygons.removeAll { it in usedInPolygons }
|
||||
construction.polyhedra.removeAll { it in usedInPolyhedra }
|
||||
}
|
||||
}
|
||||
|
||||
class Polygon<V>(
|
||||
val construction: MutablePolytopicConstruction3DImpl<V>,
|
||||
override val vertices: Set<Vertex<V>>,
|
||||
override val edges: Set<Edge<V>>,
|
||||
) : MutablePolytopicConstruction3D.Polygon<V> {
|
||||
val usedInPolyhedra: MutableSet<Polyhedron<V>> = mutableSetOf()
|
||||
|
||||
override fun remove() {
|
||||
construction.polygons.remove(this)
|
||||
construction.polyhedra.removeAll { it in usedInPolyhedra }
|
||||
}
|
||||
}
|
||||
|
||||
class Polyhedron<V>(
|
||||
val construction: MutablePolytopicConstruction3DImpl<V>,
|
||||
override val vertices: Set<Vertex<V>>,
|
||||
override val edges: Set<Edge<V>>,
|
||||
override val faces: Set<Polygon<V>>,
|
||||
) : MutablePolytopicConstruction3D.Polyhedron<V> {
|
||||
override fun remove() {
|
||||
construction.polyhedra.remove(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v2.v2
|
||||
|
||||
import space.kscience.kmath.geometry.GeometrySpace
|
||||
import space.kscience.kmath.geometry.projectAlong
|
||||
|
||||
|
||||
public fun <V: Any> GeometrySpace<V, *>.projectAlong(
|
||||
projectedPolytopicConstruction: PolytopicConstruction<V>,
|
||||
targetPolytopicConstruction: MutablePolytopicConstruction<V>,
|
||||
normal: V,
|
||||
base: V,
|
||||
) {
|
||||
require(targetPolytopicConstruction.dimension >= projectedPolytopicConstruction.dimension - 1)
|
||||
with(targetPolytopicConstruction) {
|
||||
val newVertices: Map<PolytopicConstruction.Vertex<V>, MutablePolytopicConstruction.Vertex<V>> =
|
||||
projectedPolytopicConstruction.vertices.associateWith { vertex ->
|
||||
addVertex(projectAlong(vertex.position, normal, base))
|
||||
}
|
||||
val newPolytopes: MutableList<Map<PolytopicConstruction.Polytope<V>, MutablePolytopicConstruction.Polytope<V>>> =
|
||||
mutableListOf(
|
||||
buildMap {
|
||||
for ((pVertex, tVertex) in newVertices) put(pVertex.asPolytope(), tVertex.asPolytope())
|
||||
}
|
||||
)
|
||||
for (dim in 1 ..< projectedPolytopicConstruction.dimension)
|
||||
newPolytopes += buildMap {
|
||||
for (pPolytope in projectedPolytopicConstruction.polytopes[dim]) {
|
||||
val tVertices = pPolytope.vertices.mapTo(mutableSetOf()) { newVertices[it]!! }
|
||||
val tFaces: MutableList<Set<MutablePolytopicConstruction.Polytope<V>>> = mutableListOf()
|
||||
for (subdim in 0 ..< dim)
|
||||
tFaces += pPolytope.faces[subdim].mapTo(mutableSetOf()) { newPolytopes[subdim][it]!! }
|
||||
put(
|
||||
pPolytope,
|
||||
addPolytope(
|
||||
dimension = dim,
|
||||
vertices = tVertices,
|
||||
faces = tFaces,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun <V: Any> GeometrySpace<V, *>.projectAlong(
|
||||
polytopicConstruction3D: PolytopicConstruction3D<V>,
|
||||
normal: V,
|
||||
base: V,
|
||||
): PolytopicConstruction2D<V> = PolytopicConstruction2D {
|
||||
val newVertices = polytopicConstruction3D.vertices.associateWith { vertex ->
|
||||
addVertex(projectAlong(vertex.position, normal, base))
|
||||
}
|
||||
val newEdges = polytopicConstruction3D.edges.associateWith { edge ->
|
||||
addEdge(newVertices[edge.start]!!, newVertices[edge.end]!!)
|
||||
}
|
||||
polytopicConstruction3D.polygons.forEach { polygon ->
|
||||
addPolygon(
|
||||
vertices = polygon.vertices.mapTo(mutableSetOf()) { newVertices[it]!! },
|
||||
edges = polygon.edges.mapTo(mutableSetOf()) { newEdges[it]!! }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v3.v1
|
||||
|
||||
|
||||
public interface Vertex<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector, VertexType, PolytopeType>,
|
||||
out PolytopeType: Polytope<Vector, VertexType, PolytopeType>
|
||||
> {
|
||||
public val position: Vector
|
||||
|
||||
public fun asPolytope(): PolytopeType
|
||||
}
|
||||
|
||||
public interface Polytope<
|
||||
out Vector,
|
||||
out VertexType: Vertex<Vector, VertexType, PolytopeType>,
|
||||
out PolytopeType: Polytope<Vector, VertexType, PolytopeType>
|
||||
> {
|
||||
public val dimension: Int
|
||||
public val vertices: Set<VertexType>
|
||||
public val faces: List<Set<PolytopeType>>
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v3.v1
|
||||
|
||||
|
||||
public interface Vertex2D<
|
||||
Vector
|
||||
> {
|
||||
public val position: Vector
|
||||
}
|
||||
|
||||
public interface Edge2D<
|
||||
Vector,
|
||||
VertexType: Vertex2D<Vector>,
|
||||
> {
|
||||
public val start: VertexType
|
||||
public val end: VertexType
|
||||
}
|
||||
|
||||
public interface Polygon2D<
|
||||
Vector,
|
||||
VertexType: Vertex2D<Vector>,
|
||||
EdgeType: Edge2D<Vector, VertexType>
|
||||
> {
|
||||
public val vertices: Set<VertexType>
|
||||
public val edges: Set<EdgeType>
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v3.v1
|
||||
|
||||
|
||||
public interface Vertex3D<
|
||||
Vector
|
||||
> {
|
||||
public val position: Vector
|
||||
}
|
||||
|
||||
public interface Edge3D<
|
||||
Vector,
|
||||
VertexType: Vertex3D<Vector>,
|
||||
> {
|
||||
public val start: VertexType
|
||||
public val end: VertexType
|
||||
}
|
||||
|
||||
public interface Polygon3D<
|
||||
Vector,
|
||||
VertexType: Vertex3D<Vector>,
|
||||
EdgeType: Edge3D<Vector, VertexType>
|
||||
> {
|
||||
public val vertices: Set<VertexType>
|
||||
public val edges: Set<EdgeType>
|
||||
}
|
||||
|
||||
public interface Polyhedron3D<
|
||||
Vector,
|
||||
VertexType: Vertex3D<Vector>,
|
||||
EdgeType: Edge3D<Vector, VertexType>,
|
||||
PolygonType: Polygon3D<Vector, VertexType, EdgeType>,
|
||||
> {
|
||||
public val vertices: Set<VertexType>
|
||||
public val edges: Set<EdgeType>
|
||||
public val faces: Set<PolygonType>
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v3.v1
|
||||
|
||||
import space.kscience.kmath.geometry.GeometrySpace
|
||||
|
||||
|
||||
public fun <
|
||||
Vector: Any,
|
||||
VertexType: Vertex<Vector, VertexType, *>
|
||||
> GeometrySpace<Vector, *>.nearestVertexOfTo(
|
||||
polytopeVertices: Collection<VertexType>,
|
||||
point: Vector,
|
||||
): VertexType =
|
||||
polytopeVertices.minBy { it.position.distanceTo(point) }
|
||||
|
||||
//public fun <
|
||||
// Vector: Any,
|
||||
// VertexType: Vertex<Vector, VertexType, *>
|
||||
//> GeometrySpace<Vector, *>.removeNearestVertexOfTo(
|
||||
// polytopeVertices: Collection<VertexType>,
|
||||
// point: Vector,
|
||||
//) {
|
||||
// nearestVertexOfTo(polytopeVertices, point).remove()
|
||||
//}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v3.v2
|
||||
|
||||
|
||||
public interface Vertex<Vector> {
|
||||
public val position: Vector
|
||||
|
||||
public fun asPolytope(): Polytope<Vector>
|
||||
}
|
||||
|
||||
public interface Polytope<Vector> {
|
||||
public val dimension: Int
|
||||
public val vertices: Set<Vertex<Vector>>
|
||||
public val faces: List<Set<Polytope<Vector>>>
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v3.v2
|
||||
|
||||
|
||||
public interface Vertex2D<out Vector> {
|
||||
public val position: Vector
|
||||
}
|
||||
|
||||
public interface Edge2D<out Vector> {
|
||||
public val start: Vertex2D<Vector>
|
||||
public val end: Vertex2D<Vector>
|
||||
}
|
||||
|
||||
public interface Polygon2D<out Vector> {
|
||||
public val vertices: Set<Vertex2D<Vector>>
|
||||
public val edges: Set<Vertex2D<Vector>>
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v3.v2
|
||||
|
||||
|
||||
public interface Vertex3D<out Vector> {
|
||||
public val position: Vector
|
||||
}
|
||||
|
||||
public interface Edge3D<out Vector> {
|
||||
public val start: Vertex3D<Vector>
|
||||
public val end: Vertex3D<Vector>
|
||||
}
|
||||
|
||||
public interface Polygon3D<out Vector> {
|
||||
public val vertices: Set<Vertex3D<Vector>>
|
||||
public val edges: Set<Edge3D<Vector>>
|
||||
}
|
||||
|
||||
public interface Polyhedron3D<out Vector> {
|
||||
public val vertices: Set<Vertex3D<Vector>>
|
||||
public val edges: Set<Edge3D<Vector>>
|
||||
public val faces: Set<Polygon3D<Vector>>
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v3.v2
|
||||
|
||||
import space.kscience.kmath.geometry.GeometrySpace
|
||||
|
||||
|
||||
public fun <
|
||||
Vector: Any,
|
||||
VertexType: Vertex<Vector>
|
||||
> GeometrySpace<Vector, *>.nearestVertexOfTo(
|
||||
polytopeVertices: Collection<VertexType>,
|
||||
point: Vector,
|
||||
): VertexType =
|
||||
polytopeVertices.minBy { it.position.distanceTo(point) }
|
||||
|
||||
//public fun <
|
||||
// Vector: Any,
|
||||
// VertexType: Vertex<Vector, VertexType, *>
|
||||
//> GeometrySpace<Vector, *>.removeNearestVertexOfTo(
|
||||
// polytopeVertices: Collection<VertexType>,
|
||||
// point: Vector,
|
||||
//) {
|
||||
// nearestVertexOfTo(polytopeVertices, point).remove()
|
||||
//}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v4
|
||||
|
||||
|
||||
public interface Polytope<Vector> {
|
||||
public val dimension: Int
|
||||
public val vertices: Set<Vertex<Vector>>
|
||||
public val faces: List<Set<Polytope<Vector>>>
|
||||
}
|
||||
|
||||
public interface Vertex<Vector> : Polytope<Vector> {
|
||||
public val position: Vector
|
||||
|
||||
override val dimension: Int get() = 0
|
||||
override val vertices: Set<Vertex<Vector>> get() = setOf(this)
|
||||
override val faces: List<Set<Polytope<Vector>>> get() = emptyList()
|
||||
}
|
||||
|
||||
public interface Edge<Vector> : Polytope<Vector> {
|
||||
public val start: Vertex<Vector>
|
||||
public val end: Vertex<Vector>
|
||||
|
||||
override val dimension: Int get() = 1
|
||||
override val vertices: Set<Vertex<Vector>> get() = setOf(start, end)
|
||||
override val faces: List<Set<Polytope<Vector>>> get() = listOf(vertices)
|
||||
}
|
||||
|
||||
public interface Polygon<Vector> : Polytope<Vector> {
|
||||
public val edges: Set<Edge<Vector>>
|
||||
|
||||
override val dimension: Int get() = 2
|
||||
override val faces: List<Set<Polytope<Vector>>> get() = listOf(vertices, edges)
|
||||
}
|
||||
|
||||
public interface Polyhedron<Vector> : Polytope<Vector> {
|
||||
public val edges: Set<Edge<Vector>>
|
||||
public val polygons: Set<Polygon<Vector>>
|
||||
|
||||
override val dimension: Int get() = 3
|
||||
override val faces: List<Set<Polytope<Vector>>> get() = listOf(vertices, edges, polygons)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v5
|
||||
|
||||
|
||||
public interface PolytopicConstruction<Vector, Vertex, Polytope> {
|
||||
public val dimension: Int
|
||||
public val polytopes: List<Set<Polytope>>
|
||||
public val vertices: Set<Vertex>
|
||||
|
||||
public val Vertex.position: Vector
|
||||
public fun Vertex.asPolytope(): Polytope
|
||||
|
||||
public val Polytope.dimension: Int
|
||||
public val Polytope.faces: List<Set<Polytope>>
|
||||
public val Polytope.vertices: Set<Vertex>
|
||||
}
|
||||
|
||||
public interface MutablePolytopicConstruction<Vector, Vertex, Polytope> : PolytopicConstruction<Vector, Vertex, Polytope> {
|
||||
public fun Vertex.bind(position: Vector, correspondingPolytope: Polytope)
|
||||
public fun Polytope.bind(
|
||||
dimension: Int,
|
||||
vertices: Set<Vertex>,
|
||||
faces: List<Set<Polytope>>,
|
||||
)
|
||||
public fun Vertex.unbind()
|
||||
public fun Polytope.unbind()
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v5
|
||||
|
||||
|
||||
public interface PolytopicConstruction2D<Vector, Vertex, Edge, Polygon> {
|
||||
public val vertices: Set<Vertex>
|
||||
public val edges: Set<Edge>
|
||||
public val polygons: Set<Polygon>
|
||||
|
||||
public val Vertex.position: Vector
|
||||
|
||||
public val Edge.start: Vertex
|
||||
public val Edge.end: Vertex
|
||||
|
||||
public val Polygon.vertices: Set<Vertex>
|
||||
public val Polygon.edges: Set<Edge>
|
||||
}
|
||||
|
||||
public interface MutablePolytopicConstruction2D<Vector, Vertex, Edge, Polygon> : PolytopicConstruction2D<Vector, Vertex, Edge, Polygon> {
|
||||
public fun Vertex.bind(position: Vector)
|
||||
public fun Edge.bind(start: Vertex, end: Vertex)
|
||||
public fun Polygon.bind(vertices: Set<Vertex>, edges: Set<Edge>)
|
||||
|
||||
public fun Vertex.remove()
|
||||
public fun Edge.remove()
|
||||
public fun Polygon.remove()
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v5
|
||||
|
||||
|
||||
public interface PolytopicConstruction3D<Vector, Vertex, Edge, Polygon, Polyhedron> {
|
||||
public val vertices: Set<Vertex>
|
||||
public val edges: Set<Edge>
|
||||
public val polygons: Set<Polygon>
|
||||
public val polyhedra: Set<Polyhedron>
|
||||
|
||||
public val Vertex.position: Vector
|
||||
|
||||
public val Edge.start: Vertex
|
||||
public val Edge.end: Vertex
|
||||
|
||||
public val Polygon.vertices: Set<Vertex>
|
||||
public val Polygon.edges: Set<Edge>
|
||||
|
||||
public val Polyhedron.vertices: Set<Vertex>
|
||||
public val Polyhedron.edges: Set<Edge>
|
||||
public val Polyhedron.faces: Set<Polygon>
|
||||
}
|
||||
|
||||
public interface MutablePolytopicConstruction3D<Vector, Vertex, Edge, Polygon, Polyhedron> : PolytopicConstruction3D<Vector, Vertex, Edge, Polygon, Polyhedron> {
|
||||
public fun addVertex(position: Vector): Vertex
|
||||
public fun addEdge(start: Vertex, end: Vertex): Edge
|
||||
public fun addPolygon(vertices: Set<Vertex>, edges: Set<Edge>): Polygon
|
||||
public fun addPolyhedron(vertices: Set<Vertex>, edges: Set<Edge>, faces: Set<Polygon>): Polyhedron
|
||||
|
||||
public fun Vertex.remove()
|
||||
public fun Edge.remove()
|
||||
public fun Polygon.remove()
|
||||
public fun Polyhedron.remove()
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v5
|
||||
|
||||
import space.kscience.kmath.geometry.GeometrySpace
|
||||
import space.kscience.kmath.geometry.projectAlong
|
||||
|
||||
|
||||
public fun <V: Any, Vertex, Polytope> GeometrySpace<V, *>.projectAlong(
|
||||
projectedPolytopicConstruction: PolytopicConstruction<V, Vertex, Polytope>,
|
||||
targetPolytopicConstruction: MutablePolytopicConstruction<V, Vertex, Polytope>,
|
||||
normal: V,
|
||||
base: V,
|
||||
) {
|
||||
require(targetPolytopicConstruction.dimension >= projectedPolytopicConstruction.dimension - 1)
|
||||
projectedPolytopicConstruction.vertices.forEach { vertex ->
|
||||
val correspondingPolytope = with(projectedPolytopicConstruction) { vertex.asPolytope() }
|
||||
with(targetPolytopicConstruction) { vertex.bind(projectAlong(vertex.position, normal, base), correspondingPolytope) }
|
||||
}
|
||||
for (dim in 1 ..< projectedPolytopicConstruction.dimension)
|
||||
for (polytope in projectedPolytopicConstruction.polytopes[dim]) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val vertices = with(projectedPolytopicConstruction) { polytope.vertices }
|
||||
val faces = with(projectedPolytopicConstruction) { polytope.faces }
|
||||
with(targetPolytopicConstruction) { polytope.bind(dim, vertices, faces) }
|
||||
}
|
||||
}
|
||||
|
||||
public fun <
|
||||
Vector: Any,
|
||||
Vertex
|
||||
> GeometrySpace<Vector, *>.nearestVertexOfTo(
|
||||
polytopicConstruction: PolytopicConstruction<Vector, Vertex, *>,
|
||||
point: Vector,
|
||||
): Vertex =
|
||||
with(polytopicConstruction) { vertices.minBy { it.position.distanceTo(point) } }
|
||||
|
||||
public fun <
|
||||
Vector: Any,
|
||||
Vertex,
|
||||
> GeometrySpace<Vector, *>.removeNearestVertexOfTo(
|
||||
polytopicConstruction: MutablePolytopicConstruction<Vector, Vertex, *>,
|
||||
point: Vector,
|
||||
) {
|
||||
val vertexToRemove = nearestVertexOfTo(polytopicConstruction, point)
|
||||
with(polytopicConstruction) { vertexToRemove.unbind() }
|
||||
}
|
||||
@@ -7,7 +7,7 @@ package space.kscience.kmath.geometry
|
||||
|
||||
import space.kscience.kmath.linear.Point
|
||||
|
||||
public interface Vector2D<T> : Point<T> {
|
||||
public interface Vector2D<out T> : Point<T> {
|
||||
public val x: T
|
||||
public val y: T
|
||||
override val size: Int get() = 2
|
||||
|
||||
@@ -8,7 +8,7 @@ package space.kscience.kmath.geometry
|
||||
import space.kscience.kmath.linear.Point
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
|
||||
public interface Vector3D<T> : Point<T> {
|
||||
public interface Vector3D<out T> : Point<T> {
|
||||
public val x: T
|
||||
public val y: T
|
||||
public val z: T
|
||||
|
||||
@@ -24,4 +24,4 @@ public fun <V : Any> GeometrySpace<V, *>.projectToLine(vector: V, line: Line<V>)
|
||||
* @param base point belonging to a hyper-plane to which vector should be projected
|
||||
*/
|
||||
public fun <V : Any> GeometrySpace<V, *>.projectAlong(vector: V, normal: V, base: V): V =
|
||||
vector + normal * ((base - vector) dot normal) / (normal dot normal)
|
||||
vector + normal * ((base - vector) dot normal) / (normal dot normal)
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2018-2025 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 proposals.v1
|
||||
|
||||
import kotlin.test.Test
|
||||
|
||||
|
||||
class Applications {
|
||||
@Test
|
||||
fun projectAlong() {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user