rotationnettopologysuite

NetTopologySuite : Rotating a LineSegment


In NetTopologySuite, how do you rotate a LineSegment?

I have a LineRing called outerBoundary. As I could not find a direct method to extract the individual segments of this LineRing, I created an extension method as follows;

`

public static List<LineSegment> GetSegments(this LinearRing lineRing)
{
    List<LineSegment> segments = new List<LineSegment>();
    Coordinate[] coordinates = lineRing.Coordinates;
    for (int i = 0; i < coordinates.Length; i++)
    {
        segments.Add(new LineSegment(coordinates[i], coordinates[(i + 1 )% coordinates.Length]));
    }
    return segments;
}

`

Hence I call the GetSegments method on the outerBoundary, which returns the list of individual sides as a list of LineSegments. Now, I want to rotate each of these segments by an angle. If the GetSegments returned a list of LineStrings, I could have cereated a AffineTransformation instance with Rotation and apply that to each of these segments. But I felt having a list of LineSegment is intutional, as each of these sides will have only two end points, compared to LineString which allows more than two vertices. Now, how to do the same with LineSegments? As LineSegment doesnt inherit the Geometry base class, AffineTransformation cannot be applied on LineSegments is what I understand. Could someone help?


Solution

  • I would use a little trigonometry to move P0 and P1 in each segment by the origin point (in this case the midpoint).

    Using your code above, loop each of the segments

    foreach (LineSegment segment in segments)
            Rotate(segments, seg.MidPoint, rotation);
    

    And the code to rotate:

    public void Rotate(LineSegment segment, Coordinate origin, double radAngle)
    {
        double x = origin.X + (Math.Cos(radAngle) * (segment.P0.X - origin.X) - Math.Sin(radAngle) * (segment.P0.Y - origin.Y));
        double y = origin.Y + (Math.Sin(radAngle) * (segment.P0.X - origin.X) + Math.Cos(radAngle) * (segment.P0.Y - origin.Y));
        segment.P0.X = x;
        segment.P0.Y = y;
    
        x = origin.X + (Math.Cos(radAngle) * (segment.P1.X - origin.X) - Math.Sin(radAngle) * (segment.P1.Y - origin.Y));
        y = origin.Y + (Math.Sin(radAngle) * (segment.P1.X - origin.X) + Math.Cos(radAngle) * (segment.P1.Y - origin.Y));
        segment.P1.X = x;
        segment.P1.Y = y;
    }