JavaScript实现封闭区域布尔运算:多段线与曲线交点处理

作者:纸飞机时间:2026-10-22 15:40:57浏览:514

本文介绍使用JavaScript实现封闭曲线(多段线与圆)布尔运算的核心思路。通过计算两曲线的交点,将原始曲线分割为多个部分,并根据交点位置判断线段属于相交、合并或相减区域,最终生成并集、交集与差集结果。

JavaScript封闭曲线布尔运算概述

本文重点探讨如何利用JavaScript处理多段线及封闭曲线的布尔运算问题。

首先展示相关实现代码。

核心算法与代码实现


function getOperatedCurves(sourceCurs: Curve[], targetCus: Curve[])
  {
    let source: Polyline | Circle = (sourceCurs[0] instanceof Circle) ? sourceCurs[0] as Circle : new Polyline().Combine(sourceCurs)[0];
    let target: Polyline | Circle = (targetCus[0] instanceof Circle) ? targetCus[0] as Circle : new Polyline().Combine(targetCus)[0];
    try
    {
      if (!source.IsClose || !target.IsClose) throw new Error("不是封闭曲线");
    }
    catch (err)
    {
      console.log(err);
    }

    let interPts = source.IntersectWith(target, IntersectOption.OnBothOperands);
    let sourceContainerTarget = isTargetCurInSourceCur(source, target);
    let targetContainerSource = isTargetCurInSourceCur(target, source);

    let isContainer = sourceContainerTarget || targetContainerSource;
    let intersectionList: Curve[] = []; //交集
    let unionList: Curve[] = []; //并集
    let subList: Curve[] = []; //补集

    /*
    *两封闭区域有交点并且不是包含关系,则通过交点把区域分割
    */
    if (interPts.length && !isContainer)
    {
      let pars1 = interPts.map(p => source.GetParamAtPoint(p)).sort((a, b) => a - b);
      let pars2 = interPts.map(p => target.GetParamAtPoint(p)).sort((a, b) => a - b);

      let cus1: Array<Polyline | Arc> = source.GetSplitCurves(pars1);

      cus1.forEach(pl =>
      {
        if (isTargetCurInSourceCur(target, pl))
        {
          intersectionList.push(pl);
        }
        else
        {
          subList.push(pl);
          unionList.push(pl);
        }
      })

      let cus2: Array<Polyline | Arc> = target.GetSplitCurves(pars2);
      cus2.forEach(pl =>
      {
        if (isTargetCurInSourceCur(source, pl))
        {
          intersectionList.push(pl);
          subList.push(pl);
        }
        else
        {
          unionList.push(pl);
        }
      })

    }
    else
    {
      if (isContainer)
      {
        if (sourceContainerTarget)
        {
          intersectionList.push(target);
          subList.push(source, target);
          unionList.push(source);
        }
        else
        {
          unionList.push(target);
          intersectionList.push(source);
        }
      }
      else
      {
        unionList.push(source, target)
        subList.push(source);
      }

    }
    return {
      intersectionList, unionList, subList
    }
  }

运算逻辑与步骤详解

由于各类曲线类的具体实现方式存在差异,此处主要阐述执行布尔运算的核心逻辑与思路。

  1. 第一步是判断两条封闭曲线之间是否存在包含关系。
  2. 第二步是获取两条封闭曲线的所有交点。这些交点可能产生于圆与线、线与线或圆与圆的交互中。关于求交点的具体算法网络资源较多,后续若有精力将补充JavaScript实现细节。
  3. 第三步是根据获取到的所有交点,将两条封闭曲线分别分割为多个独立的线段部分。
  4. 第四步是对分割后的线段进行整理与分类。其中,位于对方曲线内部的相交部分、互不在对方内部的合并部分,以及相减部分(逻辑类似,此处略述),具体实现需参考代码。若存在包含关系,处理逻辑相对更为简单。

以上内容为本文的全部介绍,希望能为读者的学习提供有益参考,同时也欢迎大家继续支持本站。

作者最新文章