protected override bool GetNextSegment(out double length, out double dz, out int partIndex, out int segmentIndex) { if (!_enumSegments.MoveNext()) { length = double.NaN; dz = double.NaN; partIndex = -1; segmentIndex = -1; return(false); } SegmentProxy segment = Assert.NotNull(_enumSegments.Current); partIndex = segment.PartIndex; segmentIndex = segment.SegmentIndex; length = segment.Length; double z0 = segment.GetStart(true)[2]; double z1 = segment.GetEnd(true)[2]; dz = z1 - z0; return(true); }
public override Pnt GetNearestVertex() { double fraction = Fraction; Pnt vertex = fraction < 0.5 ? _segmentProxy.GetStart(as3D: true) : _segmentProxy.GetEnd(as3D: true); return(vertex); }
private static double GetOffset([NotNull] Pnt pnt, [NotNull] SegmentProxy segmentProxy, out double fraction, out bool?onRightSide) { double?offset; fraction = SegmentUtils.GetClosestPointFraction( segmentProxy, pnt, out offset, out onRightSide, as3D: false); double distance2; if (fraction < 0) { distance2 = pnt.Dist2(segmentProxy.GetStart(as3D: false)); onRightSide = null; } else if (fraction > 1) { distance2 = pnt.Dist2(segmentProxy.GetEnd(as3D: false)); onRightSide = null; } else { if (!offset.HasValue) { Pnt s = segmentProxy.GetStart(as3D: false); Pnt e = segmentProxy.GetEnd(as3D: false); double vectorProd = (pnt - s).VectorProduct(s - e); onRightSide = vectorProd < 0; distance2 = pnt.Dist2(segmentProxy.GetPointAt(fraction, as3D: false)); } else { distance2 = 0; // offset has value and will be used as distance } } double distance = offset ?? Math.Sqrt(distance2); return(distance); }
private static double GetDistanceToVertices([NotNull] IPoint point, [NotNull] IFeature neighbourFeature, [NotNull] IPoint nearestPoint, double maxNeededDistance) { double minDistance2 = double.MaxValue; SegmentProxy nearestSegment = null; var isEndNearest = false; Pnt qaPoint = QaGeometryUtils.CreatePoint3D(point); IEnumerable <SegmentProxy> segments = EnumSegments(qaPoint, neighbourFeature, maxNeededDistance); foreach (SegmentProxy segment in segments) { if (GetNearest(qaPoint, segment.GetStart(false), ref minDistance2)) { nearestSegment = segment; isEndNearest = false; } if (GetNearest(qaPoint, segment.GetEnd(false), ref minDistance2)) { nearestSegment = segment; isEndNearest = true; } } double minDistance; if (nearestSegment != null) { minDistance = Math.Sqrt(minDistance2); if (minDistance <= maxNeededDistance) { Pnt nearest = !isEndNearest ? nearestSegment.GetStart(true) : nearestSegment.GetEnd(true); nearestPoint.PutCoords(nearest.X, nearest.Y); nearestPoint.Z = nearest[2]; } } else { minDistance = double.MaxValue; } return(minDistance); }
private bool IsHorizontal([NotNull] SegmentProxy segment) { double length = segment.Length; if (Math.Abs(length) < double.Epsilon) { return(false); } double z0 = segment.GetStart(true)[2]; double z1 = segment.GetEnd(true)[2]; double slopeAngle = Math.Atan2(Math.Abs(z1 - z0), length); bool isHorizontal = slopeAngle <= _horizontalToleranceRad; return(isHorizontal); }
public AzimuthSegment([NotNull] SegmentProxy segment, double xyResolution) { Segment = segment; _xyResolution = xyResolution; Pnt start = Segment.GetStart(false); Pnt end = Segment.GetEnd(false); double dx = end.X - start.X; double dy = end.Y - start.Y; Azimuth = Math.Atan2(dx, dy); // Azimuth is the angle to north if (Azimuth < 0) // the orientation must be ignored { Azimuth += Math.PI; } }
private static double GetDistanceToCurve( [NotNull] IPoint point, [NotNull] IFeature neighbourFeature, [NotNull] IPoint nearestPoint, double maxNeededDistance, out bool onRightSide) { var neighborCurve = (ICurve)neighbourFeature.Shape; if (UseQueryPointAndDistance) { const bool asRatio = false; double along = 0; double distance = 0; var rightSide = false; // TLMQA-292 (EBG - BB): most time spent here (> 90%) neighborCurve.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, point, asRatio, nearestPoint, ref along, ref distance, ref rightSide); onRightSide = rightSide; return(distance); } { double nearestDistance = maxNeededDistance * 1.01; bool? nearestOnRightSide = null; SegmentProxy nearestSegment = null; double nearestFraction = 0; double x; double y; point.QueryCoords(out x, out y); Pnt qaPoint = new Pnt2D(x, y); foreach (SegmentProxy segmentProxy in EnumSegments(qaPoint, neighbourFeature, maxNeededDistance)) { bool? onSegmentRightSide; double alongFraction; double offset = GetOffset(qaPoint, segmentProxy, out alongFraction, out onSegmentRightSide); if (offset <= nearestDistance) { if (!onSegmentRightSide.HasValue && !nearestOnRightSide.HasValue && nearestSegment != null) { nearestOnRightSide = GetOnRightSide( nearestSegment, nearestFraction, segmentProxy, alongFraction, neighborCurve); } else if (offset < nearestDistance) { nearestOnRightSide = onSegmentRightSide; } nearestDistance = offset; nearestSegment = segmentProxy; nearestFraction = alongFraction; } } if (nearestSegment != null) { double f = Math.Min(1, Math.Max(0, nearestFraction)); IPnt p = nearestSegment.GetPointAt(f, as3D: true); nearestPoint.PutCoords(p.X, p.Y); nearestPoint.Z = p[2]; if (!nearestOnRightSide.HasValue) { // Extend segment lineary to determine right side Pnt s = nearestSegment.GetStart(as3D: false); Pnt e = nearestSegment.GetEnd(as3D: false); if (nearestFraction >= 1) { nearestOnRightSide = (e - s).VectorProduct(e - qaPoint) > 0; } else if (nearestFraction <= 0) { nearestOnRightSide = (e - s).VectorProduct(s - qaPoint) > 0; } } } onRightSide = nearestOnRightSide ?? false; return(nearestDistance); } }