(function (window) { "use strict"; /** * 判斷給出的座標點是否在多邊形內 * */ function pointInPolygon(targetPoint, targetPoints) { var leftPointCount = 0; var rightPointCount = 0;//左右點的個數 var _points = []; //第一步:取出全部的點,並計算交點座標 for (var i = 0, _length = targetPoints.length - 1; i < _length; i++) { var p1 = targetPoints[i], p2 = targetPoints[i + 1];//取出當前點和當前點的下一個點 var point = _calcCrossoverPoint(targetPoint, p1, p2); //若是交點有效,則保存 if (point) { _points.push(point); } } // 第二步:計算給定的座標點,左右兩邊的交點個數,奇數在範圍內,偶數則不在 for (var j = 0, length = _points.length; j < length; j++) { var x = _points[j]; if (x === targetPoint.x) { return false;//在線上,直接返回不在範圍內 } else { (targetPoint.x !== x && targetPoint.x > x) ? leftPointCount++ : rightPointCount++; } } //判斷交點個數 return (leftPointCount % 2 !== 0 && rightPointCount % 2 !== 0); } /** * 算交點座標,座標點在掃描行上或者上方時,交點無效 * @param targetPoint * @param startPoint * @param endPoint * @returns {*} */ function _calcCrossoverPoint(targetPoint, startPoint, endPoint) { var crossoverPointX = startPoint.x - ((startPoint.y - targetPoint.y) * (startPoint.x - endPoint.x) / (startPoint.y - endPoint.y)); // 判斷交點座標是否有效,即交點在startPoint,endPoint構成的線段範圍內 if ((startPoint.y < targetPoint.y && endPoint.y >= targetPoint.y) || (endPoint.y < targetPoint.y && startPoint.y >= targetPoint.y)) { if ((crossoverPointX >= startPoint.x && crossoverPointX <= endPoint.x) || (crossoverPointX <= startPoint.x && crossoverPointX >= endPoint.x)) { return crossoverPointX; } else { return false; } } else { return false; } } var isIn = pointInPolygon({x: 4, y: 4}, [{x: 2, y: 1}, {x: 1, y: 3}, {x: 3, y: 5}, {x: 5, y: 4}, { x: 4, y: 1 }, {x: 3, y: 2}, { x: 2, y: 1 }]); console.log(isIn); })(window);