判断多边形是否自相交的算法

function segmentsIntr(a, b, c, d) {
  /** 1 解线性方程组, 求线段交点. **/
  // 如果分母为0 则平行或共线, 不相交
  let denominator = (b.y - a.y) * (d.x - c.x) - (a.x - b.x) * (c.y - d.y);
  if (denominator == 0) {
    return false;
  }
  // 线段所在直线的交点坐标 (x , y)
  let x =
    ((b.x - a.x) * (d.x - c.x) * (c.y - a.y) +
      (b.y - a.y) * (d.x - c.x) * a.x -
      (d.y - c.y) * (b.x - a.x) * c.x) /
    denominator;
  let y =
    -(
      (b.y - a.y) * (d.y - c.y) * (c.x - a.x) +
      (b.x - a.x) * (d.y - c.y) * a.y -
      (d.x - c.x) * (b.y - a.y) * c.y
    ) / denominator;
  /** 2 判断交点是否在两条线段上 **/
  if (
    // 交点在线段1上
    (x - a.x) * (x - b.x) <= 0 &&
    (y - a.y) * (y - b.y) <= 0 &&
    // 且交点也在线段2上
    (x - c.x) * (x - d.x) <= 0 &&
    (y - c.y) * (y - d.y) <= 0
  ) {
    // 返回交点p
    return { x: x, y: y };
  }
  //否则不相交
  return false;
}

/**单个polygon是否相交 */
/**示例:
 *judgeIsSelf([
            [119.86779263801948, 31.75129376368056],
            [119.94598259813965, 31.82022438641808],
            [119.96381539606179, 31.759524285798474],
            [119.8859683743632, 31.820910263261236],
          ]); 
 *
 */
export const judgeIsSelf = (ring) =>{
  let rings = JSON.parse(JSON.stringify(ring));
  rings.pop();
  const arr = [];
  const data = rings;
  for (let i = 0; i < data.length - 3; i++) {
    for (let j = i + 2; j <= data.length - 2; j++) {
      let a = {
        x: data[i][0],
        y: data[i][1],
      };
      let b = {
        x: data[i + 1][0],
        y: data[i + 1][1],
      };
      let c = {
        x: data[j][0],
        y: data[j][1],
      };
      let d = {
        x: data[j + 1][0],
        y: data[j + 1][1],
      };
      let obj = segmentsIntr(a, b, c, d);
      if (obj) {
        arr.push(obj);
      }
    }
  }
  return arr;
}

/**多个polygon之间是否相交 */
/**
 * 示例
 * judgeIsSelfMuti([
        [
            [119.86290576551194, 31.840886426318242],
            [119.86084813498246, 31.813108414170287],
            [119.85055998233507, 31.839085999604947],
        ],
        [
            [119.84198652179558, 31.834627800124412],
            [119.8704504107867, 31.833341781043487],
            [119.86633514972775, 31.81945277496951],
            [119.84713059811928, 31.819709978785696],
        ],
        [
            [119.89317008121638, 31.83792858243214],
            [119.91340344808958, 31.835870951902663],
            [119.90723055650115, 31.822496353461055],
        ],
        ]); 
 */
export const judgeIsSelfMuti = (rings)=> {
  const arr = [];
  const data = rings;
  console.log(data);
  for (let i = 0; i < data.length - 1; i++) {
    for (let j = i + 1; j < data.length; j++) {
      let item1 = data[i];
      let item2 = data[j];
      for (let m = 0; m < item1.length - 1; m++) {
        for (let n = 0; n < item2.length - 1; n++) {
          let a = {
            x: Number(item1[m][0]),
            y: Number(item1[m][1]),
          };
          let b = {
            x: Number(item1[m + 1][0]),
            y: Number(item1[m + 1][1]),
          };
          let c = {
            x: Number(item2[n][0]),
            y: Number(item2[n][1]),
          };
          let d = {
            x: Number(item2[n + 1][0]),
            y: Number(item2[n + 1][1]),
          };
          let obj = segmentsIntr(a, b, c, d);
          if (obj) {
            arr.push(obj);
          }
        }
      }
    }
  }
  return arr;
};

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值