예제 #1
0
        private int getx2y2()
        {
            long xy = _x * _x + _y * _y;

            xy = xy < 0 ? -xy : xy;

            int v = KMath.isqrt(xy);

            return(v);
        }
예제 #2
0
        public Segment(KInt2 first, KInt2 second, int id)
        {
            this.start = first;
            this.end   = second;
            cachedir   = null;
            uid        = id;

            this.MinX = KMath.Min(this.start.IntX, this.end.IntX);
            this.MaxX = KMath.Max(this.start.IntX, this.end.IntX);
            this.MinY = KMath.Min(this.start.IntY, this.end.IntY);
            this.MaxY = KMath.Max(this.start.IntY, this.end.IntY);
        }
예제 #3
0
        void RemoveUnused()
        {
            //sort
            BeginSample("SortByXcoordinate");
            SortByXcoordinate(segments);
            EndSample();
            BeginSample("connectlines check");
            HashSet <KInt2> allpoints = new HashSet <KInt2> ();
            Dictionary <KInt2, HashSet <KInt2> > connectlines = new Dictionary <KInt2, HashSet <KInt2> >(segments.Count);

            for (int i = 0; i < segments.Count; ++i)
            {
                Segment seg = segments [i];
                if (allpoints.Add(seg.start))
                {
                    connectlines [seg.start] = new HashSet <KInt2> ();
                }

                if (allpoints.Add(seg.end))
                {
                    connectlines [seg.end] = new HashSet <KInt2> ();
                }
            }


            KInt2 p1, p2, p3;

            for (int i = 0; i < segments.Count; ++i)
            {
                Segment firstline = segments [i];
                for (int j = i + 1; j < segments.Count; ++j)
                {
                    Segment secondline = segments [j];
                    if (firstline.MinX > secondline.MaxX)
                    {
                        break;
                    }

                    long maxminy = KMath.Max(firstline.MinY, secondline.MinY);
                    long minmaxy = KMath.Min(firstline.MaxY, secondline.MaxY);
                    if (maxminy > minmaxy)
                    {
                        continue;
                    }

                    if (Segment.isConnectRetPoints(firstline, secondline, out p1, out p2, out p3))
                    {
                        //only three point

                        connectlines [p1].Add(p2);
                        connectlines [p1].Add(p3);
                    }
                }

                ShowProgress("创建链接点", (float)i / segments.Count);
            }

            EndSample();
            this.segments.Clear();

            HashSet <Segment> realList    = new HashSet <Segment> ();
            List <KInt2>      linequeue   = new List <KInt2> (segments.Count);
            HashSet <KInt2>   openlist    = new HashSet <KInt2> ();
            HashSet <KInt2>   enabledlist = new HashSet <KInt2> ();

            BeginSample("combine polygon check");
            int progress = 0;
            var pointen  = allpoints.GetEnumerator();

            while (pointen.MoveNext())
            {
                KInt2 pt = pointen.Current;

                if (enabledlist.Contains(pt) || connectlines [pt].Count < 2)
                {
                    continue;
                }
                openlist.Clear();
                linequeue.Clear();

                linequeue.Add(pt);
                if (TryConnectUntilFindTarget(pt, pt, linequeue, openlist, connectlines))
                {
                    if (!isAllLine(linequeue))
                    {
                        AddtoList(realList, linequeue);
                        for (int k = 0; k < linequeue.Count; ++k)
                        {
                            enabledlist.Add(linequeue [k]);
                        }
                    }
                    else
                    {
#if UNITY_EDITOR
                        if (ObstacleDebug >= DebugMode.ShowAndLog)
                        {
                            LogMgr.LogFormat("准备剔除 原始目标点 为 :{0}", pt);
                            for (int k = 0; k < linequeue.Count; ++k)
                            {
                                LogMgr.LogFormat("准备剔除 :{0}", linequeue [k]);
                            }
                            LogMgr.Log("剔除结束");
                        }
#endif
                    }
                }
                progress++;
                ShowProgress("检测非多边形点", (float)progress / allpoints.Count);
            }
            EndSample();

            segments.Capacity = realList.Count;

            var realen = realList.GetEnumerator();
            while (realen.MoveNext())
            {
                segments.Add(realen.Current);
            }

            if (ExactMode >= ExactType.TWO)
            {
                BeginSample("PolygonIntersect");
                PolygonIntersect();
                EndSample();
            }
        }
예제 #4
0
 long doublearea(KInt2 p1, KInt2 p2, KInt2 p3)
 {
     return(KMath.Abs((p1.IntX * (p2.IntY - p3.IntY) + p2.IntX * (p3.IntY - p1.IntY) + p3.IntX * (p1.IntY - p2.IntY))));
 }
예제 #5
0
        void PolygonIntersect()
        {
            //相交检测
            BeginSample("PolygonIntersect - SegmentIntersect");

            this.SortByXcoordinate(segments);

            List <Segment> removeList = new List <Segment> (segments.Count / 2);
            Dictionary <Segment, intersectCls>     SegPointsdict = new Dictionary <Segment, intersectCls> (segments.Count / 2);
            Dictionary <KInt2, HashSet <Segment> > dic           = new Dictionary <KInt2, HashSet <Segment> >();

            for (int i = 0; i < segments.Count; ++i)
            {
                Segment firstline = segments [i];
                for (int j = i + 1; j < segments.Count; ++j)
                {
                    Segment secondline = segments [j];

                    if (firstline.MinX > secondline.MaxX)
                    {
                        break;
                    }

                    long maxminy = KMath.Max(segments[i].MinY, segments[j].MinY);
                    long minmaxy = KMath.Min(segments[i].MaxY, segments[j].MaxY);
                    if (maxminy > minmaxy)
                    {
                        continue;
                    }

                    KInt2 result;
                    if (!firstline.isConnect(secondline) && Segment.Intersect(firstline.start, firstline.end, secondline.start, secondline.end, out result))
                    {
                        if (dic.ContainsKey(result))
                        {
                            dic[result].Add(firstline);
                            dic[result].Add(secondline);
                        }
                        else
                        {
                            HashSet <Segment> hashdata = new HashSet <Segment>();
                            hashdata.Add(firstline);
                            hashdata.Add(secondline);
                            dic[result] = hashdata;
                        }

                        if (firstline.start != result && firstline.end != result)
                        {
                            if (SegPointsdict.ContainsKey(firstline))
                            {
                                SegPointsdict [firstline].points.TryAdd(result);
                            }
                            else
                            {
                                intersectCls data = new intersectCls();
                                data.points.Add(result);
                                data.intersectseg         = secondline;
                                SegPointsdict [firstline] = data;
                            }

                            removeList.Add(firstline);
                        }

                        if (secondline.start != result && secondline.end != result)
                        {
                            if (SegPointsdict.ContainsKey(secondline))
                            {
                                SegPointsdict [secondline].points.TryAdd(result);
                            }
                            else
                            {
                                intersectCls data = new intersectCls();
                                data.points.Add(result);
                                data.intersectseg          = firstline;
                                SegPointsdict [secondline] = data;
                            }
                            removeList.Add(secondline);
                        }

                        // LogMgr.LogError("first =>" + firstline.uid + " => " + secondline.uid);
                    }
                }

                ShowProgress("相交检测", (float)i / segments.Count);
            }

            EndSample();

            //remove old segments  即使有重复也无所谓,减少多次检查的开销
            for (int i = 0; i < removeList.Count; ++i)
            {
                segments.Remove(removeList [i]);
            }

            BeginSample("PolygonIntersect - SortAndAdd2Segments");
            SortAndAdd2Segments(SegPointsdict);
            EndSample();


            DefineIDforSegments(segments);
            //
            BeginSample("Build - TriangleTree");
            tree = new TriangleTree();
            tree.Build(ObsTriangles, 2);
            EndSample();
            //
            List <NavmeshTriangle> testtriangles = new List <NavmeshTriangle> (10);
            List <KInt2>           nearestidxs   = new List <KInt2>(10);

            removeList.Clear();

            BeginSample("Build - Test Triangle");
            for (int i = 0; i < segments.Count; ++i)
            {
                Segment seg = segments [i];
                testtriangles.Clear();
                nearestidxs.Clear();

                tree.ball_queryPoints((seg.start + seg.end) / 2, Seekrange, nearestidxs);
                for (int k = 0; k < nearestidxs.Count; ++k)
                {
                    List <NavmeshTriangle> list = point2triangle [nearestidxs [k]];
                    for (int v = 0; v < list.Count; ++v)
                    {
                        testtriangles.Add(list [v]);
                    }
                }

                ShowProgress("获取邻近三角形", (float)i / segments.Count);

                TriangleCheck(testtriangles, dic, removeList, seg);
            }

            EndSample();
            //
#if UNITY_EDITOR
            willremoveList.AddRange(removeList);
#endif
            for (int i = 0; i < removeList.Count; ++i)
            {
                segments.Remove(removeList [i]);
            }
        }