Ray-casting algorithm: Difference between revisions

Added Julia language
m (→‎{{header|Racket}}: Switched Racket to Scheme syntax highlighting since it's close enough and better than nothing.)
(Added Julia language)
Line 1,920:
}
</lang>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
'''Module''':
<lang julia>module RayCastings
 
export Point
 
struct Point{T}
x::T
y::T
end
Base.show(io::IO, p::Point) = print(io, "($(p.x), $(p.y))")
 
const Edge = Tuple{Point{T}, Point{T}} where T
Base.show(io::IO, e::Edge) = print(io, "$(e[1]) ∘-∘ $(e[2])")
 
function rayintersectseg(p::Point{T}, edge::Edge{T}) where T
a, b = edge
if a.y > b.y
a, b = b, a
end
if p.y ∈ (a.y, b.y)
p = Point(p.x, p.y + eps(p.y))
end
 
rst = false
if (p.y > b.y || p.y < a.y) || (p.x > max(a.x, b.x))
return false
end
 
if p.x < min(a.x, b.x)
rst = true
else
mred = (b.y - a.y) / (b.x - a.x)
mblu = (p.y - a.y) / (p.x - a.x)
rst = mblu ≥ mred
end
 
return rst
end
 
isinside(poly::Vector{Tuple{Point{T}, Point{T}}}, p::Point{T}) where T =
isodd(count(edge -> rayintersectseg(p, edge), poly))
 
connect(a::Point{T}, b::Point{T}...) where T =
[(a, b) for (a, b) in zip(vcat(a, b...), vcat(b..., a))]
 
end # module RayCastings</lang>
 
'''Main''':
<lang julia>let A = Point(0.0, 0.0),
B = Point(0.0, 10.0),
C = Point(10.0, 10.0),
D = Point(10.0, 0.0),
E = Point(2.5, 2.5),
F = Point(2.5, 7.5),
G = Point(7.5, 7.5),
H = Point(7.5, 2.5),
I = Point(3.0, 0.0),
J = Point(7.0, 0.0),
K = Point(10.0, 5.0),
L = Point(7.0, 10.0),
M = Point(3.0, 10.0),
N = Point(0.0, 5.0),
testpts = (Point(5.0, 5.0), Point(5.0, 8.0), Point(-10.0, 5.0), Point(0.0, 5.0),
Point(10.0, 5.0), Point(8.0, 5.0), Point(10.0, 10.0))
 
square = RayCastings.connect(A, B, C, D)
square_withhole = vcat(square, RayCastings.connect(E, F, G, H))
strange = RayCastings.connect(A, E, B, F, G, C, D, E)
exagon = RayCastings.connect(I, J, K, L, M, N)
 
println("\n# TESTING WHETHER POINTS ARE WITHIN POLYGONS")
for poly in (square, square_withhole, strange, exagon)
println("\nEdges: \n - ", join(poly, "\n - "))
println("Inside/outside:")
for p in testpts
@printf(" - %-12s is %s\n", p, RayCastings.isinside(poly, p) ? "inside" : "outside")
end
end
end</lang>
 
{{out}}
<pre># TESTING WHETHER POINTS ARE WITHIN POLYGONS
 
Edges:
- (0.0, 0.0) ∘-∘ (0.0, 10.0)
- (0.0, 10.0) ∘-∘ (10.0, 10.0)
- (10.0, 10.0) ∘-∘ (10.0, 0.0)
- (10.0, 0.0) ∘-∘ (0.0, 0.0)
Inside/outside:
- (5.0, 5.0) is inside
- (5.0, 8.0) is inside
- (-10.0, 5.0) is outside
- (0.0, 5.0) is outside
- (10.0, 5.0) is inside
- (8.0, 5.0) is inside
- (10.0, 10.0) is outside
 
Edges:
- (0.0, 0.0) ∘-∘ (0.0, 10.0)
- (0.0, 10.0) ∘-∘ (10.0, 10.0)
- (10.0, 10.0) ∘-∘ (10.0, 0.0)
- (10.0, 0.0) ∘-∘ (0.0, 0.0)
- (2.5, 2.5) ∘-∘ (2.5, 7.5)
- (2.5, 7.5) ∘-∘ (7.5, 7.5)
- (7.5, 7.5) ∘-∘ (7.5, 2.5)
- (7.5, 2.5) ∘-∘ (2.5, 2.5)
Inside/outside:
- (5.0, 5.0) is outside
- (5.0, 8.0) is inside
- (-10.0, 5.0) is outside
- (0.0, 5.0) is outside
- (10.0, 5.0) is inside
- (8.0, 5.0) is inside
- (10.0, 10.0) is outside
 
Edges:
- (0.0, 0.0) ∘-∘ (2.5, 2.5)
- (2.5, 2.5) ∘-∘ (0.0, 10.0)
- (0.0, 10.0) ∘-∘ (2.5, 7.5)
- (2.5, 7.5) ∘-∘ (7.5, 7.5)
- (7.5, 7.5) ∘-∘ (10.0, 10.0)
- (10.0, 10.0) ∘-∘ (10.0, 0.0)
- (10.0, 0.0) ∘-∘ (2.5, 2.5)
- (2.5, 2.5) ∘-∘ (0.0, 0.0)
Inside/outside:
- (5.0, 5.0) is inside
- (5.0, 8.0) is outside
- (-10.0, 5.0) is outside
- (0.0, 5.0) is outside
- (10.0, 5.0) is inside
- (8.0, 5.0) is inside
- (10.0, 10.0) is outside
 
Edges:
- (3.0, 0.0) ∘-∘ (7.0, 0.0)
- (7.0, 0.0) ∘-∘ (10.0, 5.0)
- (10.0, 5.0) ∘-∘ (7.0, 10.0)
- (7.0, 10.0) ∘-∘ (3.0, 10.0)
- (3.0, 10.0) ∘-∘ (0.0, 5.0)
- (0.0, 5.0) ∘-∘ (3.0, 0.0)
Inside/outside:
- (5.0, 5.0) is inside
- (5.0, 8.0) is inside
- (-10.0, 5.0) is outside
- (0.0, 5.0) is outside
- (10.0, 5.0) is inside
- (8.0, 5.0) is inside
- (10.0, 10.0) is outside</pre>
 
=={{header|Kotlin}}==
Anonymous user