public bool Cut(HullLineArc line, ref double tMin, ref double tMax) { double angS = line.StartDirection; double r = line.Radius; // Handle start point of line-arc var aS = new Pnt2D(r * Math.Cos(angS), r * Math.Sin(angS)); Lin2D s = line.Lin.GetParallel(aS); bool intersects = CutLineThis(s.Ps, s.L, ref tMin, ref tMax); // Handle end point of line-arc double angE = angS + line.Angle; var aE = new Pnt2D(r * Math.Cos(angE), r * Math.Sin(angE)); Lin2D e = line.Lin.GetParallel(aE); intersects |= CutLineThis(e.Ps, e.L, ref tMin, ref tMax); if (Angle.HasValue) { intersects |= CutLineEndpoint(StartDirection + Angle.Value, line, ref tMin, ref tMax); intersects |= CutLineEndpoint(StartDirection, line, ref tMin, ref tMax); } intersects |= CutLineThis(line.Lin.Ps, line.Lin.L, ref tMin, ref tMax, new SignedHullLineArc(line, deflate: false)); intersects |= CutLineThis(line.Lin.Ps, line.Lin.L, ref tMin, ref tMax, new SignedHullLineArc(line, deflate: true)); return(intersects); }
public bool Cut(HullLineLine line, ref double tMin, ref double tMax) { // Handle start point of endPart Pnt lS = line.EndPart.Ps; Lin2D s = line.Lin.GetParallel(lS); bool intersects = CutLineThis(s.Ps, s.L, ref tMin, ref tMax); // Handle end point of endPart Pnt lE = line.EndPart.Pe; Lin2D e = line.Lin.GetParallel(lE); intersects |= CutLineThis(e.Ps, e.L, ref tMin, ref tMax); if (Angle.HasValue) { double r = _radius; // Handle start point of arc double angS = StartDirection; Pnt aS = new Pnt2D(r * Math.Cos(angS), r * Math.Sin(angS)) + _center - lS; Lin2D eS = line.EndPart.GetParallel(aS); intersects |= LineHullPart.CutLin(eS, e, ref tMin, ref tMax); // Handle end point of arc double angE = StartDirection + Angle.Value; Pnt aE = new Pnt2D(r * Math.Cos(angE), r * Math.Sin(angE)) + _center - lS; Lin2D eE = line.EndPart.GetParallel(aE); intersects |= LineHullPart.CutLin(eE, e, ref tMin, ref tMax); } // Handle tangents Pnt eNormal = line.EndPart.LNormal; double dir = Angle.HasValue ? Math.Atan2(eNormal.Y, eNormal.X) : double.NaN; if (!Angle.HasValue || IsInArcAngle(dir)) { Lin2D eT0 = line.EndPart.GetParallel(_center + _radius * eNormal - lS); intersects |= LineHullPart.CutLin(eT0, e, ref tMin, ref tMax); } if (!Angle.HasValue || IsInArcAngle(dir + Math.PI)) { Lin2D eT1 = line.EndPart.GetParallel(_center - _radius * eNormal - lS); intersects |= LineHullPart.CutLin(eT1, e, ref tMin, ref tMax); } return(intersects); }
public override IEnumerable <IHullPart> GetInflatedHullParts(Pnt at, Pnt opposite, double offset, double inflate) { Pnt l = opposite - at; double l0 = Math.Sqrt(l * l); Pnt lNorm = new Pnt2D(l.X / l0, l.Y / l0); Pnt vNorm = new Pnt2D(lNorm.Y, -lNorm.X); Pnt pntOffset = Math.Max(0, offset - _length) * vNorm; yield return(new CircleHullPart(at + pntOffset, _length + inflate)); Pnt cap = at - (_length + inflate) * lNorm; yield return(new LineHullPart(cap + pntOffset, cap - pntOffset)); yield return(new CircleHullPart(at - pntOffset, _length + inflate)); }
public bool Cut(HullLineArc line, ref double tMin, ref double tMax) { double angS = line.StartDirection; double r = line.Radius; // Handle start point of arc var aS = new Pnt2D(r * Math.Cos(angS), r * Math.Sin(angS)); Lin2D s = line.Lin.GetParallel(aS); bool intersects = CutLin(_lin, s, ref tMin, ref tMax); // Handle end point of arc double angE = angS + line.Angle; var aE = new Pnt2D(r * Math.Cos(angE), r * Math.Sin(angE)); Lin2D e = line.Lin.GetParallel(aE); intersects |= CutLin(_lin, e, ref tMin, ref tMax); // Handle this start/end point intersects |= CutArcLine(_lin.Ps, line, ref tMin, ref tMax); intersects |= CutArcLine(_lin.Pe, line, ref tMin, ref tMax); // handle sides double arcAngle = GetNormedAngle(line.Angle); Pnt normal = _lin.LNormal; double normalDir = _lin.DirectionAngle + Math.PI / 2; // handle left side if (GetNormedAngle(normalDir - line.StartDirection) < arcAngle) { intersects |= CutLin(_lin.GetParallel(r * normal), line.Lin, ref tMin, ref tMax); } // handle right side if (GetNormedAngle(normalDir + Math.PI - line.StartDirection) < arcAngle) { intersects |= CutLin(_lin.GetParallel(-r * normal), line.Lin, ref tMin, ref tMax); } return(intersects); }
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); } }
public static bool SnapPoint([NotNull] IPoint newEndPoint, [NotNull] IList <IFeature> candidateTargetEdges, [NotNull] ILinearNetworkFeatureFinder networkFeatureFinder) { if (networkFeatureFinder.SearchTolerance <= 0) { return(false); } Pnt2D newEndPnt = new Pnt2D(newEndPoint.X, newEndPoint.Y); IPoint fromPoint = new PointClass() { SpatialReference = newEndPoint.SpatialReference }; IPoint toPoint = new PointClass() { SpatialReference = newEndPoint.SpatialReference }; double searchToleranceSquared = networkFeatureFinder.SearchTolerance * networkFeatureFinder.SearchTolerance; bool snapped = false; foreach (IFeature feature in candidateTargetEdges) { IPolyline otherPolyline = (IPolyline)feature.Shape; otherPolyline.QueryFromPoint(fromPoint); Pnt2D fromPnt = new Pnt2D(fromPoint.X, fromPoint.Y); double fromDistance2 = fromPnt.Dist2(newEndPnt); otherPolyline.QueryToPoint(toPoint); Pnt2D toPnt = new Pnt2D(toPoint.X, toPoint.Y); double toDistance2 = toPnt.Dist2(newEndPnt); if (fromDistance2 > searchToleranceSquared && toDistance2 > searchToleranceSquared) { continue; } if (Math.Min(fromDistance2, toDistance2) < GetXyResolutionSquared(feature)) { // already snapped continue; } IPoint sourcePoint = fromDistance2 < toDistance2 ? fromPoint : toPoint; snapped = true; CopyCoords(sourcePoint, newEndPoint); } if (!snapped) { // Try snapping onto curve interior foreach (IFeature feature in candidateTargetEdges) { IPolyline otherPolyline = (IPolyline)feature.Shape; double distanceFromCurve = GeometryUtils.GetDistanceFromCurve(newEndPoint, otherPolyline, fromPoint); if (distanceFromCurve >= 0 && distanceFromCurve < networkFeatureFinder.SearchTolerance) { snapped = true; CopyCoords(fromPoint, newEndPoint); } } } return(snapped); }