Hello Andy,
the typical approach: with the method Rotate() you can determine the rotation angle before adding the triangle to the path. To rotate the triangle around its center you will also need to use the method Translate() to move the origin of the coordinate system to the center of the triangle. Please see the documentation Apply 2D transformations during the path creation. Please note, the both methods PushMatrix() and PopMatrix() are convenient to store the transformation matrix before you apply a rotation and the to restore it again. It is important if you adds several triangles each with different rotation angle. For example:
Path.SetMaxNoOfSubPaths( 3 );
// TRIANGLE #1 at position 150,100 and -15°
// Initialize the Sub-Path for the first triangle
Path.InitSubPath( 0, 3 );
Path.PushMatrix();
// Move to the center of the first triangle
Path.Translate( 150, 100 );
Path.Rotate( -15.0 );
// Add an equilateral triangle with 100 pixel long edge.
Path.Begin ( 0, -50.0, 43.3 );
Path.AddLine( 0, 0.0, -43.3 );
Path.AddLine( 0, 50.0, 43.3 );
Path.Close( 0 );
// Restore the transformation matrix.
Path.PopMatrix();
// TRIANGLE #2 at position 250,175 and 45°
// Initialize the Sub-Path for the first triangle
Path.InitSubPath( 1, 3 );
Path.PushMatrix();
// Move to the center of the first triangle
Path.Translate( 250, 175 );
Path.Rotate( 45.0 );
// Add an equilateral triangle with 100 pixel long edge.
Path.Begin ( 1, -50.0, 43.3 );
Path.AddLine( 1, 0.0, -43.3 );
Path.AddLine( 1, 50.0, 43.3 );
Path.Close( 1 );
// Restore the transformation matrix.
Path.PopMatrix();
// TRIANGLE #3 at position 50,250 and 100°
// Initialize the Sub-Path for the first triangle
Path.InitSubPath( 2, 3 );
Path.PushMatrix();
// Move to the center of the first triangle
Path.Translate( 50, 250 );
Path.Rotate( 100.0 );
// Add an equilateral triangle with 100 pixel long edge.
Path.Begin ( 2, -50.0, 43.3 );
Path.AddLine( 2, 0.0, -43.3 );
Path.AddLine( 2, 50.0, 43.3 );
Path.Close( 2 );
// Restore the transformation matrix.
Path.PopMatrix();
In this example you see, that for every triangle we add exact he same coordinate 3-coordinates (-50,43.3, 0.0, -43.3, 50.0, 43.3). That the resulting triangles appear rotated and correctly positioned is determined by the preceding Rotate() and Translate() method invocation. To avoid, that rotation/position of triangle #1 affect the triangle #2 we use PushMatrix() and PopMatrix() invocation. They save the intermediate state of the matrix.
With the above example you create every triangle separately from three line segments. You can simplify this by using a temporary sub-path. In other words, you store the basic form of the triangle in a first sub-path and then you copy this basic triangle by applying the right transformation:
Path.SetMaxNoOfSubPaths( 4 );
// The sub-path #0 stores the basic form of a triangle with its default size and orientation 0°
Path.InitSubPath( 0, 3 );
Path.Begin ( 0, -50.0, 43.3 );
Path.AddLine( 0, 0.0, -43.3 );
Path.AddLine( 0, 50.0, 43.3 );
Path.Close( 0 );
// TRIANGLE #1 creates a copy of the previously prepare triangle at position 150,100 and -15°
// Initialize the Sub-Path for the first triangle
Path.InitSubPath( 1, 3 );
Path.PushMatrix();
Path.Translate( 150, 100 );
Path.Rotate( -15.0 );
// Add a copy of the previously prepared sub-path
Path.AddCopy( 1, Path, 0, 0, 3 );
Path.Close( 1 );
// Restore the transformation matrix.
Path.PopMatrix();
// TRIANGLE #2 at position 250,175 and 45°
// Initialize the Sub-Path for the first triangle
Path.InitSubPath( 2, 3 );
Path.PushMatrix();
Path.Translate( 250, 175 );
Path.Rotate( 45.0 );
// Add a copy of the previously prepared sub-path
Path.AddCopy( 2, Path, 0, 0, 3 );
Path.Close( 2 );
// Restore the transformation matrix.
Path.PopMatrix();
// TRIANGLE #3 at position 50,250 and 100°
// Initialize the Sub-Path for the first triangle
Path.InitSubPath( 3, 3 );
Path.PushMatrix();
Path.Translate( 50, 250 );
Path.Rotate( 100.0 );
// Add a copy of the previously prepared sub-path
Path.AddCopy( 3, Path, 0, 0, 3 );
Path.Close( 3 );
// Restore the transformation matrix.
Path.PopMatrix();
// The basic form of the triangle is not needed anymore.
Path.InitSubPath( 0, 0 );
The both above approaches create/initialize new paths. They are thus ideal if you receive new data for all the triangles and you re-create all triangles. If the data changes for few of the triangles, then you can re-initialize the corresponding sub-path only. All other sub-paths will retain their contents. In this case, however, you should prepare the path to have enough capacity for the maximum number of triangles. For example, if your aplication will show up to 100 triangles:
// Initialize the path to be able to store up to 100 triangles
Path.SetMaxNoOfSubPaths( 100 );
Later when you receive new data for triangle number e.g. 17, you just reinitialize this sub-path:
// Initialize the Sub-Path for the updated triangle
Path.InitSubPath( 17, 3 );
Path.PushMatrix();
Path.Translate( ... );
[...]
Completely another approach is to access and modify the coordinates of the respectove nodes. Please see Evaluate and modify the coordinates stored in the Path Data object. With this approach you can take care of the rotation and translation of the triangle coordinates. You just assign the resulting coordinates to the path. Please note, to do this the respective sub-path has to contain the edges already - it has to be initialized and loaded with some data. Otherwise you can't access the coordfinates.
I hope it helps you further.
Best regards
Paul Banach