point-in-polygon.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. /**
  2. * @fileoverview 判断点是否在多边形内
  3. * @author dxq613@gmail.com
  4. */
  5. // 多边形的射线检测,参考:https://blog.csdn.net/WilliamSun0122/article/details/77994526
  6. var tolerance = 1e-6;
  7. // 三态函数,判断两个double在eps精度下的大小关系
  8. function dcmp(x) {
  9. if (Math.abs(x) < tolerance) {
  10. return 0;
  11. }
  12. return x < 0 ? -1 : 1;
  13. }
  14. // 判断点Q是否在p1和p2的线段上
  15. function onSegment(p1, p2, q) {
  16. if ((q[0] - p1[0]) * (p2[1] - p1[1]) === (p2[0] - p1[0]) * (q[1] - p1[1]) &&
  17. Math.min(p1[0], p2[0]) <= q[0] &&
  18. q[0] <= Math.max(p1[0], p2[0]) &&
  19. Math.min(p1[1], p2[1]) <= q[1] &&
  20. q[1] <= Math.max(p1[1], p2[1])) {
  21. return true;
  22. }
  23. return false;
  24. }
  25. // 判断点P在多边形内-射线法
  26. export default function isInPolygon(points, x, y) {
  27. var isHit = false;
  28. var n = points.length;
  29. if (n <= 2) {
  30. // svg 中点小于 3 个时,不显示,也无法被拾取
  31. return false;
  32. }
  33. for (var i = 0; i < n; i++) {
  34. var p1 = points[i];
  35. var p2 = points[(i + 1) % n];
  36. if (onSegment(p1, p2, [x, y])) {
  37. // 点在多边形一条边上
  38. return true;
  39. }
  40. // 前一个判断min(p1[1],p2[1])<P.y<=max(p1[1],p2[1])
  41. // 后一个判断被测点 在 射线与边交点 的左边
  42. if (dcmp(p1[1] - y) > 0 !== dcmp(p2[1] - y) > 0 &&
  43. dcmp(x - ((y - p1[1]) * (p1[0] - p2[0])) / (p1[1] - p2[1]) - p1[0]) < 0) {
  44. isHit = !isHit;
  45. }
  46. }
  47. return isHit;
  48. }
  49. //# sourceMappingURL=point-in-polygon.js.map