io.data2viz.voronoi.Circle.kt Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2018-2019. data2viz sàrl.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package io.data2viz.voronoi
import kotlin.math.sqrt
internal var firstCircle: RedBlackNode? = null
internal val circles = RedBlackTree()
internal val circlePool = mutableListOf>()
class Circle {
var x: Double = .0
var y: Double = .0
var cy: Double = .0
lateinit var site: Site
var arcNode: RedBlackNode? = null
}
var RedBlackNode.x: Double
get() = node.x
set(value) {node.x = value}
var RedBlackNode.y: Double
get() = node.y
set(value) {node.y = value}
var RedBlackNode.cy: Double
get() = node.cy
set(value) {node.cy = value}
var RedBlackNode.site: Site
get() = node.site
set(value) {node.site = value}
fun attachCircle(arcNode: RedBlackNode) {
val lArc = arcNode.P
val rArc = arcNode.N
if (lArc == null || rArc == null) return
val lSite = lArc.site
val cSite = arcNode.site
val rSite = rArc.site
if (lSite === rSite) return
val bx = cSite.x
val by = cSite.y
val ax = lSite.x - bx
val ay = lSite.y - by
val cx = rSite.x - bx
val cy = rSite.y - by
val d = 2 * (ax * cy - ay * cx)
if (d >= -epsilon2) return
val ha = ax * ax + ay * ay
val hc = cx * cx + cy * cy
val x = (cy * ha - ay * hc) / d
val y = (ax * hc - cx * ha) / d
val circle = if (circlePool.isEmpty()) Circle().redBlackNode() else circlePool.pop()!!
circle.node.arcNode= arcNode
circle.site = cSite
circle.x = x + bx
circle.cy = y + by
circle.y = y + by + sqrt(x * x + y * y) // y bottom
arcNode.node.circleNode = circle
var before: RedBlackNode? = null
var node = circles.root
while (node != null) {
if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) {
if (node.L != null) node = node.L
else {
before = node.P; break; }
} else {
if (node.R != null) node = node.R
else {
before = node; break; }
}
}
circles.insert(circle, before)
if (before == null)
firstCircle = circle
}
fun detachCircle(arcNode: RedBlackNode) {
val circle = arcNode.node.circleNode
if (circle != null) {
if (circle.P == null) {
firstCircle = circle.N
}
circles.remove(circle)
circle.clean()
circlePool.add(circle)
arcNode.node.circleNode = null
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy