private static bool CutCurveHullBuffer([NotNull] SegmentProxy segment, [NotNull] SegmentProxy hull, bool is3D, double r2, [NotNull] out IList <double[]> limits, out NearSegment hullStartNear, out NearSegment hullEndNear, out bool coincident) { coincident = GetCoincident(segment, hull, is3D, out hullStartNear, out hullEndNear); if (r2 > 0) { IPolygon buffer = hull.CreateBuffer(Math.Sqrt(r2)); limits = SegmentUtils.GetLimits(segment, buffer); } else if (coincident) { limits = new List <double[]>(); limits.Add(new double[] { 0, 1 }); } else { limits = new List <double[]>(); } return(limits.Count > 0); }
public SegmentProxy GetSegment(int partIndex, int segmentIndex) { PartProxy partProxy = _partProxies[partIndex]; SegmentProxy segmentProxy = partProxy.GetSegment(segmentIndex); return(segmentProxy); }
public static bool CutCurveCircle([NotNull] SegmentProxy segmentProxy, [NotNull] Pnt circleCenter, double r2, bool as3D, out IList <double[]> limits) { if (segmentProxy.IsLinear) { double tMin; double tMax; bool cut = as3D ? CutLineCircle3D(segmentProxy, circleCenter, r2, out tMin, out tMax) : CutLineCircle2D(segmentProxy, circleCenter, r2, out tMin, out tMax); limits = new List <double[]>(); if (cut && tMin < 1 && tMax > 0) { limits.Add(new[] { tMin, tMax }); } return(cut); } return(CutCurveCircle(segmentProxy, circleCenter, r2, out limits)); }
public IEnumerable <SegmentProxy> GetSegments() { for (int i = 0; i < SegmentCount; i++) { SegmentProxy seg = GetSegment(i); yield return(seg); } }
internal static IList <double[]> GetLimits([NotNull] SegmentProxy segmentProxy, [NotNull] IPolygon buffer) { // TODO this method would be extremely expensive when called on WksSegmentProxy instances var result = new List <double[]>(); // Remark: segmentLine is altered by ITopologicalOperator.Intersect in such a way // that equal segments may not be considered as equal anymore IPolyline segmentLine = segmentProxy.GetPolyline(true); //IPolyline segmentLine = segmentProxy.GetPolyline(); var intersects = (IGeometryCollection) ((ITopologicalOperator)buffer).Intersect( segmentLine, esriGeometryDimension.esriGeometry1Dimension); int intersectCount = intersects.GeometryCount; for (var i = 0; i < intersectCount; i++) { var part = (IPath)intersects.Geometry[i]; double t0 = 0; double t1 = 0; double offset = 0; var rightSide = false; // TODO if called frequently, create abstract GetSegmentDistance(IPoint) on SegmentProxy, // with custom implementation on WksSegmentProxy. // Currently this seems to be called for AoSegmentProxys only, but this is not obvious. // TODO use a template point and part.QueryFromPoint() / part.QueryToPoint()? segmentLine.QueryPointAndDistance(esriSegmentExtension.esriExtendTangents, part.FromPoint, true, HelpPoint, ref t0, ref offset, ref rightSide); segmentLine.QueryPointAndDistance(esriSegmentExtension.esriExtendTangents, part.ToPoint, true, HelpPoint, ref t1, ref offset, ref rightSide); double tMin = Math.Min(t0, t1); double tMax = Math.Max(t0, t1); result.Add(new[] { tMin, tMax }); } // Handle spatial tolerance problems for segments near tolerance size! if (intersectCount == 0 && !((IRelationalOperator)buffer).Disjoint(segmentLine)) { ((ITopologicalOperator)segmentLine).Simplify(); if (segmentLine.IsEmpty) { result.Add(new[] { 0.0, 1.0 }); } } return(result); }
public SegmentHull([NotNull] SegmentProxy segment, double leftOffset, double rightOffset, [NotNull] SegmentCap startCap, [NotNull] SegmentCap endCap) { _segment = segment; _leftOffset = leftOffset; _rightOffset = rightOffset; _startCap = startCap; _endCap = endCap; }
public static double GetClosestPointFraction([NotNull] SegmentProxy segmentProxy, [NotNull] Pnt nearPoint, bool as3D) { double?offset; bool? onRightSide; return(GetClosestPointFraction(segmentProxy, nearPoint, out offset, out onRightSide, as3D)); }
private static bool CutLineCircle2D([NotNull] SegmentProxy segmentProxy, [NotNull] Pnt center, double r2, out double tMin, out double tMax) { const bool as3D = false; var p0s = (Pnt2D)segmentProxy.GetStart(as3D); var p0e = (Pnt2D)segmentProxy.GetEnd(as3D); Pnt l0 = p0e - p0s; return(CutLineCircle(p0s, l0, center, r2, out tMin, out tMax)); }
public static double GetClosestPointFraction([NotNull] SegmentProxy segmentProxy, [NotNull] Pnt nearPoint, out double?offset, out bool?onRightSide, bool as3D) { if (segmentProxy.IsLinear) { Pnt p0s = segmentProxy.GetStart(as3D); Pnt p0e = segmentProxy.GetEnd(as3D); Pnt l0 = p0e - p0s; offset = null; onRightSide = null; return(GetAlongFraction(nearPoint - p0s, l0)); } const bool forceCreation = true; IPolyline segmentLine = segmentProxy.GetPolyline(forceCreation); IPoint near = new PointClass(); near.PutCoords(nearPoint.X, nearPoint.Y); IPoint onPoint = new PointClass(); double fraction = 0; double offsetValue = 0; var rightSide = false; const bool asRatio = true; segmentLine.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, near, asRatio, onPoint, ref fraction, ref offsetValue, ref rightSide); offset = offsetValue; onRightSide = rightSide; return(fraction); }
private static bool CutCurveCircle([NotNull] SegmentProxy segmentProxy, [NotNull] IPnt circleCenter, double r2, [NotNull] out IList <double[]> limits) { double radius = Math.Sqrt(r2); IPoint center = new Point(); center.PutCoords(circleCenter.X, circleCenter.Y); ICircularArc arc = new CircularArcClass(); arc.PutCoordsByAngle(center, 0, 2 * Math.PI, radius); object emptyRef = Type.Missing; IPolygon circle = new PolygonClass(); ((ISegmentCollection)circle).AddSegment(((ISegment)arc), ref emptyRef, ref emptyRef); limits = GetLimits(segmentProxy, circle); return(limits.Count > 0); }
public IPolyline GetSubpart(int startSegmentIndex, double startFraction, int endSegmentIndex, double endFraction) { IPointCollection4 subpart = new PolylineClass(); ((IZAware)subpart).ZAware = true; var add = 2; if (endFraction == 0) { add = 1; } int pointCount = endSegmentIndex - startSegmentIndex + add; var points = new WKSPointZ[pointCount]; SegmentProxy seg0 = GetSegment(startSegmentIndex); IPnt p = seg0.GetPointAt(startFraction, true); points[0] = QaGeometryUtils.GetWksPoint(p); for (int i = startSegmentIndex + 1; i <= endSegmentIndex; i++) { points[i - startSegmentIndex] = GetPlanePoint(i); } if (endFraction > 0) { SegmentProxy seg1 = GetSegment(endSegmentIndex); IPnt end = seg1.GetPointAt(endFraction, true); points[pointCount - 1] = QaGeometryUtils.GetWksPoint(end); } GeometryUtils.SetWKSPointZs(subpart, points); return((IPolyline)subpart); }
private IPolyline GetLinearSubpart(int startSegmentIndex, double startFraction, int endSegmentIndex, double endFraction) { IPointCollection4 subpart = new PolylineClass(); int add = 2; if (endFraction == 0) { add = 1; } int pointCount = endSegmentIndex - startSegmentIndex + add; var points = new WKSPointZ[pointCount]; SegmentProxy seg0 = GetSegment(startSegmentIndex); IPnt p = seg0.GetPointAt(startFraction, as3D: true); points[0] = QaGeometryUtils.GetWksPoint(p); for (int i = startSegmentIndex + 1; i <= endSegmentIndex; i++) { points[i - startSegmentIndex] = _points[i]; } if (endFraction > 0) { SegmentProxy seg1 = GetSegment(endSegmentIndex); IPnt end = seg1.GetPointAt(endFraction, as3D: true); points[pointCount - 1] = QaGeometryUtils.GetWksPoint(end); } GeometryUtils.SetWKSPointZs(subpart, points); ((IPolyline)subpart).SpatialReference = SpatialReference; return((IPolyline)subpart); }
private static bool GetCoincident([NotNull] SegmentProxy segment, [NotNull] SegmentProxy hull, bool is3D, out NearSegment hullStartNear, out NearSegment hullEndNear) { hullStartNear = NearSegment.NotNear; // TODO hullEndNear = NearSegment.NotNear; // TODO IPolyline segLine = segment.GetPolyline(false); IPolyline hullLine = hull.GetPolyline(false); if (!((IRelationalOperator)segLine).Equals(hullLine)) { return(false); } var coincident = true; Pnt segmentStart = segment.GetStart(is3D); Pnt segmentEnd = segment.GetEnd(is3D); Pnt hullStart = hull.GetStart(is3D); Pnt hullEnd = hull.GetEnd(is3D); double distFromSegFromHull; { double dx = segmentStart.X - hullStart.X; double dy = segmentStart.Y - hullStart.Y; distFromSegFromHull = dx * dx + dy * dy; } double distFromSegToHull; { double dx = segmentStart.X - hullEnd.X; double dy = segmentStart.Y - hullEnd.Y; distFromSegToHull = dx * dx + dy * dy; } bool isInverse = (distFromSegFromHull > distFromSegToHull); Pnt hullMatchSegFrom; Pnt hullMatchSegTo; if (!isInverse) { hullMatchSegFrom = hullStart; hullMatchSegTo = hullEnd; } else { hullMatchSegFrom = hullEnd; hullMatchSegTo = hullStart; } if (is3D) { double zPrecision = 0; ISpatialReference spatialReference = segment.SpatialReference; if (spatialReference != null && spatialReference.HasZPrecision()) { double falseZ; double zUnits; spatialReference.GetZFalseOriginAndUnits(out falseZ, out zUnits); zPrecision = 1 / zUnits; } if (Math.Abs(hullMatchSegFrom[2] - segmentStart[2]) > zPrecision || Math.Abs(hullMatchSegTo[2] - segmentStart[2]) > zPrecision) { coincident = false; } } if (coincident) { if (!isInverse) { hullStartNear = NearSegment.NearStart; hullEndNear = NearSegment.NearEnd; } else { hullStartNear = NearSegment.NearEnd; hullEndNear = NearSegment.NearStart; } } return(coincident); }