Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
commonMain.ru.casperix.math.intersection.int32.Intersection2Int.kt Maven / Gradle / Ivy
package ru.casperix.math.intersection.int32
import ru.casperix.math.axis_aligned.int32.Box2i
import ru.casperix.math.geometry.float64.Geometry2Double
import ru.casperix.math.geometry.float64.Geometry2Double.distPointToLine
import ru.casperix.math.geometry.*
import ru.casperix.math.intersection.ConvexHullIntersection
import ru.casperix.math.intersection.IntersectionApi
import ru.casperix.math.intersection.float64.Intersection2Double
import ru.casperix.math.vector.float64.Vector2d
import ru.casperix.math.vector.int32.Vector2i
import ru.casperix.misc.toDoubleArray
import kotlin.math.absoluteValue
object Intersection2Int : IntersectionApi {
fun hasBoxWithBox(A: Box2i, B: Box2i): Boolean {
if (A.max.y - B.min.y < 0) return false
if (B.max.y - A.min.y < 0) return false
if (A.max.x - B.min.x < 0) return false
if (B.max.x - A.min.x < 0) return false
return true
}
override fun hasPointWithTriangle(P: Vector2i, triangle: Triangle2i): Boolean {
// Compute vectors
val v0 = triangle.v2 - triangle.v0
val v1 = triangle.v1 - triangle.v0
val v2 = P - triangle.v0
// Compute dot products
val dot00 = v0.dot(v0)
val dot01 = v0.dot(v1)
val dot02 = v0.dot(v2)
val dot11 = v1.dot(v1)
val dot12 = v1.dot(v2)
// Compute barycentric coordinates
val invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01)
val u = (dot11 * dot02 - dot01 * dot12) * invDenom
val v = (dot00 * dot12 - dot01 * dot02) * invDenom
// Check if point is in triangle
return (u >= 0) && (v >= 0) && (u + v <= 1.0)
}
override fun hasPointWithPolygon(P: Vector2i, polygon: Polygon): Boolean {
val vertices = polygon.getVertices()
if (vertices.isEmpty()) return false
if (vertices.size == 1) return P == vertices[0]
if (vertices.size == 2) return hasPointWithLine(P, vertices[0], vertices[1])
repeat(polygon.getTriangleAmount()) { index ->
if (hasPointWithTriangle(P, polygon.getTriangle(index))) return true
}
return false
}
override fun hasTriangleWithTriangle(a: Triangle2i, b: Triangle2i): Boolean {
val listA = intArrayOf(a.v0.x, a.v0.y, a.v1.x, a.v1.y, a.v2.x, a.v2.y).toDoubleArray()
val listB = intArrayOf(b.v0.x, b.v0.y, b.v1.x, b.v1.y, b.v2.x, b.v2.y).toDoubleArray()
return ConvexHullIntersection.hasIntersection(listA, listA.size, listB, listB.size)
}
override fun hasQuadWithQuad(a: Quad2i, b: Quad2i): Boolean {
val listA = intArrayOf(a.v0.x, a.v0.y, a.v1.x, a.v1.y, a.v2.x, a.v2.y, a.v3.x, a.v3.y).toDoubleArray()
val listB = intArrayOf(b.v0.x, b.v0.y, b.v1.x, b.v1.y, b.v2.x, b.v2.y, b.v3.x, b.v3.y).toDoubleArray()
return ConvexHullIntersection.hasIntersection(listA, listA.size, listB, listB.size)
}
override fun hasQuadWithTriangle(a: Quad2i, b: Triangle2i): Boolean {
val listA = intArrayOf(b.v0.x, b.v0.y, b.v1.x, b.v1.y, b.v2.x, b.v2.y).toDoubleArray()
val listB = intArrayOf(a.v0.x, a.v0.y, a.v1.x, a.v1.y, a.v2.x, a.v2.y, a.v3.x, a.v3.y).toDoubleArray()
return ConvexHullIntersection.hasIntersection(listA, listA.size, listB, listB.size)
}
override fun hasPointWithLine(P: Vector2i, T: Line2i): Boolean {
val T2 = T.convert { it.toVector2d() }
val P2 = P.toVector2d()
return distPointToLine(P2, T2) < Intersection2Double.EPSILON
&& (P2.distTo(T2.v0) + P2.distTo(T2.v1) - T2.v0.distTo(T2.v1)).absoluteValue < Intersection2Double.EPSILON
}
override fun hasPointWithSegment(P: Vector2i, T: Line2i): Boolean {
return Geometry2Double.distPointToSegment(P.toVector2d(), T.convert { it.toVector2d() }) < Intersection2Double.EPSILON
}
override fun getSegmentWithSegment(S: Line2i, T: Line2i): Vector2i? {
return intersectSegments(S.v0.x, S.v0.y, S.v1.x, S.v1.y, T.v0.x, T.v0.y, T.v1.x, T.v1.y)
}
override fun getLineWithLine(S: Line2i, T: Line2i): Vector2i? {
return Intersection2Double.getLineWithLine(S.convert { it.toVector2d() }, T.convert { it.toVector2d() })?.roundToVector2i()
}
fun pointWithQuadEdge(P: Vector2i, polygon: Quad2i): Boolean {
return pointWithAbstractPolygon(P, polygon)
}
fun pointWithTriangleEdge(P: Vector2i, polygon: Triangle2i): Boolean {
return pointWithAbstractPolygon(P, polygon)
}
fun pointWithPolygonEdge(P: Vector2i, polygon: Polygon2i): Boolean {
return pointWithAbstractPolygon(P, polygon)
}
private fun pointWithAbstractPolygon(P: Vector2i, quad: Polygon): Boolean {
quad.getEdgeList().forEach { edge ->
if (hasPointWithSegment(P, edge)) return true
}
return false
}
private fun intersectSegments(
x1: Int, y1: Int, x2: Int, y2: Int, x3: Int, y3: Int, x4: Int, y4: Int
): Vector2i? {
val d = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
if (d == 0) return null
val yd = y1 - y3
val xd = x1 - x3
val ua = ((x4 - x3) * yd - (y4 - y3) * xd) / d.toDouble()
if (ua < 0 || ua > 1) return null
val ub = ((x2 - x1) * yd - (y2 - y1) * xd) / d.toDouble()
if (ub < 0 || ub > 1) return null
return Vector2d(x1 + (x2 - x1) * ua, y1 + (y2 - y1) * ua).roundToVector2i()
}
}