39 lines
1.3 KiB
Plaintext
39 lines
1.3 KiB
Plaintext
import "/fmt" for Fmt
|
|
|
|
class RayCasting {
|
|
static intersects(a, b, p) {
|
|
if (a[1] > b[1]) return intersects(b, a, p)
|
|
if (p[1] == a[1] || p[1] == b[1]) p[1] = p[1] + 0.0001
|
|
if (p[1] > b[1] || p[1] < a[1] || p[0] >= a[0].max(b[0])) return false
|
|
if (p[0] < a[0].min(b[0])) return true
|
|
var red = (p[1] - a[1]) / (p[0] - a[0])
|
|
var blue = (b[1] - a[1]) / (b[0] - a[0])
|
|
return red >= blue
|
|
}
|
|
|
|
static contains(shape, pnt) {
|
|
var inside = false
|
|
var len = shape.count
|
|
for (i in 0...len) {
|
|
if (intersects(shape[i], shape[(i + 1) % len], pnt)) inside = !inside
|
|
}
|
|
return inside
|
|
}
|
|
|
|
static square { [[0, 0], [20, 0], [20, 20], [0, 20]] }
|
|
|
|
static squareHole { [[0, 0], [20, 0], [20, 20], [0, 20], [5, 5], [15, 5], [15, 15], [5, 15]] }
|
|
|
|
static strange { [[0, 0], [5, 5], [0, 20], [5, 15], [15, 15], [20, 20], [20, 0]] }
|
|
|
|
static hexagon { [[6, 0], [14, 0], [20, 10], [14, 20], [6, 20], [0, 10]] }
|
|
|
|
static shapes { [square, squareHole, strange, hexagon] }
|
|
}
|
|
|
|
var testPoints = [[10, 10], [10, 16], [-20, 10], [0, 10], [20, 10], [16, 10], [20, 20]]
|
|
for (shape in RayCasting.shapes) {
|
|
for (pnt in testPoints) Fmt.write("$7s ", RayCasting.contains(shape, pnt))
|
|
System.print()
|
|
}
|