Exemple #1
0
        /// <summary>
        /// Creates the IntersectionPoint3D of type <see cref="IntersectionPointType.LinearIntersectionEnd"/>
        /// that corresponds to the second intersection along the source segment.
        /// </summary>
        /// <param name="intersection">The intersection</param>
        /// <param name="sourceSegments"></param>
        /// <param name="targetSegments"></param>
        /// <returns></returns>
        public static IntersectionPoint3D GetLinearIntersectionEnd(
            [NotNull] SegmentIntersection intersection,
            [NotNull] ISegmentList sourceSegments,
            [NotNull] ISegmentList targetSegments)
        {
            Line3D sourceSegment = sourceSegments[intersection.SourceIndex];

            double endFactor;
            Pnt3D  toPoint =
                intersection.GetLinearIntersectionEnd(sourceSegment, out endFactor);

            int sourcePartIdx;
            int sourceSegmentIndex = sourceSegments.GetLocalSegmentIndex(
                intersection.SourceIndex, out sourcePartIdx);

            IntersectionPoint3D result =
                new IntersectionPoint3D(
                    toPoint, sourceSegmentIndex + endFactor, intersection)
            {
                Type            = IntersectionPointType.LinearIntersectionEnd,
                SourcePartIndex = sourcePartIdx
            };

            int targetPartIdx;

            result.VirtualTargetVertex = CalculateVirtualTargetVertex(
                targetSegments, result.Type, intersection, out targetPartIdx);

            result.TargetPartIndex = targetPartIdx;

            return(result);
        }
Exemple #2
0
        private static IEnumerable <SegmentIntersection> FilterIntersections(
            [NotNull] IEnumerable <SegmentIntersection> intersectionsForSourceSegment,
            [NotNull] ISegmentList source,
            [NotNull] IDictionary <int, HashSet <double> > usedIntersectionFactorsByPart)
        {
            foreach (SegmentIntersection intersection in intersectionsForSourceSegment)
            {
                var filter = false;

                if (!intersection.HasLinearIntersection &&
                    intersection.SingleInteriorIntersectionFactor == null)
                {
                    double intersectionFactor;
                    if (intersection.SourceStartIntersects)
                    {
                        intersectionFactor = 0;
                    }
                    else if (intersection.SourceEndIntersects)
                    {
                        intersectionFactor = 1;
                    }
                    else if (intersection.TargetStartIntersects)
                    {
                        intersectionFactor =
                            Assert.NotNull(intersection.TargetStartFactor).Value;
                    }
                    else
                    {
                        intersectionFactor =
                            Assert.NotNull(intersection.TargetEndFactor).Value;
                    }

                    int partIndex;
                    int localSegmentIndex =
                        source.GetLocalSegmentIndex(intersection.SourceIndex, out partIndex);

                    double intersectionFactorPartGlobal = localSegmentIndex + intersectionFactor;

                    // TODO: Extract class IntersectionFactors which encapsulates all the
                    // Contains, Add etc. methods, probably even the filtering
                    if (ContainsIntersection(usedIntersectionFactorsByPart, partIndex,
                                             intersectionFactorPartGlobal))
                    {
                        filter = true;
                    }
                    else
                    {
                        AddIntersectionFactor(intersectionFactorPartGlobal, partIndex,
                                              usedIntersectionFactorsByPart, source);
                    }
                }

                if (!filter)
                {
                    yield return(intersection);
                }
            }
        }
Exemple #3
0
        private static void CollectIntersection(
            [NotNull] SegmentIntersection intersection,
            [NotNull] ISegmentList source,
            [NotNull] IDictionary <int, HashSet <double> > allLinearIntersectionFactors,
            [NotNull] ICollection <SegmentIntersection> intersectionsForCurrentSourceSegment)
        {
            // Collect segments for current index in list, unless they are clearly not needed
            // (and would need to be filtered by a later linear intersection if added)

            bool isLinear = intersection.HasLinearIntersection;

            if (isLinear)
            {
                int partIndex;
                int localSegmentIndex =
                    source.GetLocalSegmentIndex(intersection.SourceIndex, out partIndex);

                double linearIntersectionStartFactor =
                    localSegmentIndex +
                    intersection.GetLinearIntersectionStartFactor(true);

                double linearIntersectionEndFactor =
                    localSegmentIndex +
                    intersection.GetLinearIntersectionEndFactor(true);

                if (intersection.IsSourceZeroLength2D &&
                    ContainsIntersection(allLinearIntersectionFactors,
                                         partIndex, linearIntersectionEndFactor))
                {
                    // avoid double linear segments if the source segment is vertical
                    return;
                }

                AddIntersectionFactor(linearIntersectionStartFactor, partIndex,
                                      allLinearIntersectionFactors, source);

                AddIntersectionFactor(linearIntersectionEndFactor, partIndex,
                                      allLinearIntersectionFactors, source);
            }

            if (!isLinear && intersection.SourceStartIntersects &&
                source.IsFirstSegmentInPart(intersection.SourceIndex) && source.IsClosed)
            {
                // will be reported again at the end
                return;
            }

            if (!isLinear && intersection.SourceEndIntersects &&
                !source.IsLastSegmentInPart(intersection.SourceIndex))
            {
                // will be reported again at next segment
                return;
            }

            intersectionsForCurrentSourceSegment.Add(intersection);
        }
Exemple #4
0
        private static double CalculateVirtualTargetVertex(ISegmentList targetSegments,
                                                           IntersectionPointType intersectionType,
                                                           SegmentIntersection segmentIntersection,
                                                           out int targetPartIndex)
        {
            int targetSegmentIndex = targetSegments.GetLocalSegmentIndex(
                segmentIntersection.TargetIndex, out targetPartIndex);

            double result;

            switch (intersectionType)
            {
            case IntersectionPointType.LinearIntersectionStart:
                result = targetSegmentIndex +
                         segmentIntersection.GetRatioAlongTargetLinearStart();
                break;

            case IntersectionPointType.LinearIntersectionEnd:
            case IntersectionPointType.LinearIntersectionIntermediate:
                result = targetSegmentIndex +
                         segmentIntersection.GetRatioAlongTargetLinearEnd();
                break;

            case IntersectionPointType.Crossing:
            case IntersectionPointType.TouchingInPoint:
                result = targetSegmentIndex +
                         segmentIntersection.GetIntersectionPointFactorAlongTarget();
                break;

            default:
                throw new InvalidOperationException(
                          $"Unsupported type :{intersectionType}");
            }

            return(result);
        }
Exemple #5
0
        public static IntersectionPoint3D CreateSingleIntersectionPoint(
            [NotNull] SegmentIntersection intersection,
            [NotNull] ISegmentList sourceSegments,
            [NotNull] ISegmentList targetSegments,
            double tolerance)
        {
            Line3D sourceSegment = sourceSegments.GetSegment(intersection.SourceIndex);
            double?targetIntersectionFactorOnSource =
                intersection.GetIntersectionPointFactorAlongSource();

            int sourcePartIdx;
            int sourceSegmentIndex = sourceSegments.GetLocalSegmentIndex(
                intersection.SourceIndex, out sourcePartIdx);

            Pnt3D  point;
            double sourceIndex;

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (targetIntersectionFactorOnSource == 0)
            {
                point       = sourceSegment.StartPoint;
                sourceIndex = sourceSegmentIndex;
            }
            // ReSharper disable once CompareOfFloatsByEqualityOperator
            else if (targetIntersectionFactorOnSource == 1)
            {
                point       = sourceSegment.EndPoint;
                sourceIndex = sourceSegmentIndex + 1;
            }
            else
            {
                point = sourceSegment.GetPointAlong(
                    targetIntersectionFactorOnSource.Value, true);
                sourceIndex = sourceSegmentIndex +
                              targetIntersectionFactorOnSource.Value;
            }

            IntersectionPoint3D result = new IntersectionPoint3D(point, sourceIndex, intersection)
            {
                SourcePartIndex = sourcePartIdx
            };

            bool?targetDeviatesToLeft;

            result.Type = intersection.IsCrossingInPoint(
                sourceSegments, targetSegments, tolerance,
                out targetDeviatesToLeft)
                                              ? IntersectionPointType.Crossing
                                              : IntersectionPointType.TouchingInPoint;

            result.TargetDeviatesToLeftOfSource = targetDeviatesToLeft;

            int targetPartIdx;

            result.VirtualTargetVertex = CalculateVirtualTargetVertex(
                targetSegments, result.Type, intersection, out targetPartIdx);

            result.TargetPartIndex = targetPartIdx;

            return(result);
        }