RosettaCodeData/Task/Ray-casting-algorithm/Zkl/ray-casting-algorithm-1.zkl

18 lines
685 B
Plaintext

const E = 0.0001;
fcn rayHitsSeg([(Px,Py)],[(Ax,Ay)],[(Bx,By)]){ // --> Bool
if(Py==Ay or Py==By) Py+=E;
if(Py<Ay or Py>By or Px>Ax.max(Bx)) False
else if(Px<Ax.min(Bx)) True
else try{ ( (Py - Ay)/(Px - Ax) )>=( (By - Ay)/(Bx - Ax) ) } //blue>=red
catch(MathError){ Px==Ax } // divide by zero == ∞, only blue?
}
fcn pointInPoly(point, polygon){ // --> Bool, polygon is ( (a,b),(c,d).. )
polygon.filter('wrap([(ab,cd)]){ a,b:=ab; c,d:=cd;
if(b<=d) rayHitsSeg(point,ab,cd); // left point has smallest y coordinate
else rayHitsSeg(point,cd,ab);
})
.len().isOdd; // True if crossed an odd number of borders ie inside polygon
}