Created
December 22, 2017 23:00
-
-
Save Grissess/8fd12737f2a09bda82160c0b9e3eb0e9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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