判断点在多边形外算法:
通过改点做一条水平射线:如果与多边形有 偶数个交点则说明点在多边形外,否则点在多边形内。
以下通过一个简单例子:
http://888.qq.com/promote/party/2013/0801_jczq/index.shtml#nogo
var o = {
init: function () {
o.initParty();
this.flag =
false; //鼠标位于多边形内
this.pos = 0; //记录位于哪个多边形
this.lastpos =
-1;
this.point = {
x: 0,
y: 0
};
this.polygon =
[
[
{x: 400, y: 220},
{x: 520, y: 0},
{x: 715, y:
0},
{x: 895, y: 220},
{x: 715, y: 445},
{x: 520, y:
445}
],
[
{x: 0, y: 450},
{x: 120, y:
230},
{x: 375, y: 230},
{x: 500, y: 450},
{x: 375, y:
665},
{x: 120, y: 665}
],
[
{x: 400, y:
675},
{x: 520, y: 455},
{x: 715, y: 455},
{x: 895, y:
675},
{x: 715, y: 895},
{x: 520, y:
895}
],
[
{x: 0, y: 895},
{x: 120, y:
680},
{x: 375, y: 680},
{x: 500, y: 895},
{x: 375, y:
1115},
{x: 120, y:
1115}
]
];
o.getLeftMoney();
o.bindEvent();
},
//鼠标划过效果
hoverEffect:
function (flag) {
if (flag) {
//移入
$(".cent2-img").fadeIn(100);
switch (o.pos) {
case
0:
$(".cent2-img1").fadeOut(100);
break;
case
1:
$(".cent2-img2").fadeOut(100);
break;
case
2:
$(".cent2-img3").fadeOut(100);
break;
case
3:
$(".cent2-img4").fadeOut(100);
break;
}
} else
{ //移出
$(".cent2-img").fadeIn(100);
}
},
bindEvent: function
() {
//鼠标位置获取
$(".mid-cent").mousemove(function (e) {
if
(e.pageX || e.pageY) {
var x = e.pageX,
y = e.pageY;
}
else {
var x = e.clientX + document.body.scrollLeft -
document.body.clientLeft,
y = e.clientY + document.body.scrollTop -
document.body.clientTop;
}
var offsetX = $(this).offset().left,
offsetY =
$(this).offset().top;
o.point.x = x - offsetX;
o.point.y = y - offsetY; //鼠标当前坐标位置
for (var i = 0; i < 4; i++) {
o.checkPP(o.point, o.polygon[i],
i);
if (o.flag) { //
位于多边形内
break;
}
}
//移入、移出、内部移动、外部移动
if (!o.flag)
{
if (o.pos == o.lastpos) { //移出
o.lastpos =
-1;
o.hoverEffect(o.flag);
}
} else {
if (o.pos
!== o.lastpos) { //移入
o.hoverEffect(o.flag);
o.lastpos =
o.pos;
}
}
});
},
//向量叉乘
crossMul: function
(v1, v2) {
return v1.x * v2.y - v1.y *
v2.x;
},
//两条直线是否相交
checkCross: function (p1, p2, p3, p4)
{
var v1 = {x: p1.x - p3.x, y: p1.y - p3.y},
v2 = {x: p2.x - p3.x,
y: p2.y - p3.y},
v3 = {x: p4.x - p3.x, y: p4.y - p3.y},
v =
o.crossMul(v1, v3) * o.crossMul(v2, v3),
v1 = {x: p3.x - p1.x, y: p3.y -
p1.y},
v2 = {x: p4.x - p1.x, y: p4.y - p1.y},
v3 = {x: p2.x -
p1.x, y: p2.y - p1.y};
return (v <= 0 && o.crossMul(v1, v3) *
o.crossMul(v2, v3) <= 0) ? true :
false;
},
//判断点是否在多边形内
checkPP: function (point, polygon, pos)
{
var p1, p2, p3, p4
p1 = point
p2 = {x: -100, y:
point.y}
var count = 0
//对每条边都和射线作对比
for (var i = 0; i <
polygon.length - 1; i++) {
p3 = polygon[i]
p4 = polygon[i +
1]
if (o.checkCross(p1, p2, p3, p4) == true)
{
count++
}
}
p3 = polygon[polygon.length -
1]
p4 = polygon[0]
if (o.checkCross(p1, p2, p3, p4) == true)
{
count++
}
(count % 2 == 0) ? o.flag = false : o.flag =
true;
//移动位置记录位于哪个区域
if (o.flag) { //多边形内部
o.pos =
pos;
}
},
//数字位数补齐,1对应000001,11对应000011
padNum: function
(num, n) {
var len = num.toString().length;
while (len < n)
{
num = ‘0‘ + num;
len++;
}
return num;
}
}
代码如上:大概思路是这样:
$(".mid-cent").mousemove(function (e) {
if (e.pageX || e.pageY)
{
var x = e.pageX,
y = e.pageY;
} else {
var x =
e.clientX + document.body.scrollLeft - document.body.clientLeft,
y =
e.clientY + document.body.scrollTop - document.body.clientTop;
}
var offsetX = $(this).offset().left,
offsetY =
$(this).offset().top;
o.point.x = x - offsetX;
o.point.y = y - offsetY; //鼠标当前坐标位置
//通过上面代码获取鼠标所在位置, 其中以.mid-cent 的div边框的左上角为左边原点
for (var i = 0; i < 4; i++) {
o.checkPP(o.point, o.polygon[i],
i);//判断相交焦点个数
if (o.flag) { //
位于多边形内
break;
}
}
//移入、移出、内部移动、外部移动
if (!o.flag)
{
if (o.pos == o.lastpos) { //移出
o.lastpos =
-1;
o.hoverEffect(o.flag);
}
} else {
if (o.pos
!== o.lastpos) { //移入
o.hoverEffect(o.flag);
o.lastpos =
o.pos;
}
}
});