判断鼠标在 多边形外

判断点在多边形外算法:

 通过改点做一条水平射线:如果与多边形有 偶数个交点则说明点在多边形外,否则点在多边形内。

以下通过一个简单例子:

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;
}
}
});

ruby前端观察
原文地址:https://www.cnblogs.com/rubyxie/p/3535505.html