Example #1
0
        public ISurface AdaptToCurves(IEnumerable <ICurve> curves)
        {
            BoundingRect domain = BoundingRect.EmptyBoundingRect;

            foreach (ICurve curve in curves)
            {
                ICurve2D c2d = periodicSurface.GetProjectedCurve(curve, 0.0);
                if (domain.IsEmpty())
                {
                    domain = c2d.GetExtent();
                }
                else
                {
                    SurfaceHelper.AdjustPeriodic(periodicSurface, domain, c2d);
                    domain.MinMax(c2d.GetExtent());
                }
            }
            return(new NonPeriodicSurface(periodicSurface, domain));
        }
Example #2
0
        /// <summary>
        /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.Intersect (ICurve, BoundingRect, out GeoPoint[], out GeoPoint2D[], out double[])"/>
        /// </summary>
        /// <param name="curve"></param>
        /// <param name="uvExtent"></param>
        /// <param name="ips"></param>
        /// <param name="uvOnFaces"></param>
        /// <param name="uOnCurve3Ds"></param>
        public override void Intersect(ICurve curve, BoundingRect uvExtent, out GeoPoint[] ips, out GeoPoint2D[] uvOnFaces, out double[] uOnCurve3Ds)
        {
            if (curve is Line)
            {
                GeoPoint ip;
                if (Plane.Intersect(curve.StartPoint, curve.StartDirection, out ip))
                {
                    ips         = new GeoPoint[] { ip };
                    uvOnFaces   = new GeoPoint2D[] { PositionOf(ip) };
                    uOnCurve3Ds = new double[] { curve.PositionOf(ip) };
                }
                else
                {
                    ips         = new GeoPoint[0];
                    uvOnFaces   = new GeoPoint2D[0];
                    uOnCurve3Ds = new double[0];
                }
#if DEBUG
                //GeoPoint[] ipsdbg;
                //GeoPoint2D[] uvOnFacesdbg;
                //double[] uOnCurve3Dsdbg;
                //base.Intersect(curve, out ipsdbg, out uvOnFacesdbg, out uOnCurve3Dsdbg);
#endif
                return;
            }
            //else if (curve is IExplicitPCurve3D)
            //{
            //    ExplicitPCurve3D epc3d = (curve as IExplicitPCurve3D).GetExplicitPCurve3D();
            //    double [] res = epc3d.GetPlaneIntersection(Location, DirectionX, DirectionY);
            //    for (int i = 0; i < res.Length; i++)
            //    {
            //        double d = Plane.Distance(epc3d.PointAt(res[i]));
            //        if (i>0) d = Plane.Distance(epc3d.PointAt((res[i]+res[i-1])/2.0));
            //    }
            //    double dd = Plane.Distance(epc3d.PointAt(epc3d.knots[epc3d.knots.Length - 1]));
            //    for (int i = 0; i < res.Length; i++)
            //    {
            //        res[i] = (res[i] - epc3d.knots[0]) / (epc3d.knots[epc3d.knots.Length - 1] - epc3d.knots[0]);
            //    }
            //}
            else
            {
                if (curve.GetPlanarState() == PlanarState.Planar)
                {
                    GeoPoint  loc;
                    GeoVector dir;
                    Plane     pln = curve.GetPlane();
                    if (Plane.Intersect(curve.GetPlane(), out loc, out dir))
                    {
                        ICurve2D     c2d = curve.GetProjectedCurve(pln);
                        BoundingRect ext = c2d.GetExtent();
                        ext.Inflate(ext.Height + ext.Width); // sonst entstehen null-Linien
                        ICurve2D ll = new Line2D(pln.Project(loc), pln.Project(dir), ext);
#if DEBUG
                        DebuggerContainer dc = new DebuggerContainer();
                        dc.Add(c2d);
                        dc.Add(ll);
#endif
                        GeoPoint2DWithParameter[] gpp = ll.Intersect(c2d);
                        ips         = new GeoPoint[gpp.Length];
                        uvOnFaces   = new GeoPoint2D[gpp.Length];
                        uOnCurve3Ds = new double[gpp.Length];
                        for (int i = 0; i < gpp.Length; ++i)
                        {
                            ips[i]         = pln.ToGlobal(gpp[i].p);
                            uvOnFaces[i]   = PositionOf(ips[i]);
                            uOnCurve3Ds[i] = curve.PositionOf(ips[i]);
                        }
                    }
                    else
                    {
                        ips         = new GeoPoint[0];
                        uvOnFaces   = new GeoPoint2D[0];
                        uOnCurve3Ds = new double[0];
                    }
#if DEBUG
                    //GeoPoint[] ipsdbg;
                    //GeoPoint2D[] uvOnFacesdbg;
                    //double[] uOnCurve3Dsdbg;
                    //base.Intersect(curve, out ipsdbg, out uvOnFacesdbg, out uOnCurve3Dsdbg);
#endif
                    return;
                }
            }
            TetraederHull th = new TetraederHull(curve);
            // alle Kurven müssten eine gemeinsame basis habe, auf die man sich hier beziehen kann
            // damit die TetraederHull nicht mehrfach berechnet werden muss
            th.PlaneIntersection(this, out ips, out uvOnFaces, out uOnCurve3Ds);
            // base.Intersect(curve, out ips, out uvOnFaces, out uOnCurve3Ds);
        }
Example #3
0
        static public CurveGraph CrackCurves(GeoObjectList l, Plane plane, double maxGap)
        {   // alle Kurven in l werden in die Ebene plane projiziert. Das ist mal ein erster Ansatz
            // Man könnte auch gemeinsame Ebenen finden u.s.w.
            ArrayList    curves = new ArrayList();
            BoundingRect ext    = BoundingRect.EmptyBoundingRect;

            foreach (IGeoObject go in l)
            {
                ICurve cv = go as ICurve;
                if (cv != null)
                {
                    ICurve2D cv2 = cv.GetProjectedCurve(plane);
                    if (cv2 != null)
                    {
                        // "3d" wird nur verwendet um hinterher aus den Originalkurven die Ebene zu bestimmen
                        // in die alles zurücktranformiert wird. Besser würde man vermutlich mit "plane" arbeiten
                        // so wie es hier reinkommt.
                        if (cv2 is Path2D && (cv2 as Path2D).GetSelfIntersections().Length > 0)
                        {   // ein sich selbst überschneidender Pfad muss aufgelöst werden
                            ICurve2D[] sub = (cv2 as Path2D).SubCurves;
                            curves.AddRange(sub);
                            for (int i = 0; i < sub.Length; ++i)
                            {
                                sub[i].UserData.Add("3d", cv);
                            }
                            ext.MinMax(cv2.GetExtent());
                        }
                        else
                        {
                            cv2.UserData.Add("3d", cv);
                            curves.Add(cv2);
                            ext.MinMax(cv2.GetExtent());
                        }
                    }
                }
            }
            if (curves.Count == 0)
            {
                return(null);
            }
            QuadTree qt = new QuadTree(ext);

            qt.MaxDeepth  = 8;
            qt.MaxListLen = 3;
            for (int i = 0; i < curves.Count; ++i)
            {
                qt.AddObject(curves[i] as ICurve2D);
            }
            // jetzt alle mit allen schneiden und die Schnipsel in eine weitere Liste stecken
            ArrayList snippet = new ArrayList();

            for (int i = 0; i < curves.Count; ++i)
            {
                ICurve2D    cv1 = curves[i] as ICurve2D;
                ArrayList   intersectionPoints = new ArrayList(); // double
                ICollection closecurves        = qt.GetObjectsCloseTo(cv1);
                foreach (ICurve2D cv2 in closecurves)
                {
                    if (cv2 != cv1)
                    {
                        //if ((cv1 is Line2D && (cv1 as Line2D).Length > 10 && (cv1 as Line2D).Length < 15) ||
                        //    (cv2 is Line2D && (cv2 as Line2D).Length > 10 && (cv2 as Line2D).Length < 15))
                        //{
                        //}
                        GeoPoint2DWithParameter[] isp = cv1.Intersect(cv2);
                        for (int k = 0; k < isp.Length; ++k)
                        {
                            if (cv2.IsParameterOnCurve(isp[k].par2) && 0.0 < isp[k].par1 && isp[k].par1 < 1.0)
                            {
                                intersectionPoints.Add(isp[k].par1);
                            }
                        }
                    }
                }
                if (intersectionPoints.Count == 0)
                {
                    snippet.Add(cv1);
                }
                else
                {
                    intersectionPoints.Add(0.0);
                    intersectionPoints.Add(1.0); // damit sinds mindesten 3
                    double[] pps = (double[])intersectionPoints.ToArray(typeof(double));
                    Array.Sort(pps);
                    for (int ii = 1; ii < pps.Length; ++ii)
                    {
                        if (pps[ii - 1] < pps[ii])
                        {
                            ICurve2D cv3 = cv1.Trim(pps[ii - 1], pps[ii]);
                            if (cv3 != null)
                            {
#if DEBUG
                                GeoPoint2D dbg1 = cv1.PointAt(pps[ii - 1]);
                                GeoPoint2D dbg2 = cv1.PointAt(pps[ii]);
                                GeoPoint2D dbg3 = cv3.StartPoint;
                                GeoPoint2D dbg4 = cv3.EndPoint;
                                double     d1   = dbg1 | dbg3;
                                double     d2   = dbg2 | dbg4;
#endif
                                cv3.UserData.Add("3d", cv1.UserData.GetData("3d"));
                                snippet.Add(cv3);
                            }
                        }
                    }
                }
            }
            // snippet ist jetzt die Liste aller Schnipsel
            return(new CurveGraph((ICurve2D[])snippet.ToArray(typeof(ICurve2D)), maxGap));
        }
Example #4
0
        /// <summary>
        /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.Orientation (GeoPoint)"/>
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public override double Orientation(GeoPoint p)
        {   // soll vermutlich feststellen ob außerhalb oder innerhalb der Fläche im Bezug auf die Achse
            // Richards code verwendet das aufwendige GetLineIntersection.
            // Hier die bessere Version, die das Problem ins zweidimensionale projiziert:
            GeoPoint     up = fromSurface * p;
            double       x = Math.Sqrt(up.z * up.z + up.x * up.x);
            double       y = up.y;
            GeoPoint2D   toCeck = new GeoPoint2D(x, y);
            BoundingRect ext = basisCurve2D.GetExtent();
            GeoPoint2D   sp, ep;

            if (ext.Left > 0)
            {
                sp = new GeoPoint2D(ext.Left, y);
                ep = new GeoPoint2D(ext.Right, y);
            }
            else
            {
                sp = new GeoPoint2D(ext.Right, y);
                ep = new GeoPoint2D(ext.Left, y);
            }
            GeoPoint2DWithParameter[] isp = basisCurve2D.Intersect(sp, ep);
            // muss die Kurve immer rechts von der Achse liegen? Durch sp und ep sid wir davon unabhängig, es sei denn die Kurve schneidet die Achse
            SortedList <double, GeoPoint2D> par = new SortedList <double, GeoPoint2D>();

            for (int i = 0; i < isp.Length; ++i)
            {
                if (isp[i].par2 >= 0.0 && isp[i].par2 <= 1.0 && isp[i].par1 >= 0.0 && isp[i].par1 <= 1.0)
                {                                // nur wenn echter Schnitt
                    par[isp[i].par2] = isp[i].p; // nach Position auf der horizontalen Linie
                }
            }
            if (par.Count == 0)
            {
                return(0.0);                // Seite kann nicht bestimmt werden, da völlig außerhalb. Das Vorzeichen von 0.0
            }
            // ist aber verschieden von +1 und von -1, so dass wenn es andere konkrete Punkte gibt also ein Test gemacht wird
            double ppar = Geometry.LinePar(sp, ep, toCeck);

            for (int i = 0; i < par.Count; ++i)
            {
                if (ppar < par.Keys[i])
                {
                    if ((i & 1) == 0)                      // gerade, also innerhalb
                    {
                        return(-(toCeck | par.Values[i])); // innerhalb ist negativ
                    }
                    else
                    {
                        return(toCeck | par.Values[i]);  // außerhalb positiv
                    }
                }
            }
            // größer als alle
            if ((par.Count & 1) == 1)                       // ungerade, also letzer Punkt innerhalb
            {
                return(toCeck | par.Values[par.Count - 1]); // außerhalb positiv
            }
            else
            {
                return(-(toCeck | par.Values[par.Count - 1])); // innerhalb ist negativ
            }
            // Richards code:
            //GeoPoint gp = fromSurface * p;
            //double d = gp.y;
            //double e = Math.Abs(d);
            //GeoPoint ac = new GeoPoint(0, d, 0);
            //GeoPoint2D[] sp = GetLineIntersection(p, toSurface * (ac - gp));
            //int n = 0;
            //for (int i = 0; i < sp.Length; ++i)
            //{
            //    double ds = (sp[i] - GeoPoint2D.Origin).Length - e;
            //    if (Math.Abs(ds) > Precision.eps)
            //    {
            //        if (ds < 0)
            //            n++;
            //    }
            //    else return 0;
            //}
            //if (n % 4 == 2)
            //    return (-e);
            //else
            //    return e;
        }