Skip to content

Instantly share code, notes, and snippets.

@spectrox
Last active April 30, 2020 15:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save spectrox/2241623 to your computer and use it in GitHub Desktop.
Save spectrox/2241623 to your computer and use it in GitHub Desktop.
Polygon
<?php
class Polygon {
/**
* @var array
*/
protected $polygon = [];
/**
* Polygon itself, with basic vector-based structure
* Array: [ [1,1], [2,1], [3,0], [2,-1] ]
*
* @var $polygon array
*/
public function setPolygon($polygon) {
if (count($polygon) < 3) {
return false;
}
if (!isset($polygon[0]['x'])) {
foreach ($polygon as &$point) {
$point = ['x' => $point[0], 'y' => $point[1]];
}
}
$this->polygon = $polygon;
}
/**
* Check if $polygon contains $test value
*
* @var $test array(x=>decimal, y=>decimal)
*/
public function calc($test) {
$q_patt= [[0, 1], [3, 2]];
$end = end($this->polygon);
$pred_pt = end($this->polygon);
$pred_pt['x'] -= $test['x'];
$pred_pt['y'] -= $test['y'];
$pred_q = $q_patt[$pred_pt['y'] < 0][$pred_pt['x'] < 0];
$w = 0;
for ($iter = reset($this->polygon); $iter !== false; $iter = next($this->polygon)) {
$cur_pt = $iter;
$cur_pt['x'] -= $test['x'];
$cur_pt['y'] -= $test['y'];
$q = $q_patt[$cur_pt['y'] < 0][$cur_pt['x'] < 0];
switch ($q - $pred_q) {
case -3:
++$w;
break;
case 3:
--$w;
break;
case -2:
if ($pred_pt['x'] * $cur_pt['y'] >= $pred_pt['y'] * $cur_pt['x']) {
++$w;
}
break;
case 2:
if (!($pred_pt['x'] * $cur_pt['y'] >= $pred_pt['y'] * $cur_pt['x'])) {
--$w;
}
break;
}
$pred_pt = $cur_pt;
$pred_q = $q;
}
return $w != 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment