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 for Desktop Basic | ArcGIS for Desktop Basic |
ArcGIS for Desktop Standard | ArcGIS for Desktop Standard |
ArcGIS for Desktop Advanced | ArcGIS for Desktop Advanced |
Engine Developer Kit | Engine |