Пример #1
0
        private static void RenderVisualizationFrame()
        {
            var segments = Util.Generate(200, RandomSegment);
//         var quad = new[] { new IntVector2(100, 100), new IntVector2(200, 200), new IntVector2(300, 300), new IntVector2(400, 400) };
            var quad = Util.Generate(4, RandomPoint);
            var hull = GeometryOperations.ConvexHull4(quad[0], quad[1], quad[2], quad[3]);

            var canvas = host.CreateAndAddCanvas(frameCounter++);

            canvas.BatchDraw(() => {
                foreach (var(x, y) in quad.Zip(quad.RotateLeft()))
                {
                    canvas.DrawLine(x, y, StrokeStyle.BlackHairLineDashed5);
                }
                foreach (var(x, y) in hull.Zip(hull.RotateLeft()))
                {
                    canvas.DrawLine(x, y, StrokeStyle.BlackHairLineSolid);
                }
                foreach (var p in hull)
                {
                    canvas.DrawPoint(p, StrokeStyle.RedThick5Solid);
                }
                foreach (var s in segments)
                {
                    canvas.DrawLine(s.First, s.Second, GeometryOperations.SegmentIntersectsConvexPolygonInterior(s, hull) ? StrokeStyle.LimeHairLineDashed5 : StrokeStyle.RedHairLineDashed5);
                }
            });
        }
Пример #2
0
        // Todo: Can we support DV2s?

        public int[] AddMany(DoubleLineSegment2 edgeSegment, IntVector2[] points)
        {
            Interlocked.Increment(ref AddManyInvocationCount);
            //         return points.Map(p => 0);
            var segmentSeeingWaypoints = landPolyNode.ComputeSegmentSeeingWaypoints(edgeSegment);

            // It's safe to assume <some> point in points will be new, so preprocess which segments are betwen us and other edge segments
            var barriers = landPolyNode.FindContourAndChildHoleBarriers();
            Dictionary <DoubleLineSegment2, IntLineSegment2[]> barriersBySegment = indicesBySegment.Map((s, _) => {
                Interlocked.Increment(ref AddManyConvexHullsComputed);
                var hull = GeometryOperations.ConvexHull4(s.First, s.Second, edgeSegment.First, edgeSegment.Second);
                return(barriers.Where(b => {
                    var barrierDv2 = new DoubleLineSegment2(b.First.ToDoubleVector2(), b.Second.ToDoubleVector2());
                    return GeometryOperations.SegmentIntersectsConvexPolygonInterior(barrierDv2, hull);
                }).ToArray());
            });

            return(indicesBySegment[edgeSegment] = points.Map(p => {
                if (TryAdd(p, out var cpi))
                {
                    Interlocked.Increment(ref CrossoverPointsAdded);
                    segmentByCrossoverPoint[p] = edgeSegment;
                }

                return cpi;
            }));

            bool TryAdd(IntVector2 crossoverPoint, out int crossoverPointIndex)
            {
                if (!crossoverPoints.TryAdd(crossoverPoint, out crossoverPointIndex))
                {
                    return(false);
                }

                var(visibleWaypointLinks, visibleWaypointLinksLength, optimalLinkToWaypoints, optimalLinkToCrossovers) = FindOptimalLinksToCrossovers(crossoverPoint, segmentSeeingWaypoints, barriersBySegment);
                // visibleWaypointLinksByCrossoverPointIndex.Add(visibleWaypointLinks);
                optimalLinkToWaypointsByCrossoverPointIndex.Add(optimalLinkToWaypoints);
                optimalLinkToOtherCrossoversByCrossoverPointIndex.Add(optimalLinkToCrossovers);
                Trace.Assert(optimalLinkToOtherCrossoversByCrossoverPointIndex.Count == optimalLinkToCrossovers.Count);

                for (var otherCpi = 0; otherCpi < crossoverPoints.Count - 1; otherCpi++)
                {
                    var linkToOther   = optimalLinkToCrossovers[otherCpi];
                    var linkFromOther = linkToOther.PriorIndex < 0
                  ? new PathLink {
                        PriorIndex = linkToOther.PriorIndex, TotalCost = linkToOther.TotalCost
                    }
                  : new PathLink {
                        PriorIndex = optimalLinkToWaypointsByCrossoverPointIndex[otherCpi][linkToOther.PriorIndex].PriorIndex,
                        TotalCost  = linkToOther.TotalCost
                    };
                    optimalLinkToOtherCrossoversByCrossoverPointIndex[otherCpi].Add(linkFromOther);
                }

                return(true);
            }
        }
Пример #3
0
        private static void Benchmark()
        {
            var segments = Util.Generate(100000, RandomSegment);
            var quad     = Util.Generate(4, RandomPoint);
            var hull     = GeometryOperations.ConvexHull(quad);
            var sw       = new Stopwatch();

            sw.Start();
            const int niters = 100;

            for (var i = 0; i < niters; i++)
            {
                for (var j = 0; j < segments.Length; j++)
                {
                    GeometryOperations.SegmentIntersectsConvexPolygonInterior(segments[j], hull);
                }
            }
            Console.WriteLine(sw.Elapsed.TotalMilliseconds / niters);
        }