Ray-casting algorithm: Difference between revisions
Content added Content deleted
(Added Wren) |
|||
Line 2,250: | Line 2,250: | ||
rand = Int(Rnd(0)*(hiNum-loNum+1)+loNum) |
rand = Int(Rnd(0)*(hiNum-loNum+1)+loNum) |
||
End Function </lang> |
End Function </lang> |
||
=={{header|Nim}}== |
|||
{{trans|D}} |
|||
<lang Nim>import fenv, sequtils, strformat |
|||
type |
|||
Point = tuple[x, y: float] |
|||
Edge = tuple[a, b: Point] |
|||
Figure = tuple[name: string; edges: seq[Edge]] |
|||
func contains(poly: Figure; p: Point): bool = |
|||
func raySegI(p: Point; edge: Edge): bool = |
|||
const Epsilon = 0.00001 |
|||
if edge.a.y > edge.b.y: |
|||
# Swap "a" and "b". |
|||
return p.raySegI((edge.b, edge.a)) |
|||
if p.y == edge.a.y or p.y == edge.b.y: |
|||
# p.y += Epsilon. |
|||
return (p.x, p.y + Epsilon).raySegI(edge) |
|||
if p.y > edge.b.y or p.y < edge.a.y or p.x > max(edge.a.x, edge.b.x): |
|||
return false |
|||
if p.x < min(edge.a.x, edge.b.x): |
|||
return true |
|||
let blue = if abs(edge.a.x - p.x) > minimumPositiveValue(float): |
|||
(p.y - edge.a.y) / (p.x - edge.a.x) |
|||
else: |
|||
maximumPositiveValue(float) |
|||
let red = if abs(edge.a.x - edge.b.x) > minimumPositiveValue(float): |
|||
(edge.b.y - edge.a.y) / (edge.b.x - edge.a.x) |
|||
else: |
|||
maximumPositiveValue(float) |
|||
result = blue >= red |
|||
result = (poly.edges.filterIt(p.raySegI(it)).len and 1) != 0 |
|||
when isMainModule: |
|||
const |
|||
Polys: array[4, Figure] = |
|||
[("Square", |
|||
@[(( 0.0, 0.0), (10.0, 0.0)), ((10.0, 0.0), (10.0, 10.0)), |
|||
((10.0, 10.0), ( 0.0, 10.0)), (( 0.0, 10.0), ( 0.0, 0.0))]), |
|||
("Square hole", |
|||
@[(( 0.0, 0.0), (10.0, 0.0)), ((10.0, 0.0), (10.0, 10.0)), |
|||
((10.0, 10.0), ( 0.0, 10.0)), (( 0.0, 10.0), ( 0.0, 0.0)), |
|||
(( 2.5, 2.5), ( 7.5, 2.5)), (( 7.5, 2.5), ( 7.5, 7.5)), |
|||
(( 7.5, 7.5), ( 2.5, 7.5)), (( 2.5, 7.5), ( 2.5, 2.5))]), |
|||
("Strange", |
|||
@[(( 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))]), |
|||
("Hexagon", |
|||
@[(( 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))]) |
|||
] |
|||
TestPoints: array[7, Point] = |
|||
[(5.0, 5.0), (5.0, 8.0), (-10.0, 5.0), (0.0, 5.0), (10.0, 5.0), (8.0, 5.0), (10.0, 10.0)] |
|||
for poly in Polys: |
|||
echo &"Is point inside figure {poly.name}?" |
|||
for p in TestPoints: |
|||
echo &" ({p.x:3},{p.y:3}): {poly.contains(p)}"</lang> |
|||
{{out}} |
|||
<pre>Is point inside figure Square? |
|||
( 5, 5): true |
|||
( 5, 8): true |
|||
(-10, 5): false |
|||
( 0, 5): false |
|||
( 10, 5): true |
|||
( 8, 5): true |
|||
( 10, 10): false |
|||
Is point inside figure Square hole? |
|||
( 5, 5): false |
|||
( 5, 8): true |
|||
(-10, 5): false |
|||
( 0, 5): false |
|||
( 10, 5): true |
|||
( 8, 5): true |
|||
( 10, 10): false |
|||
Is point inside figure Strange? |
|||
( 5, 5): true |
|||
( 5, 8): false |
|||
(-10, 5): false |
|||
( 0, 5): false |
|||
( 10, 5): true |
|||
( 8, 5): true |
|||
( 10, 10): false |
|||
Is point inside figure Hexagon? |
|||
( 5, 5): true |
|||
( 5, 8): true |
|||
(-10, 5): false |
|||
( 0, 5): false |
|||
( 10, 5): true |
|||
( 8, 5): true |
|||
( 10, 10): false</pre> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |