This document is archived and information here might be outdated.  Recommended version.


How to perform an affine transformation (ArcObjects .NET 10.8 SDK)
ArcObjects Help for .NET developers > ArcObjects Help for .NET developers > Developing with ArcGIS > Learning ArcObjects > Managing data > Working with spatial references > How to perform an affine transformation

How to perform an affine transformation


Summary
This topic shows how to use an affine transformation to transform a digitized geometry into ground (projected) coordinates.

Performing an affine transformation

The following code example first uses an affine transformation to transform a digitized geometry into ground (projected) coordinates. The same transformation is then applied to an array of double precision, raw coordinate values. This second approach is useful when transforming large numbers of coordinates from a text file, binary file, or some other source of coordinates. This avoids the processing overhead of creating Component Object Model (COM) point objects for every coordinate.
[C#]
private void AffineTransformation2D_Example()
{
    // Define control points.
    IPoint[] controlFromPoints=new IPoint[4];
    // To point.
    IPoint[] controlToPoints=new IPoint[4];
    for (int i=0; i < 4; i++)
    {
        controlFromPoints[i]=new PointClass();
        controlToPoints[i]=new PointClass();
    }
    // From points.
    controlFromPoints[0].PutCoords(0, 0);
    controlFromPoints[1].PutCoords(0, 1);
    controlFromPoints[2].PutCoords(1, 0);
    controlFromPoints[3].PutCoords(1, 1);
    // To points.
    controlToPoints[0].PutCoords(5, 5);
    controlToPoints[1].PutCoords(5, 6);
    controlToPoints[2].PutCoords(6, 5);
    controlToPoints[3].PutCoords(6, 6);

    // Create an AffineTransformation2D object.
    // You have to use IAffineTransformation2D3GEN because DefineFromControlPoints
    // uses C-Style Arrays in IAffineTransformation2D, which are not usable in .NET.
    IAffineTransformation2D3GEN affineTransformation2D=new
        AffineTransformation2DClass();
    affineTransformation2D.DefineFromControlPoints(ref controlFromPoints, ref
        controlToPoints);

    double fromError=0;
    double toError=0;
    affineTransformation2D.GetRMSError(ref fromError, ref toError);
    if (fromError > 0.05)
    {
        System.Windows.Forms.MessageBox.Show(
            "RMS error is too large; please redigitize control points");
    }

    // Create a polygon.
    ISegmentCollection tranformPolygon=new Polygon()as ISegmentCollection;
    IEnvelope envelope=new EnvelopeClass();
    envelope.PutCoords(0, 0, 10, 10);
    tranformPolygon.SetRectangle(envelope);

    ITransform2D transformee=tranformPolygon as ITransform2D;
    transformee.Transform(esriTransformDirection.esriTransformForward,
        affineTransformation2D as ITransformation);

    // DigitizedGeometry is now in the destination coordinate system and should be assigned a 
    // spatial reference.
    // Now you will apply the same transformation directly to an array of double precision values 
    // representing (x,y) points.
    // The x,y values are assumed to be interleaved in the array: fromPoints(0) is the x-coordinate 
    // for the first point, fromPoints(1) is the y-coordinate, etc.
    int length=50;
    double[] fromPoints=new double[length];
    for (int i=0; i < length; i++)
    {
        fromPoints[i]=(i + 1) * 2;
    }
    double[] toPoints=new double[length];

    affineTransformation2D.TransformPointsFF
        (esriTransformDirection.esriTransformForward, ref fromPoints, ref toPoints);

    // Print results.
    String report="";
    for (int i=0; i < length; i++)
    {
        report=report + "Coordinate before=" + fromPoints[i] + 
            " and after transformation=" + toPoints[i] + "\n";
    }
    System.Windows.Forms.MessageBox.Show(report);

}
[VB.NET]
Private Sub AffineTransformation2D_Example()
    ' Define control points: Source points.
    Dim controlFromPoints(4) As IPoint
    
    ' Target points.
    Dim controlToPoints(4) As IPoint
    For i As Integer=0 To 4
        controlFromPoints(i)=New PointClass()
        controlToPoints(i)=New PointClass()
    Next i
    
    ' From points.
    controlFromPoints(0).PutCoords(0, 0)
    controlFromPoints(1).PutCoords(0, 1)
    controlFromPoints(2).PutCoords(1, 0)
    controlFromPoints(3).PutCoords(1, 1)
    
    ' To points.
    controlToPoints(0).PutCoords(5, 5)
    controlToPoints(1).PutCoords(5, 6)
    controlToPoints(2).PutCoords(6, 5)
    controlToPoints(3).PutCoords(6, 6)
    
    ' Create an AffineTransformation2D object.
    ' You have to use IAffineTransformation2D3GEN because DefineFromControlPoints
    ' uses C-Style Arrays in IAffineTransformation2D, which are not usable in .NET.
    Dim affineTransformation2D As IAffineTransformation2D3GEN=New AffineTransformation2DClass()
    affineTransformation2D.DefineFromControlPoints(controlFromPoints, controlToPoints)
    Dim fromError As Double=0
    Dim toError As Double=0
    AffineTransformation2D.GetRMSError(fromError, toError)
    
    If fromError > 0.05 Then
        System.Windows.Forms.MessageBox.Show("RMS error is too large; please redigitize control points")
    End If
    
    ' Create a polygon.
    Dim tranformPolygon As ISegmentCollection=New Polygon()
    Dim envelope As IEnvelope=New EnvelopeClass()
    envelope.PutCoords(0, 0, 10, 10)
    tranformPolygon.SetRectangle(envelope)
    Dim transformee As ITransform2D=CType(tranformPolygon, ITransform2D)
    transformee.Transform(esriTransformDirection.esriTransformForward, affineTransformation2D)
    
    ' DigitizedGeometry is now in the destination coordinate system and should be assigned a
    ' spatial reference.
    ' Now you will apply the same transformation directly to an array of double precision values
    ' representing (x,y) points.
    ' The x,y values are assumed to be interleaved in the array: fromPoints(0) is the x-coordinate
    ' for the first point, fromPoints(1) is the y-coordinate, etc.
    Dim Length As Integer=50
    Dim fromPoints(Length) As Double
    For i As Integer=0 To Length Step 1
        fromPoints(i)=((i + 1) * 2)
    Next i
    
    Dim toPoints(Length) As Double
    AffineTransformation2D.TransformPointsFF(esriTransformDirection.esriTransformForward, fromPoints, toPoints)
    
    ' Print results.
    Dim report As String=""
    For i As Integer=0 To Length -1 Step 1
        report=report & "Coordinate before=" & fromPoints(i) & " and after transformation=" & toPoints(i) & ControlChars.NewLine
    Next i
    System.Windows.Forms.MessageBox.Show(report)
End Sub






To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
Development licensing Deployment licensing
ArcGIS Desktop Basic ArcGIS Desktop Basic
ArcGIS Desktop Standard ArcGIS Desktop Standard
ArcGIS Desktop Advanced ArcGIS Desktop Advanced
Engine Developer Kit Engine