越简单越好!

php 判断一个点是否在面内

bevin 发表于 2010-08-24 17:11 | 163次阅读 1次推荐   PHP

<?php
function getPin($s,$point) {
// 求得最大点和最小点的x,y
$max_x = $s[0][0];
$max_y = $s[0][1];
$min_x = $s[0][0];
$min_y = $s[0][1];
foreach($s as $v) {
   if($v[0]>$max_x) { $max_x = $v[0]; }
   if($v[0]<$min_x) { $min_x = $v[0]; }
   if($v[1]>$max_y) { $max_y = $v[1]; }
   if($v[1]<$min_y) { $min_y = $v[1]; }
}

// 判断是不是在最大四边形外
if($point[0]>$max_x || $point[0]<$min_x || $point[1]>$max_y || $point[1]<$min_y) {
   return false;
}

// 求当前点的垂直线与几条边相交
$crosspoint = 0;
$newline = array('x1'=>$point[0],'x2'=>$point[0],'y1'=>$point[1],'y2'=>$min_y);
for($i=1; $i<count($s); $i++) {
   $tmpline = array('x1'=>$s[($i-1)][0],'x2'=>$s[$i][0],'y1'=>$s[($i-1)][1],'y2'=>$s[$i][1]);
   // 判断是否在线上,是直接返回true
   if(isInLine($point,$tmpline)) {
    return true;
   }
   if(isCross($newline,$tmpline)){
    $crosspoint++;
   }
}
$tmpline = array('x1'=>$s[($i-1)][0],'x2'=>$s[0][0],'y1'=>$s[($i-1)][1],'y2'=>$s[0][1]);
// 判断是否在线上,是直接返回true
if(isInLine($point,$tmpline)) {
   return true;
}
if(isCross($newline,$tmpline)){
   $crosspoint++;
}

// 相交的线为奇数是,在面内。
if($crosspoint%2) {
   return true;
}

return false;
}

function multiply($x1,$y1,$x2,$y2,$x0,$y0) {
    return ($x1-$x0)*($y2-$y0)-($x2-$x0)*($y1-$y0);
}

// 判断两线段是否相交
function isCross($a,$b) {
return (
        max($a['x1'],$a['x2'])>=min($b['x1'],$b['x2'])&&
        max($b['x1'],$b['x2'])>=min($a['x1'],$a['x2'])&&
        max($a['y1'],$a['y2'])>=min($b['y1'],$b['y2'])&&
        max($b['y1'],$b['y2'])>=min($a['y1'],$a['y2'])&&
        multiply($a['x1'],$a['y1'],$b['x2'],$b['y2'],$b['x1'],$b['y1'])*multiply($b['x2'],$b['y2'],$a['x2'],$a['y2'],$b['x1'],$b['y1'])>=0&&
        multiply($b['x1'],$b['y1'],$a['x2'],$a['y2'],$a['x1'],$a['y1'])*multiply($a['x2'],$a['y2'],$b['x2'],$b['y2'],$a['x1'],$a['y1'])>=0
);
}

// 判断点是否在线段上
function isInLine ($p,$line) {
if($line['x1']==$line['x2']) {
   if($p[0]==$line['x1']) {
    if($p[1]<max($line['y1'],$line['y2']) && $p[1]>min($line['y1'],$line['y2'])) { return true; } else { return false; }
   } else { 
    return false; 
   }
}

if($line['y1']==$line['y2']) {
   if($p[1]==$line['y1']) {
    if($p[0]<max($line['x1'],$line['x2']) && $p[0]>min($line['x1'],$line['x2'])) { return true; } else { return false; }
   } else { 
    return false; 
   }
}

if($line['y1']==$p[1]) { return $line['x1']==$p[0]; }
if($line['x1']==$p[0]) { return $line['y1']==$p[1]; }

return abs(($line['x1']-$line['x2'])/($line['y1']-$line['y2'])) == abs(($line['x1']-$p[0])/($line['y1']-$p[1]));

}

$s = array(array(1,1), array(2,4), array(4,4), array(4,2));
$point = array(rand(0,4),rand(0,4));
if(getPin($s,$point)) {
echo "Y";
} else {
echo "N";
}
?>

+1
发表评论
×您的大名会显示在评论处

评论内容不能少于5个字哦~~~

评论列表
当前暂无评论
发送数据中... 请求错误. 请输入评论内容和验证码后再发布 您已经参与过了,谢谢
返回顶部 ^