-
-
Save malanx/05cafebaf79f9c6f4383214efc3290e8 to your computer and use it in GitHub Desktop.
winding number algorithm for the inclusion of a point in polygon
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Point | |
{ | |
public $x; | |
public $y; | |
public function __construct($x, $y) | |
{ | |
$this->x = $x; | |
$this->y = $y; | |
} | |
} | |
class wnPoly | |
{ | |
private static function isLeft(Point $P0, Point $P1, Point $P2) | |
{ | |
return (($P1->x - $P0->x) * ($P2->y - $P0->y) - ($P2->x - $P0->x) * ($P1->y - $P0->y)); | |
} | |
// wn_PnPoly(): winding number test for a point in a polygon | |
// Input: P = a point, | |
// V[] = vertex points of a polygon V[n+1] with V[n]=V[0] | |
/** | |
* @param Point $P | |
* @param Point[] $V | |
* @return int | |
*/ | |
public static function wn_PnPoly(Point $P, array $V) | |
{ | |
$wn = 0; | |
$n = count($V); | |
// loop through all edges of the polygon | |
for ($i = 0; $i < $n; $i++) { // edge from V[i] to V[i+1] | |
if ($V[$i]->y <= $P->y) { // start y <= P->y | |
if ($V[($i + 1) % $n]->y > $P->y) // an upward crossing | |
if (self::isLeft($V[$i], $V[($i + 1) % $n], $P) > 0) // P left of edge | |
++$wn; // have a valid up intersect | |
} else { // start y > P->y (no test needed) | |
if ($V[($i + 1) % $n]->y <= $P->y) // a downward crossing | |
if (self::isLeft($V[$i], $V[($i + 1) % $n], $P) < 0) // P right of edge | |
--$wn; // have a valid down intersect | |
} | |
} | |
return $wn; | |
} | |
} | |
$V = []; | |
$V [] = new Point(0, 0); | |
$V [] = new Point(10, 0); | |
$V [] = new Point(10, 10); | |
$V [] = new Point(0, 10); | |
$P = new Point(5, 51); | |
$r = wnPoly::wn_PnPoly($P, $V); | |
var_dump($r); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment