Anonymous user
Ray-casting algorithm: Difference between revisions
→{{header|REXX}}: changed/added comments and whitespace, changed indentations, used smaller value for the epsilon value.
m (→{{header|Kotlin}}: fix trans template) |
(→{{header|REXX}}: changed/added comments and whitespace, changed indentations, used smaller value for the epsilon value.) |
||
Line 2,775:
Over half of the REXX program is devoted to specifying/defining/assigning the points for the test cases and for the various --[[User:Gerard Schildberger|Gerard Schildberger]] ([[User talk:Gerard Schildberger|talk]]) 00:47, 19 November 2015 (UTC)polygons.
Code was added to facilitate easier specification of polygon sides by just specifying their ''vertices'' instead of specifying the ''line segments''.
<lang rexx>/*REXX program verifies if a horizontal ray from point P intersects a polygon. */▼
▲<lang rexx>/*REXX program verifies if a horizontal ray from point P intersects a polygon.*/
call points 5 5, 5 8, -10 5, 0 5, 10 5, 8 5, 10 10
A=2.5; B=7.5 /*
call poly 0 0, 10 0, 10 10, 0 10 ; call test 'square'
call poly 0 0, 10 0, 10 10, 0 10, A A, B A, B B, A B ; call test 'square hole'
call poly 0 0, A A, 0 10, A B, B B, 10 10, 10 0 ; call test 'irregular'
call poly 3 0, 7 0, 10 5, 7 10, 3 10, 0 5 ; call test 'hexagon'
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
in$out: procedure expose point. poly.; parse arg p; #=0
do side=1 to poly.0 by 2;
return #//2
/*──────────────────────────────────────────────────────────────────────────────────────*/
intersect: procedure expose point. poly.; parse arg ?,s; sp=s+1
epsilon='1e' || (-digits()%2);
Px=point.?.x; Ax=poly.s.x; Ay=poly.s.y
Py=point.?.y; Bx=poly.sp.x; By=poly.sp.y /* [↓] do a swap.*/
if Ay>By then parse value Ax Ay Bx
if Py=Ay | Py=By then Py=Py+epsilon
if Py<Ay | Py>By | Px>max(Ax,Bx)
if Px<min(Ax,Bx)
if Ax\=Bx then m_red =(By-Ay) / (Bx-Ax)
else m_red =infinity
if Ax\=Px then m_blue=(Py-Ay) / (Px-Ax)
else return 1
return m_blue>=m_red
/*──────────────────────────────────────────────────────────────────────────────────────*/
points: wx=0
wy=0; do j=1 for arg(); parse value arg(j) with xx yy
wx=max(wx,length(xx)); call value 'POINT.'j".X", xx
wy=max(wy,length(yy)); call value 'POINT.'j".Y", yy
end /*j*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
poly: @='POLY.'; parse arg Fx Fy /* [↓] process the X,Y points.*/
n=0
do j=1 for arg(); n=n+1; parse value arg(j) with xx yy
call value @ || n'.X', xx ;
if n//2 then iterate
n=n+1
call value @ || n'.X', xx ;
end /*j*/
n=n+1
call value @ || n
return /*POLY.0 is number of segments(sides).*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
test: say; do k=1 for point.0; w=wx+wy+
say right(' ['arg(1)"] point:", 30),
right( right(point.k.x, wx)', 'right(point.k.y, wy), w) " is ",
right( word('outside inside', in$out(k)+1), 7)
end /*k*/
return</lang>
'''output'''
<pre>
[square] point: 5, 5 is inside
[square] point: 5, 8 is inside
[square] point: -10, 5 is
[square] point: 0, 5 is
[square] point: 10, 5 is inside
[square] point: 8, 5 is inside
[square] point: 10, 10 is outside
[square hole] point: 5, 5 is outside
[square hole] point: 5, 8 is inside
[square hole] point: -10, 5 is outside
[square hole] point: 0, 5 is outside
[square hole] point: 10, 5 is inside
[square hole] point: 8, 5 is inside
[square hole] point: 10, 10 is outside
[irregular] point: 5, 5 is
[irregular] point: 5, 8 is
[irregular] point: -10, 5 is
[irregular] point: 0, 5 is
[irregular] point: 10, 5 is
[irregular] point: 8, 5 is
[irregular] point: 10, 10 is outside
[hexagon] point: 5, 5 is
[hexagon] point: 5, 8 is inside
[hexagon] point: -10, 5 is outside
[hexagon] point: 0, 5 is outside
[hexagon] point: 10, 5 is
[hexagon] point: 8, 5 is
[hexagon] point: 10, 10 is outside
</pre>
|