SPolygonUtil.ts 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import { SPoint } from "..";
  2. /**
  3. * 多边形工具
  4. *
  5. * @author 庞利祥(sybotan@126.com)
  6. */
  7. export class SPolygonUtil {
  8. /**
  9. * 判断点是否在多边形内
  10. *
  11. * @param x 点的x坐标
  12. * @param y 点的y坐标
  13. * @param pointList 多边形顶点
  14. */
  15. static pointIn(x: number, y: number, pointList: SPoint[]): boolean {
  16. let crossNum = 0;
  17. for (let i = 0; i < pointList.length; i++) {
  18. let p1 = pointList[i];
  19. let p2 = pointList[(i + 1) % pointList.length];
  20. // p1p2 与 y=p0.y平行
  21. if (p1.y == p2.y) {
  22. continue;
  23. }
  24. // 交点在p1p2延长线上
  25. if (y < Math.min(p1.y, p2.y) || y >= Math.max(p1.y, p2.y)) {
  26. continue;
  27. }
  28. // 求交点的 x 坐标
  29. let x0 = ((y - p1.y) * (p2.x - p1.x)) / (p2.y - p1.y) + p1.x;
  30. if (x0 > x) {
  31. // 只统计单边交点
  32. crossNum++;
  33. }
  34. }
  35. // 单边交点为奇数,点在多边形之内
  36. return crossNum % 2 == 1;
  37. } // Function pointIn()
  38. /**
  39. * 判断多边型顶点的时针方向(计算基于数学坐标系统,在绘图坐标系由于y轴方向相反结果也要取反)
  40. *
  41. * @param pointList 多边形顶点
  42. * @return 为负,顺时针;为正,逆时针;0,点在直线上。
  43. */
  44. static clockDir(pointList: SPoint[]): number {
  45. if (pointList.length < 3) {
  46. return 0;
  47. }
  48. // 找出x坐标最大的值
  49. let index = 0;
  50. let len = pointList.length;
  51. for (let i = 1; i < len; i++) {
  52. if (pointList[i].x > pointList[index].x) {
  53. index = i;
  54. }
  55. }
  56. let p1 = pointList[index == 0 ? len - 1 : index - 1];
  57. let p2 = pointList[index];
  58. let p3 = pointList[(index + 1) % len];
  59. return (p2.x - p1.x) * (p3.y - p2.y) - (p2.y - p1.y) * (p3.x - p2.x);
  60. } // Function clockDir()
  61. } // Class SPolygonUtil