Skip to content

Instantly share code, notes, and snippets.

@Grissess
Created December 22, 2017 23:00
Show Gist options
  • Save Grissess/8fd12737f2a09bda82160c0b9e3eb0e9 to your computer and use it in GitHub Desktop.
Save Grissess/8fd12737f2a09bda82160c0b9e3eb0e9 to your computer and use it in GitHub Desktop.
package mods.eln.misc
import java.time.Year
data class Vec3f(var x: Double, var y: Double, var z: Double) {
val ZERO = Vec3f(0.0, 0.0, 0.0)
val ONE = Vec3f(1.0, 1.0, 1.0)
val AXIS_X = Vec3f(1.0, 0.0, 0.0)
val AXIS_Y = Vec3f(0.0, 1.0, 0.0)
val AXIS_Z = Vec3f(0.0, 0.0, 1.0)
val AXES = arrayOf(AXIS_X, AXIS_Y, AXIS_Z)
constructor(c: Coordonate) : this(c.x.toDouble(), c.y.toDouble(), c.z.toDouble())
fun toCoordonate(dim: Int = 0) = Coordonate(x.toInt(), y.toInt(), z.toInt(), dim)
fun dot(other: Vec3f) = x * other.x + y * other.y + z * other.z
fun negate(): Vec3f = Vec3f(-x, -y, -z)
operator fun unaryMinus() = negate()
fun reciprocal(): Vec3f = Vec3f(1/x, 1/y, 1/z)
fun add(other: Vec3f) = Vec3f(x + other.x, y + other.y, z + other.z)
fun add(other: Double) = Vec3f(x + other, y + other, z + other)
operator fun plus(other: Vec3f) = add(other)
operator fun plus(other: Double) = add(other)
fun sub(other: Vec3f) = add(other.negate())
fun sub(other: Double) = add(-other)
operator fun minus(other: Vec3f) = sub(other)
operator fun minus(other: Double) = sub(other)
fun mul(other: Vec3f) = Vec3f(x * other.x, y * other.y, z * other.z)
fun mul(other: Double) = Vec3f(x * other, y * other, z * other)
operator fun times(other: Vec3f) = mul(other)
operator fun times(other: Double) = mul(other)
operator fun div(other: Vec3f) = mul(other.reciprocal())
operator fun div(other: Double) = mul(1/other)
fun magSquared() = dot(this)
fun mag() = Math.sqrt(magSquared())
fun isZero() = magSquared() == 0.0
fun distanceTo(other: Vec3f) = sub(other).mag()
fun normalized() = if(isZero()) Vec3f(0.0, 0.0, 0.0) else div(mag())
}
data class Line3f(var origin: Vec3f, var vector: Vec3f) {
fun pointAt(u: Double) = origin.add(vector.mul(u))
fun midpoint() = pointAt(0.5)
fun opposite() = pointAt(1.0)
fun allIntersectionsAlongU(): List<Double> {
var isctus = ArrayList<Double>()
for(axis in Vec3f::AXES) {
val kor = Math.floor(origin.dot(axis)).toLong()
val kop = Math.floor(opposite().dot(axis)).toLong()
for(k in (Math.min(kor, kop) - 1) .. (Math.max(kor, kop) + 1)) {
val u = Plane3f(axis, axis.mul(k))
if(u === null || u < 0.0 || u > 1.0) continue
isctus.add(u)
}
}
isctus.sort()
return isctus
}
fun allIntersectionsAlong() = allIntersectionsAlongU().map {u -> pointAt(u)}
fun allSegmentsAlong(): List<Line3f> {
var segs = ArrayList<Line3f>()
val initSeq = ArrayList<Vec3f>()
initSeq.add(origin)
val iscts = allIntersectionsAlong()
for((a, b) in (initSeq.asSequence() + iscts.asSequence()).zip(iscts.asSequence() + opposite())) {
segs.add(Line3f(a, b.sub(a)))
}
return segs
}
fun allMidpointsAlong() = allSegmentsAlong().map {seg -> seg.midpoint()}
fun allCoordonatesAlong(dim: Int = 0) = allMidpointsAlong().map {pt -> pt.toCoordonate(dim)}
}
data class Plane3f(var normal: Vec3f, var offset: Double) {
init {
normal = normal.normalized()
}
val PLANE_X = Plane3f(Vec3f::AXIS_X, 0.0)
val PLANE_Y = Plane3f(Vec3f::AXIS_Y, 0.0)
val PLANE_Z = Plane3f(Vec3f::AXIS_Z, 0.0)
val AXIS_PLANES = arrayOf(PLANE_X, PLANE_Y, PLANE_Z)
constructor(normal: Vec3f, point: Vec3f) : this(normal, -normal.dot(point))
fun pointOn() = normal.mul(-offset)
fun isctLineU(ln: Line3f): Double? {
val d = ln.vector.dot(normal)
if(d == 0.0) return null
val p0 = pointOn()
return p0.sub(ln.origin).dot(normal) / d
}
fun isctLine(ln: Line3f): Vec3f? {
val u = isctLineU(ln)
if(u === null) return null
return ln.pointAt(u)
}
fun isctSegment(seg: Line3f): Vec3f? {
val u = isctLineU(seg)
if(u === null || u < 0.0 || u > 1.0) return null
return seg.pointAt(u)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment