Esempio n. 1
0
        public static int[] ComputeSegmentSeeingWaypoints(this PolyNode landNode, DoubleLineSegment2 segment)
        {
            var crossoverSeeingWaypoints   = new List <int>();
            var waypointVisibilityPolygons = ComputeWaypointVisibilityPolygons(landNode);

            for (int waypointIndex = 0; waypointIndex < waypointVisibilityPolygons.Length; waypointIndex++)
            {
                var waypoint = landNode.visibilityGraphNodeData.AggregateContourWaypoints[waypointIndex];
                var waypointVisibilityPolygon         = waypointVisibilityPolygons[waypointIndex];
                var waypointVisibilityPolygonBarriers = waypointVisibilityPolygon.Get();

                var erodedCrossoverSegmentWaypointDistanceSquared = waypoint.ToDoubleVector2().To((segment.First + segment.Second) / 2.0).SquaredNorm2D();

                // TODO: If segment matches waypoint this explodes (can't vispoly stab with its origin)
                //var segmentsIndices = waypointVisibilityPolygon.RangeStab(segment);
                var crossoverSeen = waypointVisibilityPolygon.IsPartiallyVisible(segment);
                //for (var i = 0; i < segmentsIndices.Length && !crossoverSeen; i++) {
                //   var (rangeStartIndex, rangeEndIndex) = segmentsIndices[i];
                //   for (var j = rangeStartIndex; j <= rangeEndIndex && !crossoverSeen; j++) {
                //      if (waypointVisibilityPolygonBarriers[j].MidpointDistanceToOriginSquared >= erodedCrossoverSegmentWaypointDistanceSquared) {
                //         crossoverSeen = true;
                //      }
                //   }
                //}

                if (crossoverSeen)
                {
                    crossoverSeeingWaypoints.Add(waypointIndex);
                }
            }
            return(crossoverSeeingWaypoints.ToArray());
        }
Esempio n. 2
0
        public override List<EdgeJob> EmitCrossoverJobs(double crossoverPointSpacing, LocalGeometryView sourceLgv, LocalGeometryView destinationLgv)
        {
            //         return new List<EdgeJob>();

             var sourceSegmentVector = SourceSegment.First.To(SourceSegment.Second).ToDoubleVector2();
             var destinationSegmentVector = DestinationSegment.First.To(DestinationSegment.Second).ToDoubleVector2();

             var edgeJobs = new List<EdgeJob>();
             var streamSource = X(SourceSegment, sourceLgv).ToArray();
             var streamDest = X(DestinationSegment, destinationLgv).ToArray();
             var crossResult = CrossTheStreams(streamSource, streamDest).ToArray();
             foreach (var (source, dest, tStart, tEnd) in crossResult) {
            var sourceSubSegment = new DoubleLineSegment2(
               SourceSegment.First.ToDoubleVector2() + tStart * sourceSegmentVector,
               SourceSegment.First.ToDoubleVector2() + tEnd * sourceSegmentVector);

            var destinationSubSegment = new DoubleLineSegment2(
               DestinationSegment.First.ToDoubleVector2() + tStart * destinationSegmentVector,
               DestinationSegment.First.ToDoubleVector2() + tEnd * destinationSegmentVector);

            edgeJobs.Add(new EdgeJob {
               EdgeDescription = this,
               SourcePolyNode = source,
               SourceSegment = sourceSubSegment,
               DestinationPolyNode = dest,
               DestinationSegment = destinationSubSegment
            });
             }
             return edgeJobs;
        }
        // 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);
            }
        }
Esempio n. 4
0
 public static void DrawLine(this IDebugCanvas canvas, DoubleLineSegment2 segment, StrokeStyle strokeStyle)
 {
     canvas.DrawLine(ToDV3(segment.First), ToDV3(segment.Second), strokeStyle);
 }