예제 #1
0
        /*
         *        INTERSECT: (LCurve, LCurve)
         *                - both curves are supposed to be NON-DEGENERATED
         */

        public static bool IntersectLL(LCurve lrsA, LCurve lrsB,
                                       out InfoInters inters)
        {
            inters = null;
            if ((lrsA.IsDegen) || (lrsB.IsDegen))
            {
                throw new ExceptionGMath("Intersect", "IntersectLL(lrs,lrs)", null);
            }

            VecD   a0   = lrsA.Start;
            VecD   a1   = lrsA.End;
            VecD   b0   = lrsB.Start;
            VecD   b1   = lrsB.End;
            VecD   dirA = lrsA.DirTang;
            VecD   dirB = lrsB.DirTang;
            double det  = dirA.Cross(dirB);

            // lrsA and lrsB are not parallel
            if (Math.Abs(det) > MConsts.EPS_DEC)
            {
                double lenA = (a1 - a0).Norm;
                double lenB = (b1 - b0).Norm;
                VecD   diff = b0 - a0;
                Param  parA = (diff.Cross(dirB)) / (det * lenA);
                Param  parB = (diff.Cross(dirA)) / (det * lenB);
                if (lrsA.IsEvaluableStrict(parA) && lrsB.IsEvaluableStrict(parB))
                {
                    VecD pnt = 0.5 * (lrsA.Evaluate(parA) + lrsB.Evaluate(parB));
                    inters = new IntersD0(parA, parB, pnt, false);
                }
                return(true);
            }

            // lrsA and lrsB are parallel
            LineD lineB = new LineD(lrsB);
            Param paramBInvA0, paramBInvA1;
            VecD  pntProjA0, pntProjA1;

            a0.Project(lineB, out paramBInvA0, out pntProjA0);
            a1.Project(lineB, out paramBInvA1, out pntProjA1);
            double distA0 = a0.Dist(pntProjA0);
            double distA1 = a1.Dist(pntProjA1);

            if ((distA0 < MConsts.EPS_DEC) || (distA1 < MConsts.EPS_DEC))
            {
                // lrsA and lrsB are colinear
                Param.TypeParam typeA0 = lrsB.ParamClassify(paramBInvA0);
                Param.TypeParam typeA1 = lrsB.ParamClassify(paramBInvA1);
                int             mult   = (int)typeA0 * (int)typeA1;

                if (mult == 4)
                {
                    return(true);
                }
                else if (mult == 1)
                {
                    throw new ExceptionGMath("Intersect", "IntersectLL(lrs,lrs)", null); // lrsA is degenerated
                    //return false;
                }
                else if (mult == 2)
                {
                    if ((typeA0 == Param.TypeParam.Start) &&
                        (typeA1 == Param.TypeParam.Before))
                    {
                        inters = new IntersD0(0, 0, a0, false);
                    }
                    if ((typeA0 == Param.TypeParam.Before) &&
                        (typeA1 == Param.TypeParam.Start))
                    {
                        inters = new IntersD0(1, 0, a1, false);
                    }
                    if ((typeA0 == Param.TypeParam.End) &&
                        (typeA1 == Param.TypeParam.After))
                    {
                        inters = new IntersD0(0, 1, a0, false);
                    }
                    if ((typeA0 == Param.TypeParam.After) &&
                        (typeA1 == Param.TypeParam.End))
                    {
                        inters = new IntersD0(1, 1, a1, false);
                    }
                    return(true);
                }
                else if (mult <= 0)
                {
                    return(Inters.RefineIntersLLD1(lrsA, lrsB, out inters));
                }
            }

            return(true);
        }
예제 #2
0
        public static bool RefineIntersLLD1(LCurve lrsA, LCurve lrsB,
                                            out InfoInters inters)
        {
            inters = null;
            if ((lrsA is SegD) && (lrsB is SegD))
            {
                BCurve curveA = lrsA as BCurve;
                BCurve curveB = lrsB as BCurve;
                return(Inters.RefineIntersBBD1(curveA, curveB, out inters));
            }
            if (lrsA.LComplexity > lrsB.LComplexity)
            {
                bool res = Inters.RefineIntersLLD1(lrsB, lrsA, out inters);
                if (inters != null)
                {
                    inters.ParamSwap();
                }
                return(res);
            }
            VecD a0 = lrsA.Start;
            VecD a1 = lrsA.End;
            VecD b0 = lrsB.Start;
            VecD b1 = lrsB.End;

            Param paramBInvA0, paramBInvA1;
            bool  isOn;

            if ((!a0.InverseOn(lrsB, out isOn, out paramBInvA0)) || (!isOn))
            {
                return(false);
            }
            if ((!a1.InverseOn(lrsB, out isOn, out paramBInvA1)) || (!isOn))
            {
                return(false);
            }
            Param paramAInvB0, paramAInvB1;

            if ((!b0.InverseOn(lrsA, out isOn, out paramAInvB0)) || (!isOn))
            {
                return(false);
            }
            if ((!b1.InverseOn(lrsA, out isOn, out paramAInvB1)) || (!isOn))
            {
                return(false);
            }

            bool areCoDirected = (paramBInvA1.Val >= paramBInvA0.Val);

            if (!areCoDirected)
            {
                if (lrsA is LineD)
                {
                    if (lrsB is LineD)
                    {
                        paramAInvB0 = (areCoDirected)? -Param.Infinity: Param.Infinity;
                        paramAInvB1 = (areCoDirected)? Param.Infinity: -Param.Infinity;

                        inters = new IntersD1(paramAInvB0, -Param.Infinity,
                                              paramAInvB1, Param.Infinity, lrsB, false);
                        return(true);
                    }
                    if (lrsB is RayD)
                    {
                        paramAInvB1 = (areCoDirected)? Param.Infinity: -Param.Infinity;
                        inters      = new IntersD1(paramAInvB0, 0,
                                                   paramAInvB1, Param.Infinity, lrsB, false);
                        return(true);
                    }
                    if (lrsB is SegD)
                    {
                        inters = new IntersD1(paramAInvB0, 0,
                                              paramAInvB1, 1, lrsB, false);
                        return(true);
                    }
                }
                if (lrsA is RayD)
                {
                    if (lrsB is RayD)
                    {
                        if (areCoDirected)
                        {
                            if (paramAInvB0 > 0)
                            {
                                inters = new IntersD1(paramAInvB0, 0,
                                                      Param.Infinity, Param.Infinity, lrsB, false);
                                return(true);
                            }
                            else
                            {
                                inters = new IntersD1(0, paramBInvA0,
                                                      Param.Infinity, Param.Infinity, lrsA, false);
                                return(true);
                            }
                        }
                        else
                        {
                            if (paramAInvB0 > 0)
                            {
                                inters = new IntersD1(0, paramBInvA0,
                                                      paramAInvB0, 0, new SegD(a0, b0), false);
                                return(true);
                            }
                        }
                    }
                    if (lrsB is SegD)
                    {
                        // intersection is known to have dimension D1 !!!
                        if ((paramBInvA0 >= 1) || (paramBInvA0 <= 0))
                        {
                            inters = new IntersD1(paramAInvB0, 0,
                                                  paramAInvB1, 1, new SegD(b0, b1), false);
                            return(true);
                        }
                        if ((0 < paramBInvA0) && (paramBInvA1 < 1))
                        {
                            if (areCoDirected)
                            {
                                inters = new IntersD1(0, paramBInvA0,
                                                      paramAInvB1, 1, new SegD(a0, b1), false);
                                return(true);
                            }
                            else
                            {
                                inters = new IntersD1(0, paramBInvA0,
                                                      paramAInvB0, 0, new SegD(a0, b0), false);
                                return(true);
                            }
                        }
                    }
                }
            }
            throw new ExceptionGMath("Intersect", "RefineIntersLLD1", null);
            //return false;
        }