Exemple #1
0
        public List <GeoPoint2D> GetReduced(double precision)
        {
            QuadTree <GeoPoint2DQt> qt = new QuadTree <GeoPoint2DQt>();

            for (int i = 0; i < list.Count; i++)
            {
                GeoPoint2DQt   p     = new GeoPoint2DQt(list[i]);
                GeoPoint2DQt[] close = qt.GetObjectsCloseTo(p);
                bool           found = false;
                for (int j = 0; j < close.Length; j++)
                {
                    if ((close[j].p | list[i]) <= precision)
                    {
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    qt.AddObject(p);
                }
            }
            GeoPoint2DQt[]    all = qt.GetAllObjects();
            List <GeoPoint2D> res = new List <GeoPoint2D>(all.Length);

            for (int i = 0; i < all.Length; i++)
            {
                res.Add(all[i].p);
            }
            return(res);
        }
Exemple #2
0
    /// <summary>
    /// 案例1:添加N个圆形区域
    /// </summary>
    void Case1()
    {
        _case = 1;
        _quadTree.Init(new Rect(0, 0, MapSize, MapSize));
        for (var i = 0; i < ObjectCount; i++)
        {
            var radius = Random.Range(1, ObjectSize);
            var pos    = new float2(Random.Range(-MapSize / 2, MapSize / 2), Random.Range(-MapSize / 2, MapSize / 2));
            _quadTree.AddObject(new TestQuadTreeData(), new Circle(radius, pos));
            if (Debug)
            {
                var obj = Instantiate(Sphere);
                obj.hideFlags            = HideFlags.HideInHierarchy | HideFlags.HideInInspector;
                obj.name                 = "Sphere:" + i;
                obj.transform.position   = new Vector3(pos.x, 0, pos.y);
                obj.transform.localScale = new Vector3(radius, radius, radius);
            }
        }

        if (Debug)
        {
            _quadTree.Output(10);
        }
        _quadTree.FakeClear();
    }
Exemple #3
0
    public void Subdivide()
    {
        if (objectList.Count > maxObjs && childern == null && width > minSize && height > minSize)
        {
            float x1 = bbox.xmin;
            float x2 = bbox.xmin + 0.5f * width;
            float x3 = bbox.xmax;
            float y1 = bbox.ymin;
            float y2 = bbox.ymin + height * 0.5f;
            float y3 = bbox.ymax;

            childern = new QuadTree[4];
            BBox tlBBox = new BBox(x1, x2, y2, y3);
            BBox trBBox = new BBox(x2, x3, y2, y3);
            BBox brBBox = new BBox(x2, x3, y1, y2);
            BBox blBBox = new BBox(x1, x2, y1, y2);

            QuadTree tl = new QuadTree(this, tlBBox, level + 1);
            QuadTree tr = new QuadTree(this, trBBox, level + 1);
            QuadTree br = new QuadTree(this, brBBox, level + 1);
            QuadTree bl = new QuadTree(this, blBBox, level + 1);

            foreach (PPObject obj in objectList)
            {
                tl.AddObject(obj);
                tr.AddObject(obj);
                br.AddObject(obj);
                bl.AddObject(obj);
            }

            childern[0] = tl;
            childern[1] = tr;
            childern[2] = br;
            childern[3] = bl;

            objectList = new List <PPObject>();

            leaf = false;
        }
        else if (childern != null)
        {
            PushToChildern();
        }
    }
Exemple #4
0
    /// <summary>
    /// 案例8:添加N个任意朝向的矩形区域
    /// 删除随机区域内的矩形
    /// 调用FindNearObject方法获取Start节点附近的对象
    /// (拖动StartPos可以颜色发生变化的就是查询结果)
    /// </summary>
    void Case8()
    {
        _case = 8;
        _quadTree2.Init(new Rect(0, 0, MapSize, MapSize));
        for (var i = 0; i < ObjectCount; i++)
        {
            var size    = new float2(Random.Range(1, ObjectSize), Random.Range(1, ObjectSize));
            var pos     = new float2(Random.Range(-MapSize / 2, MapSize / 2), Random.Range(-MapSize / 2, MapSize / 2));
            var forward = math.normalizesafe(new float2(Random.Range(-1f, 1f), Random.Range(-1f, 1f)));
            if (math.lengthsq(forward) < 0.1f)
            {
                forward = new float2(0, 1);
            }

            //if (Debug)
            {
                var obj = Instantiate(Cube);
                obj.hideFlags            = HideFlags.HideInHierarchy | HideFlags.HideInInspector;
                obj.name                 = "Cube:" + i;
                obj.transform.position   = new Vector3(pos.x, 0, pos.y);
                obj.transform.localScale = new Vector3(size.x * 2, 1, size.y * 2);
                obj.transform.rotation   =
                    quaternion.LookRotation(new float3(forward.x, 0, forward.y), new float3(0, 1, 0));
                _quadTree2.AddObject(new TestData2()
                {
                    Obstacle = obj
                }, new AnyForwardRect(size, pos, forward));
            }
        }

        for (var i = 0; i < ObjectCount; i++)
        {
            var size = new float2(Random.Range(1, ObjectSize), Random.Range(1, ObjectSize));
            var pos  = new float2(Random.Range(-MapSize / 2, MapSize / 2), Random.Range(-MapSize / 2, MapSize / 2));
            _quadTree2.RemoveAllObjectsInRect(pos - size, pos + size);
        }
        _startPos = new GameObject("StartPos");
        if (Debug)
        {
            _quadTree2.Output(1000);
        }
    }
Exemple #5
0
        private void Insert(ICurve2D curve)
        {   // der Start- bzw. Endpunkt einer Kurve kommt in die Cluster Liste
            Joint lp = new Joint();

            lp.curve = curve;

            GeoPoint2D   p            = curve.StartPoint;
            BoundingRect CheckSp      = new BoundingRect(p, clusterSize, clusterSize);
            ICollection  StartCluster = clusterTree.GetObjectsFromRect(CheckSp);
            Cluster      InsertInto   = null;

            foreach (Cluster cl in StartCluster)
            {
                if (Geometry.Dist(cl.center, p) < clusterSize)
                {
                    InsertInto = cl;
                    clusterTree.RemoveObject(cl); // rausnehmen, da er u.U. größer wird und unten wieder eingefügt wird
                    break;
                }
            }
            if (InsertInto == null)
            {
                InsertInto = new Cluster();
                clusterSet.Add(InsertInto);
            }
            InsertInto.Joints.Add(lp);
            lp.StartCluster = InsertInto;
            double x = 0.0;
            double y = 0.0;

            for (int i = 0; i < InsertInto.Joints.Count; ++i)
            {
                GeoPoint2D pp;
                if ((InsertInto.Joints[i]).StartCluster == InsertInto)
                {
                    pp = (InsertInto.Joints[i]).curve.StartPoint;
                }
                else
                {
                    pp = (InsertInto.Joints[i]).curve.EndPoint;
                }
                x += pp.x;
                y += pp.y;
            }
            InsertInto.center = new GeoPoint2D(x / InsertInto.Joints.Count, y / InsertInto.Joints.Count);
            clusterTree.AddObject(InsertInto);

            // desgleichen mit dem Endpunkt:
            p            = curve.EndPoint;
            CheckSp      = new BoundingRect(p, clusterSize, clusterSize);
            StartCluster = clusterTree.GetObjectsFromRect(CheckSp);
            InsertInto   = null;
            foreach (Cluster cl in StartCluster)
            {
                if (Geometry.Dist(cl.center, p) < clusterSize)
                {
                    InsertInto = cl;
                    clusterTree.RemoveObject(cl); // rausnehmen, da er u.U. größer wird und unten wieder eingefügt wird
                    break;
                }
            }
            if (InsertInto == null)
            {
                InsertInto = new Cluster();
                clusterSet.Add(InsertInto);
            }
            InsertInto.Joints.Add(lp);
            lp.EndCluster = InsertInto;
            x             = 0.0;
            y             = 0.0;
            for (int i = 0; i < InsertInto.Joints.Count; ++i)
            {
                GeoPoint2D pp;
                if ((InsertInto.Joints[i]).StartCluster == InsertInto)
                {
                    pp = (InsertInto.Joints[i]).curve.StartPoint;
                }
                else
                {
                    pp = (InsertInto.Joints[i]).curve.EndPoint;
                }
                x += pp.x;
                y += pp.y;
            }
            InsertInto.center = new GeoPoint2D(x / InsertInto.Joints.Count, y / InsertInto.Joints.Count);
            clusterTree.AddObject(InsertInto);
        }
Exemple #6
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));
        }
Exemple #7
0
 public void Add(IQuadTreeInsertableZ toAdd)
 {
     allObjects.AddObject(toAdd);
     extent.MinMax(toAdd.GetExtent());
 }