Пример #1
0
        public void SerializeQuadTree()
        {
            {
                var tree = new QuadTree <string>();
                VerifyTreeClone(tree);
            }

            {
                var tree = new QuadTree <string>();

                tree.AddItem("(0, 0)", new Vector2r());
                tree.AddItem("(1, -1)", new Vector2r(1, -1));
                tree.AddMonitor(new TestMonitor <string>(), new Bound(0, 10, 5));

                VerifyTreeClone(tree);
            }

            {
                var tree = new QuadTree <string>();

                tree.AddMonitor(new TestMonitor <string>(), new Bound(0, 0, 100));
                tree.AddMonitor(new TestMonitor <string>(), new Bound(0, 5, 100));

                VerifyTreeClone(tree);
            }
        }
Пример #2
0
        public void CollectFromQuadTree(int worldScale)
        {
            var tree = new QuadTree <string>(worldScale);

            var added = new List <string>()
            {
                "-8,0",
                "-5,0",
                "0,0",
                "5,0",
                "8,0"
            };

            tree.AddItem(added[0], new Vector2r(-8, 0));
            tree.AddItem(added[1], new Vector2r(-5, 0));
            tree.AddItem(added[2], new Vector2r(0, 0));
            tree.AddItem(added[3], new Vector2r(5, 0));
            tree.AddItem(added[4], new Vector2r(8, 0));

            // collect everything (both positive and negative)
            {
                List <string> everything = tree.CollectItems <List <string> >(new Bound(0, 0, 200));
                Assert.Equal(5, everything.Count);
                Assert.Contains(added[0], everything);
                Assert.Contains(added[1], everything);
                Assert.Contains(added[2], everything);
                Assert.Contains(added[3], everything);
                Assert.Contains(added[4], everything);
            }

            // collection a positive region
            {
                var positiveOnly = tree.CollectItems <List <string> >(new Bound(5, 0, 4));
                Assert.Equal(2, positiveOnly.Count);
                Assert.Contains(added[3], positiveOnly);
                Assert.Contains(added[4], positiveOnly);
            }

            // collect a negative region
            {
                var negativeOnly = tree.CollectItems <List <string> >(new Bound(-5, 0, 4));
                Assert.Equal(2, negativeOnly.Count);
                Assert.Contains(added[0], negativeOnly);
                Assert.Contains(added[1], negativeOnly);
            }

            // collect an empty region
            {
                var nothing = tree.CollectItems <List <string> >(new Bound(100, 0, 5));
                Assert.Empty(nothing);
            }
        }
Пример #3
0
        public void SimpleLeafTest()
        {
            var tree = new QuadTree <Tuple <int, int> >(new Rect(0, 0, 100, 100), GetTupleRect);

            tree.AddItem(Tuple.Create(25, 25));
            tree.AddItem(Tuple.Create(25, 75));
            tree.AddItem(Tuple.Create(75, 25));
            tree.AddItem(Tuple.Create(75, 75));

            Assert.Equal(4, tree.GetContainedItems(new Rect(0, 0, 100, 100)).Count);
            Assert.Equal(4, tree.GetContainedItems(new Rect(25, 25, 50, 50)).Count);
            Assert.Single(tree.GetContainedItems(new Rect(0, 0, 50, 50)));
            Assert.Single(tree.GetContainedItems(new Rect(50, 0, 50, 50)));
            Assert.Single(tree.GetContainedItems(new Rect(0, 50, 50, 50)));
            Assert.Single(tree.GetContainedItems(new Rect(50, 50, 50, 50)));
        }
Пример #4
0
        private Task UpdateSnapPoints(bool allowCancellation = true)
        {
            var oldTokenSource = updateSnapPointsCancellationTokenSource;

            updateSnapPointsCancellationTokenSource = new CancellationTokenSource();
            oldTokenSource.Cancel();
            var token = updateSnapPointsCancellationTokenSource.Token;

            var width  = ActualWidth;
            var height = ActualHeight;

            updateSnapPointsTask = Task.Run(() =>
            {
                // populate the snap points
                var transformedQuadTree = new QuadTree <TransformedSnapPoint>(new Rect(0, 0, width, height), t => new Rect(t.ControlPoint.X, t.ControlPoint.Y, 0.0, 0.0));
                foreach (var layer in Workspace.Drawing.GetLayers(token))
                {
                    token.ThrowIfCancellationRequested();
                    foreach (var entity in layer.GetEntities(token))
                    {
                        token.ThrowIfCancellationRequested();
                        foreach (var snapPoint in entity.GetSnapPoints())
                        {
                            transformedQuadTree.AddItem(new TransformedSnapPoint(snapPoint.Point, Project(snapPoint.Point), snapPoint.Kind));
                        }
                    }
                }

                snapPointsQuadTree = transformedQuadTree;
            });

            return(updateSnapPointsTask);
        }
Пример #5
0
        /// <summary>
        /// Get all transformed snap points for the drawing with the given display transform.
        /// </summary>
        public static QuadTree <TransformedSnapPoint> GetSnapPoints(this Drawing drawing, Matrix4 displayTransform, double width, double height, CancellationToken cancellationToken = default)
        {
            // populate the snap points
            var transformedQuadTree = new QuadTree <TransformedSnapPoint>(new Rect(0, 0, width, height), t => new Rect(t.ControlPoint.X, t.ControlPoint.Y, 0.0, 0.0));

            foreach (var layer in drawing.GetLayers(cancellationToken))
            {
                cancellationToken.ThrowIfCancellationRequested();
                foreach (var entity in layer.GetEntities(cancellationToken))
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    foreach (var snapPoint in entity.GetSnapPoints())
                    {
                        var projected = displayTransform.Transform(snapPoint.Point);
                        transformedQuadTree.AddItem(new TransformedSnapPoint(snapPoint.Point, projected, snapPoint.Kind));
                    }
                }
            }

            // calculate intersections
            // TODO: can this be done in a meanintful way in a separate task?
            var primitives = drawing.GetEntities().SelectMany(e => e.GetPrimitives()).ToList();

            for (int startIndex = 0; startIndex < primitives.Count; startIndex++)
            {
                cancellationToken.ThrowIfCancellationRequested();
                var first = primitives[startIndex];
                for (int i = startIndex + 1; i < primitives.Count; i++)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    var current = primitives[i];
                    foreach (var intersection in first.IntersectionPoints(current))
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        var projected = displayTransform.Transform(intersection);
                        transformedQuadTree.AddItem(new TransformedSnapPoint(intersection, projected, SnapPointKind.Intersection));
                    }
                }
            }

            cancellationToken.ThrowIfCancellationRequested();
            return(transformedQuadTree);
        }
Пример #6
0
        public void ParentNodeTest()
        {
            var tree = new QuadTree <Tuple <int, int> >(new Rect(0, 0, 100, 100), GetTupleRect);

            tree.AddItem(Tuple.Create(25, 25));
            tree.AddItem(Tuple.Create(25, 75));
            tree.AddItem(Tuple.Create(75, 25));
            tree.AddItem(Tuple.Create(75, 75));
            tree.AddItem(Tuple.Create(50, 50));
            tree.AddItem(Tuple.Create(10, 10));

            Assert.Equal(6, tree.GetContainedItems(new Rect(0, 0, 100, 100)).Count);
            Assert.Equal(5, tree.GetContainedItems(new Rect(25, 25, 50, 50)).Count);
            Assert.Equal(3, tree.GetContainedItems(new Rect(0, 0, 50, 50)).Count);
            Assert.Equal(2, tree.GetContainedItems(new Rect(50, 0, 50, 50)).Count);
            Assert.Equal(2, tree.GetContainedItems(new Rect(0, 50, 50, 50)).Count);
            Assert.Equal(2, tree.GetContainedItems(new Rect(50, 50, 50, 50)).Count);
        }
Пример #7
0
        public void MonitorTests(int worldScale)
        {
            var tree = new QuadTree <object>(worldScale);

            // test a monitor on an initially empty tree, add an object to the tree and ensure that
            // the monitor contains it, update the monitor to a position that doesn't contain the
            // item in the tree, ensure the monitor is empty, update the monitor so that it contains
            // the item again, ensure the monitor contains the item, update the monitor so that it
            // still contains the item & verify, then remove the monitor and ensure it is empty
            {
                var monitor = new TestMonitor <object>();

                // inserting a monitor into an empty tree should result in an empty monitor
                tree.AddMonitor(monitor, new Bound(0, 0, 25));
                Assert.Empty(monitor.Contained);

                // add an object to (0,0)
                var added = new object();
                tree.AddItem(added, new Vector2r());
                Assert.Contains(added, monitor.Contained);

                // update the position of the monitor so that it doesn't contain anything
                tree.UpdateMonitor(monitor, new Bound(0, 0, 25), new Bound(100, 100, 25));
                Assert.Empty(monitor.Contained);

                // update the position of the monitor so that it contains the item
                tree.UpdateMonitor(monitor, new Bound(100, 100, 25), new Bound(5, 5, 25));
                Assert.Contains(added, monitor.Contained);

                // update it back to its original position so that it contains everything
                tree.UpdateMonitor(monitor, new Bound(5, 5, 25), new Bound(0, 0, 25));
                Assert.Contains(added, monitor.Contained);

                // remove the monitor
                tree.RemoveMonitor(monitor, new Bound(0, 0, 25));
                Assert.Empty(monitor.Contained);
            }

            // test a monitor on a non-empty tree
            {
                var monitor = new TestMonitor <object>();

                // the monitor should have the object already in the tree added to it
                tree.AddMonitor(monitor, new Bound(0, 0, 25));
                Assert.NotEmpty(monitor.Contained);

                // add an object to (0,0)
                var added = new object();
                tree.AddItem(added, new Vector2r());
                Assert.Contains(added, monitor.Contained);

                // remove the monitor
                tree.RemoveMonitor(monitor, new Bound(0, 0, 25));
                Assert.Empty(monitor.Contained);
            }

            // test a monitor on a non-empty tree that doesn't contain the objects already in the
            // tree
            {
                var monitor = new TestMonitor <object>();

                // the monitor should remain empty when being added to the tree
                tree.AddMonitor(monitor, new Bound(100, 100, 25));
                Assert.Empty(monitor.Contained);

                // add an object to (0,0); it should not be added to the monitor
                var added = new object();
                tree.AddItem(added, new Vector2r());
                Assert.Empty(monitor.Contained);

                // remove the monitor
                tree.RemoveMonitor(monitor, new Bound(100, 100, 25));
                Assert.Empty(monitor.Contained);
            }
        }