Created
May 15, 2018 05:44
-
-
Save zhujunsan/81d6a2f05d590f618a5ad36f25666fc2 to your computer and use it in GitHub Desktop.
winding number algorithm for the inclusion of a point in polygon
This file contains 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