/// <summary> /// /// </summary> private void BuildIndex() { Envelope env = _ring.GetEnvelopeInternal(); _sirTree = new SIRtree(); Coordinates pts = Coordinates.RemoveRepeatedPoints(_ring.GetCoordinates()); for (int i = 1; i < pts.Count; i++) { LineSegment seg = new LineSegment(pts[i - 1], pts[i]); _sirTree.Insert(seg.P0.Y, seg.P1.Y, seg); } }
/// <summary> /// Add an end cap around point p1, terminating a line segment coming from p0 /// </summary> /// <param name="p0"></param> /// <param name="p1"></param> private void AddLineEndCap(Coordinate p0, Coordinate p1) { LineSegment seg = new LineSegment(p0, p1); LineSegment offsetL = new LineSegment(); ComputeOffsetSegment(seg, Position.Left, _distance, offsetL); LineSegment offsetR = new LineSegment(); ComputeOffsetSegment(seg, Position.Right, _distance, offsetR); double dx = p1.X - p0.X; double dy = p1.Y - p0.Y; double angle = Math.Atan2(dy, dx); AddPt(offsetL.P1); AddFillet(p1, angle + Math.PI / 2, angle - Math.PI / 2, CGAlgorithms.CLOCKWISE, _distance); AddPt(offsetR.P1); }
private void ComputeOffsetSegment(LineSegment seg, int side, double distance, LineSegment offset) { int sideSign = side == Position.Left ? 1 : -1; double dx = seg.P1.X - seg.P0.X; double dy = seg.P1.Y - seg.P0.Y; double len = Math.Sqrt(dx * dx + dy * dy); // u is the vector that is the length of the offset, in the direction of the segment double ux = sideSign * distance * dx / len; double uy = sideSign * distance * dy / len; offset.P0.X = seg.P0.X - uy; offset.P0.Y = seg.P0.Y + ux; offset.P1.X = seg.P1.X - uy; offset.P1.Y = seg.P1.Y + ux; }
public override void Select(LineSegment ls) { _nested.TestLineSegment(_p, ls); }
/// <summary> /// /// </summary> /// <param name="p"></param> /// <param name="seg"></param> private void TestLineSegment(Coordinate p, LineSegment seg) { double xInt; // x intersection of segment with ray double x1; // translated coordinates double y1; double x2; double y2; //Test if segment crosses ray from test point in positive x direction. Coordinate p1 = seg.P0; Coordinate p2 = seg.P1; x1 = p1.X - p.X; y1 = p1.Y - p.Y; x2 = p2.X - p.X; y2 = p2.Y - p.Y; if (((y1 > 0) && (y2 <= 0)) || ((y2 > 0) && (y1 <= 0))) { //segment straddles x axis, so compute intersection. xInt = RobustDeterminant.SignOfDet2x2(x1, y1, x2, y2) / (y2 - y1); //xsave = xInt; //crosses ray if strictly positive intersection. if (0.0 < xInt) { _crossings++; } } }
internal LineSegment( LineSegment ls ) : this( ls.P0, ls.P1 ) { }
/// <summary> /// Returns true if other is topologically equals to this LineSegment (e.g. irrespective of orientation). /// </summary> /// <param name="other">The other LineSegment with which to do the comparison.</param> /// <returns>Returns true if other is a LineSegment with the same values for the x and y ordinates.</returns> public bool EqualsTopology( LineSegment other ) { return _p0.Equals( other.P0 ) && _p1.Equals( other.P1 ) || _p0.Equals( other.P1 ) && _p1.Equals( other.P0 ); }
/// <summary> /// Project a line segment onto this line segment and return the resulting /// line segment. The returned line segment will be a subset of /// the target line line segment. This subset may be null, if /// the segments are oriented in such a way that there is no projection. /// </summary> /// <remarks>Note that the returned line may have zero length (i.e. the same endpoints). /// This can happen for instance if the lines are perpendicular to one another.</remarks> /// <param name="seg">The line segment to project.</param> /// <returns>Returns the projected line segment, or null if there is no overlap.</returns> public LineSegment Project( LineSegment seg ) { double pf0 = ProjectionFactor( seg.P0 ); double pf1 = ProjectionFactor( seg.P1 ); // check if segment projects at all if (pf0 >= 1.0 && pf1 >= 1.0) return null; if (pf0 <= 0.0 && pf1 <= 0.0) return null; Coordinate newp0 = Project( seg.P0 ); if (pf0 < 0.0) newp0 = _p0; if (pf0 > 1.0) newp0 = _p1; Coordinate newp1 = Project( seg.P1 ); if (pf1 < 0.0) newp1 = _p0; if (pf1 > 1.0) newp1 = _p1; return new LineSegment( newp0, newp1 ); }
/// <summary> /// Computes the distance between this line segment and another one. /// </summary> /// <param name="ls">Other LineSegment with which to calculate the distance.</param> /// <returns></returns> public double Distance(LineSegment ls) { return CGAlgorithms.DistanceLineLine( _p0, _p1, ls.P0, ls.P1 ); }
/// <summary> /// Sets the coordinates for this line segment based on the incoming LineSegment. /// </summary> /// <param name="ls"></param> public void SetCoordinates( LineSegment ls ) { SetCoordinates( ls.P0, ls.P1 ); }
} // public Envelope GetEnvelope() /// <summary> /// /// </summary> /// <param name="index"></param> /// <param name="ls"></param> public void GetLineSegment( int index, ref LineSegment ls ) { if ( ls == null ) { throw new ArgumentNullException( "ls", "LineSegment parameter is null when object was expected"); } if ( index < 0 || index >= _pts.Count ) { throw new IndexOutOfRangeException( "Coordinates index was out of range:"+index.ToString() ); } ls.P0 = _pts[index]; ls.P1 = _pts[index + 1]; } // public void GetLineSegment( int index, ref LineSegment ls )
/// <summary> /// ??? /// </summary> /// <param name="seg"></param> public virtual void Select( LineSegment seg ) { }
} // public void Overlap(MonotoneChain mc1, int start1, MonotoneChain mc2, int start2) /// <summary> /// /// </summary> /// <param name="seg1"></param> /// <param name="seg2"></param> public void Overlap(LineSegment seg1, LineSegment seg2) { }