Пример #1
0
        public static Mesh DelaunayTriangulate(this PlainShape shape, IntGeom iGeom)
        {
            int n        = shape.points.Length;
            var vertices = new Vector3[n];

            for (int i = 0; i < n; ++i)
            {
                var v = iGeom.Float(shape.points[i]);
                vertices[i] = new Vector3(v.x, v.y, 0);
            }
            var extraPoints = new NativeArray <IntVector>(0, Allocator.Temp);
            var delaunay    = shape.Delaunay(0, extraPoints, Allocator.Temp);

            extraPoints.Dispose();

            var nTriangles = delaunay.Indices(Allocator.Temp);

            delaunay.Dispose();

            var mesh = new Mesh {
                vertices  = vertices,
                triangles = nTriangles.ToArray()
            };

            nTriangles.Dispose();

            return(mesh);
        }
Пример #2
0
        public IntShape(PlainShape plainShape)
        {
            var hullLayout = plainShape.layouts[0];

            this.hull = new IntVector[hullLayout.end - 1];
            for (int i = 0; i < hullLayout.end; ++i)
            {
                this.hull[i] = plainShape.points[i];
            }

            int holesCount = plainShape.layouts.Length - 1;

            this.holes = new IntVector[holesCount][];
            for (int i = 0; i < holesCount; ++i)
            {
                var layout = plainShape.layouts[i + 1];
                int n      = layout.end - layout.begin + 1;
                var points = new IntVector[n];
                for (int j = 0; j < n; ++j)
                {
                    points[j] = plainShape.points[j + layout.begin];
                }
                this.holes[i] = points;
            }
        }
Пример #3
0
        private NativeArray <int> Triangulate(int index)
        {
            var iGeom = IntGeom.DefGeom;

            var data = ComplexTests.data[index];

            var hull  = iGeom.Int(data[0]);
            var holes = new IntVector[data.Length - 1][];

            for (int i = 1; i < data.Length; ++i)
            {
                holes[i - 1] = iGeom.Int(data[i]);
            }

            var iShape = new IntShape(hull, holes);
            var pShape = new PlainShape(iShape, Allocator.Temp);

            var triangles = pShape.Triangulate(Allocator.Temp);

            Assert.IsTrue(Triangle.IsCCW(pShape.points, triangles));

            pShape.Dispose();

            return(triangles);
        }
Пример #4
0
        public static NativeArray <int> Triangulate(this PlainShape shape, NativeArray <IntVector> extraPoints, Allocator allocator)
        {
            var layout     = shape.Split(0, extraPoints, Allocator.Temp);
            int totalCount = shape.points.Length + ((shape.layouts.Length - 2) << 1);

            int trianglesCount = 3 * totalCount;

            var triangles = new NativeArray <int>(trianglesCount, allocator);
            int counter   = 0;

            for (int i = 0; i < layout.indices.Length; ++i)
            {
                int index = layout.indices[i];
                Triangulate(index, ref counter, layout.links, triangles);
            }

            layout.Dispose();

            if (counter == trianglesCount)
            {
                return(triangles);
            }
            else
            {
                var newTriangles = new NativeArray <int>(counter, allocator);
                newTriangles.Slice(0, counter).CopyFrom(triangles.Slice(0, counter));
                triangles.Dispose();
                return(newTriangles);
            }
        }
Пример #5
0
        private static SplitLayout Split(this PlainShape self, long maxEgeSize, Allocator allocator)
        {
            var originalCount = self.points.Length;
            var nodes         = new DynamicArray <Node>(originalCount, allocator);
            var layouts       = new DynamicArray <PathLayout>(originalCount, allocator);
            var sqrMaxSize    = maxEgeSize * maxEgeSize;

            var begin         = 0;
            var originalIndex = 0;
            var extraIndex    = originalCount;

            for (int j = 0; j < self.layouts.Length; ++j)
            {
                var layout = self.layouts[j];
                var last   = layout.end;
                var a      = self.points[last];
                var length = 0;

                for (int i = layout.begin; i <= layout.end; ++i)
                {
                    var b       = self.points[i];
                    var dx      = b.x - a.x;
                    var dy      = b.y - a.y;
                    var sqrSize = dx * dx + dy * dy;
                    if (sqrSize > sqrMaxSize)
                    {
                        var    l  = (long)Mathf.Sqrt(sqrSize);
                        int    s  = (int)(l / maxEgeSize);
                        double ds = s;
                        double sx = dx / ds;
                        double sy = dy / ds;
                        double fx = 0;
                        double fy = 0;
                        for (int k = 1; k < s; ++k)
                        {
                            fx += sx;
                            fy += sy;

                            long x = a.x + (long)fx;
                            long y = a.y + (long)fy;
                            nodes.Add(new Node(extraIndex, new IntVector(x, y)));
                            extraIndex += 1;
                        }

                        length += s - 1;
                    }

                    length += 1;
                    nodes.Add(new Node(originalIndex, b));
                    originalIndex += 1;
                    a              = b;
                }

                layouts.Add(new PathLayout(begin, length, layout.isClockWise));
                begin += length;
            }

            return(new SplitLayout(layouts.Convert(), nodes.Convert()));
        }
Пример #6
0
        public static List ConvexPolygons(this PlainShape self, Allocator allocator, IntGeom intGeom)
        {
            var delaunay = self.Delaunay(Allocator.Temp);
            var list     = delaunay.ConvexPolygons(intGeom, allocator);

            delaunay.Dispose();
            return(list);
        }
Пример #7
0
        public static Delaunay Delaunay(this PlainShape shape, Allocator allocator)
        {
            var extraPoints = new NativeArray <IntVector>(0, Allocator.Temp);
            var delaunay    = shape.Delaunay(0, extraPoints, allocator);

            extraPoints.Dispose();
            return(delaunay);
        }
Пример #8
0
        public static NativeArray <int> Triangulate(this PlainShape shape, Allocator allocator)
        {
            var extraPoints = new NativeArray <IntVector>(0, Allocator.Temp);
            var triangles   = Triangulate(shape, extraPoints, allocator);

            extraPoints.Dispose();
            return(triangles);
        }
Пример #9
0
        public static NativeArray <int> DelaunayTriangulate(this PlainShape shape, Allocator allocator, NativeArray <IntVector> extraPoints)
        {
            var delaunay  = shape.Delaunay(0, extraPoints, allocator);
            var triangles = delaunay.Indices(allocator);

            delaunay.Dispose();

            return(triangles);
        }
Пример #10
0
        private static SplitLayout Plain(this PlainShape self, Allocator allocator)
        {
            var nodes = new NativeArray <Node>(self.points.Length, allocator);

            for (int i = 0; i < self.points.Length; ++i)
            {
                nodes[i] = new Node(i, self.points[i]);
            }

            var layouts = new NativeArray <PathLayout>(self.layouts, allocator);

            return(new SplitLayout(layouts, nodes));
        }
Пример #11
0
        public static Delaunay Delaunay(this PlainShape shape, long maxEdge, NativeArray <IntVector> extraPoints, Allocator allocator)
        {
            var layout = shape.Split(maxEdge, extraPoints, Allocator.Temp);

            int holesCount = shape.layouts.Length;
            int totalCount = layout.pathCount + 2 * layout.extraCount + holesCount * 2 - 2;

            var triangleStack = new TriangleStack(totalCount, allocator);

            for (int i = 0; i < layout.indices.Length; ++i)
            {
                int index = layout.indices[i];
                Triangulate(index, layout.links, ref triangleStack);
                triangleStack.Reset();
            }

            var triangles = triangleStack.Convert();

            var sliceBuffer = new SliceBuffer(layout.links.Length, layout.slices, Allocator.Temp);

            sliceBuffer.AddConnections(triangles);

            sliceBuffer.Dispose();
            layout.Dispose();

            Delaunay delaunay;

            if (extraPoints.Length == 0 && maxEdge == 0)
            {
                delaunay = new Delaunay(shape.points, triangles, allocator);
            }
            else
            {
                var points = new NativeArray <IntVector>(layout.links.Length, Allocator.Temp);
                for (int i = 0; i < layout.links.Length; ++i)
                {
                    var link = layout.links[i];
                    points[link.vertex.index] = link.vertex.point;
                }
                delaunay = new Delaunay(points, triangles, allocator);
                points.Dispose();
            }

            delaunay.Build();

            return(delaunay);
        }
        private NativeArray <int> Triangulate(int index)
        {
            var iGeom = IntGeom.DefGeom;

            var data    = MonotoneTests.data[index];
            var iPoints = iGeom.Int(data);

            var iShape = new IntShape(iPoints, new IntVector[0][]);
            var pShape = new PlainShape(iShape, Allocator.Temp);

            var triangles = pShape.Triangulate(Allocator.Temp);

            Assert.IsTrue(Triangle.IsCCW(pShape.points, triangles));

            pShape.Dispose();

            return(triangles);
        }
Пример #13
0
        public static List MakeCentroidNet(this PlainShape self, Allocator allocator, IntGeom intGeom, float maxEdge, float maxArea = 0, float minArea = 0, bool onlyConvex = false)
        {
            long  iEdge    = intGeom.Int(maxEdge);
            var   delaunay = self.Delaunay(iEdge, Allocator.Temp);
            float aMaxArea;

            if (maxArea > 0)
            {
                aMaxArea = maxArea;
            }
            else
            {
                aMaxArea = 0.4f * maxEdge * maxEdge;
            }

            delaunay.Tessellate(intGeom, aMaxArea);

            var iMinArea = intGeom.SqrInt(minArea);
            var shape    = delaunay.MakeCentroidNet(Allocator.Temp, iMinArea, onlyConvex);

            delaunay.Dispose();

            int n           = shape.layouts.Length;
            var dynamicList = new DynamicList(8 * n, n, allocator);

            for (int i = 0; i < n; ++i)
            {
                var iPath   = shape.Get(i);
                var path    = intGeom.Float(iPath, Allocator.Temp);
                var polygon = new Polygon(path, Allocator.Temp);
                dynamicList.Add(polygon);
            }

            shape.Dispose();

            return(dynamicList.Convert());
        }
        public void Invoke(NativeArray <Vector2> hull, NativeArray <Vector2> hole, bool isDelaunay)
        {
            var iGeom = IntGeom.DefGeom;

            var iHull  = iGeom.Int(hull.ToArray());
            var iHoles = new[] { iGeom.Int(hole.ToArray()) };

            var iShape = new IntShape(iHull, iHoles);
            var pShape = new PlainShape(iShape, Allocator.TempJob);

            int totalCount = pShape.points.Length * 3;

            var triangles = new NativeArray <int>(totalCount, Allocator.TempJob);
            var length    = new NativeArray <int>(1, Allocator.TempJob);

            this.job = new TriangulationJob {
                plainShape = pShape,
                isDelaunay = isDelaunay,
                triangles  = triangles,
                length     = length
            };

            this.jobHandle = this.job.Schedule();
        }
Пример #15
0
        public static MonotoneLayout Split(this PlainShape shape, long maxEdge, NativeArray <IntVector> extraPoints, Allocator allocator)
        {
            var navigator   = shape.GetNavigator(maxEdge, extraPoints, Allocator.Temp);
            var links       = new DynamicArray <Link>(navigator.links, allocator);
            var natures     = navigator.natures;
            var sortIndices = navigator.indices;

            int n = sortIndices.Length;

            var subs    = new DynamicArray <Sub>(8, Allocator.Temp);
            var dSubs   = new DynamicArray <DualSub>(8, Allocator.Temp);
            var indices = new DynamicArray <int>(16, allocator);
            var slices  = new DynamicArray <Slice>(16, allocator);

            int i = 0;

nextNode:
            while (i < n)
            {
                int sortIndex = sortIndices[i];
                var node      = links[sortIndex];
                var nature    = natures[sortIndex];

                int j;
                switch (nature)
                {
                case LinkNature.start:
                    subs.Add(new Sub(node));
                    ++i;
                    goto nextNode;

                case LinkNature.extra:
                    j = 0;

                    while (j < dSubs.Count)
                    {
                        var dSub = dSubs[j];
                        var pA   = dSub.next.vertex.point;
                        var pB   = links[dSub.next.next].vertex.point;
                        var pC   = links[dSub.prev.prev].vertex.point;
                        var pD   = dSub.prev.vertex.point;

                        var p = node.vertex.point;

                        if (IsTetragonContain(p, pA, pB, pC, pD))
                        {
                            var hand = links[dSub.middle];
                            slices.Add(new Slice(hand.vertex.index, node.vertex.index));
                            links.ConnectExtraPrev(hand.self, node.self);

                            dSubs[j] = new DualSub(links[dSub.next.self], node.self, links[dSub.prev.self]);

                            i += 1;
                            goto nextNode;
                        }

                        j += 1;
                    }   //  while dSubs

                    j = 0;

                    while (j < subs.Count)
                    {
                        var sub = subs[j];

                        var pA = sub.next.vertex.point;
                        var pB = links[sub.next.next].vertex.point;
                        var pC = links[sub.prev.prev].vertex.point;
                        var pD = sub.prev.vertex.point;

                        var p = node.vertex.point;

                        if (IsTetragonContain(p, pA, pB, pC, pD))
                        {
                            if (!sub.isEmpty)
                            {
                                if (pA.x > pD.x)
                                {
                                    var hand = sub.next;
                                    slices.Add(new Slice(hand.vertex.index, node.vertex.index));
                                    var newHandIndex = links.ConnectExtraNext(hand.self, node.self);
                                    dSubs.Add(new DualSub(links[newHandIndex], node.self, links[sub.prev.self]));
                                }
                                else
                                {
                                    var hand = sub.prev;
                                    slices.Add(new Slice(hand.vertex.index, node.vertex.index));
                                    var newHandIndex = links.ConnectExtraPrev(hand.self, node.self);
                                    dSubs.Add(new DualSub(links[sub.next.self], node.self, links[newHandIndex]));
                                }
                            }
                            else
                            {
                                var hand = links[sub.next.self];
                                slices.Add(new Slice(hand.vertex.index, b: node.vertex.index));
                                var newPrev = links.ConnectExtraPrev(hand.self, node.self);
                                dSubs.Add(new DualSub(links[hand.self], node.self, links[newPrev]));
                            }
                            subs.Exclude(j);
                            i += 1;
                            goto nextNode;
                        }

                        j += 1;
                    }
                    break;

                case LinkNature.merge:

                    var newNextSub = new Sub(true);
                    var newPrevSub = new Sub(true);

                    j = 0;

                    while (j < dSubs.Count)
                    {
                        var dSub = dSubs[j];

                        if (dSub.next.next == node.self)
                        {
                            var a      = node.self;
                            var b      = dSub.middle;
                            var bridge = links.Connect(a, b);

                            indices.Add(links.FindStart(bridge.a.self));

                            slices.Add(bridge.Slice);

                            var prevSub = new Sub(links[a], dSub.prev);

                            if (!newNextSub.isEmpty)
                            {
                                dSubs[j] = new DualSub(newNextSub, prevSub);
                                ++i;
                                goto nextNode;
                            }

                            dSubs.Exclude(j);

                            newPrevSub = prevSub;
                            continue;
                        }
                        else if (dSub.prev.prev == node.self)
                        {
                            var a = dSub.middle;
                            var b = node.self;

                            var bridge = links.Connect(a, b);

                            indices.Add(links.FindStart(bridge.a.self));
                            slices.Add(bridge.Slice);

                            var nextSub = new Sub(dSub.next, links[b]);

                            if (!newPrevSub.isEmpty)
                            {
                                dSubs[j] = new DualSub(nextSub, newPrevSub);
                                ++i;
                                goto nextNode;
                            }
                            dSubs.Exclude(j);

                            newNextSub = nextSub;
                            continue;
                        }

                        ++j;
                    }       //  while dSubs

                    j = 0;

                    while (j < subs.Count)
                    {
                        var sub = subs[j];

                        if (sub.next.next == node.self)
                        {
                            sub.next = node;

                            subs.Exclude(j);

                            if (!newNextSub.isEmpty)
                            {
                                dSubs.Add(new DualSub(newNextSub, sub));
                                ++i;
                                goto nextNode;
                            }

                            newPrevSub = sub;
                            continue;
                        }
                        else if (sub.prev.prev == node.self)
                        {
                            sub.prev = node;
                            subs.Exclude(j);

                            if (!newPrevSub.isEmpty)
                            {
                                dSubs.Add(new DualSub(sub, newPrevSub));
                                ++i;
                                goto nextNode;
                            }

                            newNextSub = sub;
                            continue;
                        }

                        ++j;
                    }
                    break;

                case LinkNature.split:

                    j = 0;

                    while (j < subs.Count)
                    {
                        var sub = subs[j];


                        var pA = sub.next.vertex.point;

                        var pB = links[sub.next.next].vertex.point;

                        var pC = links[sub.prev.prev].vertex.point;

                        var pD = sub.prev.vertex.point;


                        var p = node.vertex.point;

                        if (IsTetragonContain(p, pA, pB, pC, pD))
                        {
                            var a0 = sub.next.self;
                            var a1 = sub.prev.self;
                            var b  = node.self;

                            if (pA.x > pD.x)
                            {
                                var bridge = links.Connect(a0, b);

                                subs.Add(new Sub(bridge.b, links[a1]));

                                slices.Add(bridge.Slice);
                            }
                            else
                            {
                                var bridge = links.Connect(a1, b);

                                subs.Add(new Sub(bridge.b, bridge.a));
                                slices.Add(bridge.Slice);
                            }
                            subs[j] = new Sub(links[a0], links[b]);
                            ++i;
                            goto nextNode;
                        }

                        ++j;
                    }

                    j = 0;

                    while (j < dSubs.Count)
                    {
                        var dSub = dSubs[j];

                        var pA = dSub.next.vertex.point;

                        var pB = links[dSub.next.next].vertex.point;
                        var pC = links[dSub.prev.prev].vertex.point;
                        var pD = dSub.prev.vertex.point;
                        var p  = node.vertex.point;

                        if (IsTetragonContain(p, pA, pB, pC, pD))
                        {
                            var a = dSub.middle;

                            var b      = node.self;
                            var bridge = links.Connect(a, b);

                            subs.Add(new Sub(dSub.next, links[b]));
                            subs.Add(new Sub(bridge.b, dSub.prev));
                            slices.Add(bridge.Slice);
                            dSubs.Exclude(j);

                            ++i;
                            goto nextNode;
                        }

                        ++j;
                    }       //  while dSubs

                    break;

                case LinkNature.end:

                    j = 0;

                    while (j < subs.Count)
                    {
                        var sub = subs[j];

                        // second condition is useless because it repeats the first
                        if (sub.next.next == node.self)    /* || sub.prev.prev.index == node.this */
                        {
                            indices.Add(links.FindStart(node.self));

                            subs.Exclude(j);

                            ++i;
                            goto nextNode;
                        }

                        ++j;
                    }

                    j = 0;

                    while (j < dSubs.Count)
                    {
                        var dSub = dSubs[j];

                        // second condition is useless because it repeats the first
                        if (dSub.next.next == node.self)    /*|| dSub.prevSub.prev.prev.index == node.this*/
                        {
                            var a      = dSub.middle;
                            var b      = node.self;
                            var bridge = links.Connect(a, b);

                            indices.Add(links.FindStart(a));
                            indices.Add(links.FindStart(bridge.a.self));
                            slices.Add(bridge.Slice);

                            dSubs.Exclude(j);

                            // goto next node
                            ++i;
                            goto nextNode;
                        }

                        ++j;
                    }       //  while dSubs

                    break;

                case LinkNature.simple:

                    j = 0;

                    while (j < subs.Count)
                    {
                        var sub = subs[j];

                        if (sub.next.next == node.self)
                        {
                            sub.next = node;
                            subs[j]  = sub;

                            ++i;
                            goto nextNode;
                        }
                        else if (sub.prev.prev == node.self)
                        {
                            sub.prev = node;
                            subs[j]  = sub;
                            // goto next node
                            ++i;
                            goto nextNode;
                        }

                        ++j;
                    }

                    j = 0;

                    while (j < dSubs.Count)
                    {
                        var dSub = dSubs[j];

                        if (dSub.next.next == node.self)
                        {
                            var a = dSub.middle;
                            var b = node.self;

                            var bridge = links.Connect(a, b);

                            indices.Add(links.FindStart(node.self));
                            slices.Add(bridge.Slice);

                            var newSub = new Sub(bridge.b, dSub.prev);
                            subs.Add(newSub);

                            dSubs.Exclude(j);

                            // goto next node
                            ++i;
                            goto nextNode;
                        }
                        else if (dSub.prev.prev == node.self)
                        {
                            var a = node.self;
                            var b = dSub.middle;

                            var bridge = links.Connect(a, b);

                            indices.Add(links.FindStart(node.self));
                            slices.Add(bridge.Slice);

                            var newSub = new Sub(links[dSub.next.self], bridge.a);
                            subs.Add(newSub);

                            dSubs.Exclude(j);

                            // goto next node
                            ++i;
                            goto nextNode;
                        }

                        ++j;
                    } //  while dSubs
                    break;
                }     // switch
            }

            subs.Dispose();
            dSubs.Dispose();
            navigator.Dispose();

            int pathCount  = navigator.pathCount;
            int extraCount = navigator.extraCount;

            return(new MonotoneLayout(pathCount, extraCount, links.Convert(), slices.Convert(), indices.Convert()));
        }
Пример #16
0
        internal static ShapeNavigator GetNavigator(this PlainShape shape, long maxEdge, NativeArray <IntVector> extraPoints, Allocator allocator)
        {
            SplitLayout splitLayout;

            if (maxEdge == 0)
            {
                splitLayout = shape.Plain(Allocator.Temp);
            }
            else
            {
                splitLayout = shape.Split(maxEdge, Allocator.Temp);
            }

            int pathCount  = splitLayout.nodes.Length;
            int extraCount = extraPoints.Length;

            int n;

            if (extraCount > 0)
            {
                n = pathCount + extraCount;
            }
            else
            {
                n = pathCount;
            }

            var links   = new NativeArray <Link>(n, allocator);
            var natures = new NativeArray <LinkNature>(n, allocator);

            int m = splitLayout.layouts.Length;

            for (int j = 0; j < m; ++j)
            {
                var layout = splitLayout.layouts[j];
                var prev   = layout.end - 1;

                var self = layout.end;
                var next = layout.begin;

                var a = splitLayout.nodes[prev];
                var b = splitLayout.nodes[self];

                var A = a.point.BitPack;
                var B = b.point.BitPack;

                while (next <= layout.end)
                {
                    var c = splitLayout.nodes[next];
                    var C = c.point.BitPack;

                    var  nature = LinkNature.simple;
                    bool isCCW  = IsCCW(a.point, b.point, c.point);

                    if (layout.isClockWise)
                    {
                        if (A > B && B < C)
                        {
                            if (isCCW)
                            {
                                nature = LinkNature.start;
                            }
                            else
                            {
                                nature = LinkNature.split;
                            }
                        }

                        if (A < B && B > C)
                        {
                            if (isCCW)
                            {
                                nature = LinkNature.end;
                            }
                            else
                            {
                                nature = LinkNature.merge;
                            }
                        }
                    }
                    else
                    {
                        if (A > B && B < C)
                        {
                            if (isCCW)
                            {
                                nature = LinkNature.start;
                            }
                            else
                            {
                                nature = LinkNature.split;
                            }
                        }

                        if (A < B && B > C)
                        {
                            if (isCCW)
                            {
                                nature = LinkNature.end;
                            }
                            else
                            {
                                nature = LinkNature.merge;
                            }
                        }
                    }

                    var verNature = b.index < shape.points.Length ? Vertex.Nature.origin : Vertex.Nature.extraPath;

                    links[self]   = new Link(prev, self, next, new Vertex(self, verNature, b.point));
                    natures[self] = nature;

                    a = b;
                    b = c;

                    A = B;
                    B = C;

                    prev = self;
                    self = next;

                    ++next;
                }
            }

            splitLayout.Dispose();

            if (extraCount > 0)
            {
                for (int k = 0; k < extraPoints.Length; ++k)
                {
                    var p = extraPoints[k];
                    var j = k + pathCount;
                    links[j]   = new Link(j, j, j, new Vertex(j, Vertex.Nature.extraInner, p));
                    natures[j] = LinkNature.extra;
                }
            }

            // sort

            var dataList = new NativeArray <SortData>(n, Allocator.Temp);

            for (int j = 0; j < n; ++j)
            {
                var p = links[j].vertex.point;
                dataList[j] = new SortData(j, p.BitPack, (int)natures[j]);
            }

            Sort(dataList);

            var indices = new NativeArray <int>(n, allocator);

            // filter same points
            var x1 = new SortData(-1, long.MinValue, int.MinValue);

            int i = 0;

            while (i < n)
            {
                var x0 = dataList[i];
                indices[i] = x0.index;
                if (x0.factor == x1.factor)
                {
                    var v = links[x1.index].vertex;

                    do
                    {
                        var link = links[x0.index];
                        links[x0.index] = new Link(link.prev, link.self, link.next, new Vertex(v.index, v.nature, v.point));
                        ++i;
                        if (i < n)
                        {
                            x0         = dataList[i];
                            indices[i] = x0.index;
                        }
                        else
                        {
                            break;
                        }
                    } while(x0.factor == x1.factor);
                }
                x1 = x0;
                ++i;
            }

            dataList.Dispose();

            return(new ShapeNavigator(pathCount, extraCount, links, natures, indices));
        }
Пример #17
0
        public void Test_01()
        {
            var data = BreakerTestData.data[1];

            var nPoints = new NativeArray <Vector2>(data, allocator);
            var iPoints = iGeom.Int(nPoints, allocator);

            var pShape = new PlainShape(iPoints, true, allocator);

            iPoints.Dispose();


            var indices = pShape.DelaunayTriangulate(allocator);

            pShape.Dispose();

            var triangles = TrianglesBuilder.build(nPoints, indices, allocator);

            indices.Dispose();
            nPoints.Dispose();

            var breaker  = new BreakSolver(20, 20, BreakSolver.SmallSpawnStrategy.no);
            var polygons = breaker.Divide(triangles, allocator);

            triangles.Dispose();

            Assert.AreEqual(polygons.Count, 4);

            Assert.AreEqual(polygons.Get(0, allocator).Convert().isEqual(new[] {
                new Vector2(-1.0173526f, 5.988432f),
                new Vector2(-3.1394918f, 4.5736723f),
                new Vector2(-6.684741f, 6.6305175f),
                new Vector2(-5.5441256f, 8.911749f),
                new Vector2(-3.8257403f, 10.0f),
                new Vector2(-1.2752466f, 10.0f)
            }, 0.001f), true);

            Assert.AreEqual(polygons.Get(1, allocator).Convert().isEqual(new[] {
                new Vector2(6.31049f, 7.3790197f),
                new Vector2(8.128133f, 3.7437348f),
                new Vector2(4.760133f, 0.0f),
                new Vector2(0.6957607f, 0.0f),
                new Vector2(-1.3489046f, 5.767397f),
                new Vector2(2.0328574f, 8.021905f)
            }, 0.001f), true);

            Assert.AreEqual(polygons.Get(2, allocator).Convert().isEqual(new[] {
                new Vector2(-2.0710678f, 0.0f),
                new Vector2(2.0710678f, 0.0f),
                new Vector2(5.0f, -5.0f),
                new Vector2(2.0710678f, -7.928932f),
                new Vector2(-2.0710678f, -7.928932f),
                new Vector2(-5.0f, -5.0f)
            }, 0.001f), true);

            Assert.AreEqual(polygons.Get(3, allocator).Convert().isEqual(new[] {
                new Vector2(-0.7366932f, 4.0405293f),
                new Vector2(0.02077043f, 1.9039481f),
                new Vector2(-1.8329408f, 0.0f),
                new Vector2(-4.0998178f, 0.0f),
                new Vector2(-5.1286488f, 3.2475674f),
                new Vector2(-3.2424932f, 4.5050044f)
            }, 0.001f), true);

            polygons.Dispose();
        }
Пример #18
0
        public void Test_00()
        {
            var data = BreakerTestData.data[0];

            var nPoints = new NativeArray <Vector2>(data, allocator);
            var iPoints = iGeom.Int(nPoints, allocator);

            var pShape = new PlainShape(iPoints, true, allocator);

            iPoints.Dispose();


            var indices = pShape.DelaunayTriangulate(allocator);

            pShape.Dispose();

            var triangles = TrianglesBuilder.build(nPoints, indices, allocator);

            indices.Dispose();
            nPoints.Dispose();

            var breaker0  = new BreakSolver(5, 300, BreakSolver.SmallSpawnStrategy.no);
            var polygons0 = breaker0.Divide(triangles, allocator);

            Assert.AreEqual(polygons0.Count, 3);

            Assert.AreEqual(polygons0.Get(0, allocator).Convert().isEqual(new[] {
                new Vector2(2.0710678f, 0.0f),
                new Vector2(-2.0710678f, 0.0f),
                new Vector2(-5.0f, 5.0f),
                new Vector2(-2.0710678f, 7.928932f),
                new Vector2(2.0710678f, 7.928932f),
                new Vector2(5.0f, 5.0f)
            }, 0.001f), true);

            Assert.AreEqual(polygons0.Get(1, allocator).Convert().isEqual(new[] {
                new Vector2(-4.1628227f, 3.570849f),
                new Vector2(-3.1991942f, 1.9258323f),
                new Vector2(-4.597563f, 0.0f),
                new Vector2(-6.504041f, 0.0f),
                new Vector2(-7.6229224f, 2.3770776f),
                new Vector2(-6.2748384f, 3.7251613f)
            }, 0.001f), true);

            Assert.AreEqual(polygons0.Get(2, allocator).Convert().isEqual(new[] {
                new Vector2(3.199194f, 1.925832f),
                new Vector2(4.1628222f, 3.5708487f),
                new Vector2(6.2748384f, 3.7251616f),
                new Vector2(7.622922f, 2.3770778f),
                new Vector2(6.504041f, 0.0f),
                new Vector2(4.597563f, 0.0f)
            }, 0.001f), true);

            polygons0.Dispose();

            var breaker1  = new BreakSolver(1.5f, 10, BreakSolver.SmallSpawnStrategy.no);
            var polygons1 = breaker1.Divide(triangles, allocator);

            Assert.AreEqual(polygons1.Count > 3, true);

            triangles.Dispose();
        }