point-in-polygon.js 1.7 KB

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