Beispiel #1
0
        // 区域相交
        private bool isRegionCross(MBR m1, MBR m2)
        {
            /*
             * [矩形相交](https://blog.csdn.net/qq_40482358/article/details/86537747)
             * cx1=max(ax1,bx1)         //左下x为最大的左下x集合
             * cy1=max(ay1,by1)         //左下y为最大的左下y集合
             * cx2=min(ax2,bx2)         //右上x为最小的右上x集合
             * cy2=min(ay2,by2)         //右上y为最小的右上y集合
             * 矩形相交后仍然是矩形
             */
            float cx1 = Math.Max(m1.left, m2.left);
            float cy1 = Math.Max(m1.bottom, m2.bottom);
            float cx2 = Math.Min(m1.right, m2.right);
            float cy2 = Math.Min(m1.top, m2.top);

            if (cx1 > cx2)
            {
                return(false);
            }
            if (cy1 > cy2)
            {
                return(false);
            }

            return(true);
        }
Beispiel #2
0
 private bool isPointInRegion(float x, float z, MBR mbr)
 {
     //
     if (x < mbr.left || x > mbr.right || z > mbr.top || z < mbr.bottom)
     {
         return(false);
     }
     return(true);
 }
Beispiel #3
0
        // 初始化四叉树范围
        public void Init(MBR mbr)
        {
            if (null != _root)
            {
                return;
            }
            _root          = new QuadNode();
            _root.mbr      = mbr;
            _root.Quadrant = EQuadrant.ROOT;
            _root.Level    = 0;

            // debug
            LevelCnt           = new Dictionary <int, int>();
            TotalCnt           = 0;
            CorssCircleTestCnt = 0;
            // debug
        }
Beispiel #4
0
        // 判断mbr和圆是否相交
        private bool isCrossCricle(MBR mbr, Circle circle)
        {
            CorssCircleTestCnt++;
            // 1. 矩形的四点判断 点在圆内
            // 2. 矩形的四边判断 边与圆相交
            // [算法](https://www.cnblogs.com/llkey/p/3707351.html)

            // 01 点在圆内
            if (isPointInCricle(mbr.left, mbr.top, circle))
            {
                return(true);
            }
            else if (isPointInCricle(mbr.right, mbr.top, circle))
            {
                return(true);
            }
            else if (isPointInCricle(mbr.right, mbr.bottom, circle))
            {
                return(true);
            }
            else if (isPointInCricle(mbr.left, mbr.bottom, circle))
            {
                return(true);
            }

            // 02 边与圆相交
            float rec_x  = (mbr.right - mbr.left) * 0.5f;
            float rec_z  = (mbr.top - mbr.bottom) * 0.5f;
            float deltaX = Math.Abs(rec_x - circle.x);
            float deltaZ = Math.Abs(rec_z - circle.z);

            if (deltaX * deltaX + deltaZ * deltaZ <= circle.radius * circle.radius)
            {
                return(true);
            }

            // 03 圆点在矩形内
            if (isPointInRegion(circle.x, circle.z, mbr))
            {
                return(true);
            }


            return(false);
        }
Beispiel #5
0
 // mbr被圆包围
 private bool isInCircle(MBR mbr, Circle circle)
 {
     CorssCircleTestCnt++;
     if (false == isPointInCricle(mbr.left, mbr.top, circle))
     {
         return(false);
     }
     if (false == isPointInCricle(mbr.right, mbr.top, circle))
     {
         return(false);
     }
     if (false == isPointInCricle(mbr.right, mbr.bottom, circle))
     {
         return(false);
     }
     if (false == isPointInCricle(mbr.left, mbr.bottom, circle))
     {
         return(false);
     }
     return(true);
 }
Beispiel #6
0
        // 象限分裂
        // 分裂后,node节点的数据,尝试插入到子象限内
        private void split(QuadNode node)
        {
            // 已经分裂过了
            if (null != node.Sub)
            {
                return;
            }
            // 分裂为四个象限

            /*
             |
             |
             |      UL    |    UR
             |  ---------------------
             |
             |      LL    |    LR
             |
             |
             */
            // mbr = (x,z,w,l)
            var   mbr    = node.mbr;
            float hw     = (mbr.right - mbr.left) * 0.5f;
            float hl     = (mbr.top - mbr.bottom) * 0.5f;
            var   mbr_ur = new MBR(mbr.right - hw, mbr.right, mbr.top, mbr.top - hl);
            var   mbr_ul = new MBR(mbr.left, mbr.left + hw, mbr.top, mbr.top - hl);
            var   mbr_ll = new MBR(mbr.left, mbr.left + hw, mbr.bottom + hl, mbr.bottom);
            var   mbr_lr = new MBR(mbr.right - hw, mbr.right, mbr.bottom + hl, mbr.bottom);

            node.Sub    = new QuadNode[4];
            node.Sub[0] = new QuadNode()
            {
                Level = node.Level + 1, Quadrant = EQuadrant.UR, Cnt = 0, mbr = mbr_ur, Child = null, Sub = null,
            };
            node.Sub[1] = new QuadNode()
            {
                Level = node.Level + 1, Quadrant = EQuadrant.UL, Cnt = 0, mbr = mbr_ul, Child = null, Sub = null,
            };
            node.Sub[2] = new QuadNode()
            {
                Level = node.Level + 1, Quadrant = EQuadrant.LL, Cnt = 0, mbr = mbr_ll, Child = null, Sub = null,
            };
            node.Sub[3] = new QuadNode()
            {
                Level = node.Level + 1, Quadrant = EQuadrant.LR, Cnt = 0, mbr = mbr_lr, Child = null, Sub = null,
            };

            if (node.Level + 1 > Current_Max_Level)
            {
                Current_Max_Level = node.Level + 1;
            }

            // 尝试插入当前节点的child
            TotalCnt             -= node.Cnt;
            LevelCnt[node.Level] -= node.Cnt;
            node.Cnt              = 0;
            if (node.Child != null)
            {
                var tmp  = node.Child;
                var tmp1 = tmp.Next;
                node.Child = null;
                while (null != tmp)
                {
                    Add(tmp);
                    tmp = tmp1;
                    if (null != tmp)
                    {
                        tmp1     = tmp.Next;
                        tmp.Next = null;
                    }
                }
            }
        }