循环依赖(Voronoi Halfedge)

我知道,“循环依赖是一个糟糕的设计”,但我认为在这种情况下是有保证的。

在构建voronoi图时,单元划分为所谓的“半边”,这使您可以方便地遍历图。

无论如何,为了实例化一个半边,我必须指定半边的镜子,或者双胞胎。

这是任何语言的时髦,但在Kotlin更令人讨厌,因为我不得不使用val而不是val,如我所愿。

现在我正在做这个我不喜欢的funkiness,

val mirrorEdge: HalfEdge get() = halfEdge!! private var halfEdge: HalfEdge? = null fun setMirror(halfEdge: HalfEdge) { this.halfEdge = halfEdge } 

//别处

 newEdge.setMirror(newEdge2) newEdge2.setMirror(newEdge) 

半角镜像不能为空,应该是不变的,但是我不知道如何在代码中传达这个意图。

没有看到HalfEdge的完整定义,这可能不起作用,但考虑以下几点:

 interface HalfEdge { val mirrorHalf: HalfEdge } class HalfEdges { private inner class First : HalfEdge { override val mirrorHalf: HalfEdge get() = second } private inner class Second : HalfEdge { override val mirrorHalf: HalfEdge get() = first } val first: HalfEdge = First() val second: HalfEdge = Second() operator fun component1() = first operator fun component2() = second } 

用法:

 val (newEdge, newEdge2) = HalfEdges() check(newEdge == newEdge2.mirrorHalf) check(newEdge.mirrorHalf == newEdge2) 

您必须同时创建两个半边,虽然您可能永远不会直接引用它,但两个边都保持对整个边容器的引用,以便它们可以互相访问。 上面的实现可以很容易地适用于将数据传递给两个半边和/或将数据与整个边相关联。

同样的原理也可以用一个父“Graph”或“Network”类来实现,该类有一个内部的双向映射,其边界相互镜像。