JavaScript implementation of polyline Boolean operation

Keywords: Javascript

This paper mainly introduces the method of realizing Boolean operation with polylines

//Get all the curves after Boolean operation
    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("Not a closed curve");
        }
        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[] = [];  //intersection
        let unionList: Curve[] = []; //Union
        let subList: Curve[] = []; //Complement set

        /*
        *If two closed areas have intersection and are not included, the area is divided by intersection
        */
        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
        }
    }

Because there are different methods to realize some curve classes, here we mainly talk about some ideas to realize Boolean operation

First of all, we have to judge whether the closed curve 2 is included
Then, get all the intersections of 2 closed curves. Here, the intersections may be circles and lines, lines and lines, circles and circles. There should be many ways to find the intersections on the Internet. Later, I will write a JavaScript implementation method
Then the 2 closed curve is divided into several parts according to all intersections
Finally, the segmented line segments are sorted out. The intersecting part is the part of the curve inside the opposite curve, and the merging part is the part of the curve that is not inside the opposite curve. It's similar to subtraction, but I don't want to say. See the code specifically. If it's included, it's simpler

Posted by dotbands on Tue, 31 Mar 2020 20:56:00 -0700