define("inf",1e9);
define("EXP",1e-9);
//叉乘 if >0 p1在p2的顺时针方向;$p1=array(1,0);
function multi($p1,$p2,$p0){
return ($p1[0]-$p0[0])*($p2[1]-$p0[1])-($p1[1]-$p0[1])*($p2[0]-$p0[0]);
}
//if叉乘为零说明共线,如果该点在以side为对角线的矩形中心说明p在side上;
function isonline($p,$side){
return (abs(multi($p,$side[0],$side[1])) < EXP &&
min($side[0][0],$side[1][0]) <= $p[0] && $p[0] <= max($side[0][0],$side[1][0]) &&
$p[1] >= min($side[0][1],$side[1][1]) && $p[1] <= max($side[0][1],$side[1][1]));
}
//线段相交,跨立试验(叉积判断),快速排斥试验;
function intersect($l,$r){
return (max($l[0][0],$l[1][0])>=min($r[0][0],$r[1][0])//快速排斥试验用来确定以两线段为对角线的矩形是否相交;
&& max($r[0][0],$r[1][0]) >= min($l[0][0],$l[1][0])
&& max($l[0][1],$l[1][1]) >= min($r[0][1],$r[1][1])
&& max($r[0][1],$r[1][0]) >= min($l[0][1],$l[1][1])
&& multi($r[0],$l[1],$l[0])*multi($r[1],$l[1],$l[0])<=0
&& multi($l[0],$r[1],$r[0])*multi($l[1],$r[1],$r[0])<=0
);
}
function isinpolygon($p,$n,$new){
$i=$count =0;
if($n == 1){
return abs($p[0]-$new[0][0]) < EXP && abs($p[1]-$new[0][1])
}
if($n == 2){
$side[0]=$p;
$side[1][1]=$p[1];
return isonline($p,$side);
}
$line[0] = $p;
$line[1][1] = $p[1];
$line[1][0] = -inf;
for($i =0;$i
$side[0] = $new[$i];
$side[1] = $new[($i+1)%$n];
if(isonline($p,$side))return 1;
if(abs($side[0][1]-$side[1][1]) < EXP)continue;
if(isonline($side[0],$line) && $side[0][1]>$side[1][1])$count++;
else if(isonline($side[1],$line) && $side[1][1] > $side[0][1]){$count++;}
else if(intersect($line,$side))$count++;
}
return $count%2;
}
$new = array(
array(2,1),
array(5,1),
array(6,3),
array(7,1),
array(8,3),
array(8,6),
array(4,4),
array(2,6),
array(2,1),
);
$p = array(6,3);
$n = 8;
echo isinpolygon($p,$n,$new);
?>