I am being driven nuts by what should be a dead simple bit of matrix maths.
I am drawing a simple graph using SkiaSharp. I have a SKPath, which describes the plot of the graph. I have simulated this in the code below by a silly bit of code that just produces 50 drawable points. To draw the graph, I wish to scale it horizontally according to a value that is updated when the user pinches the screen and I want to offset the graph by a fixed amount to line it up with the x=0 point on the screen.
In the code below, the first version of the code that does two separate transforms works fine. So I thought, for efficiency, I would combine the two matrices and do one single transform. I have tried all four combinations of pre- and post- concatenation and none of them stays overlaid on the first correct line. In other words, no matter how I compose the matrices, I cannot get the same result I get by applying the matrices separately.
What am I doing wrong?
SKCanvas canvas = null; // This is passed into the drawing function.
SKPaint pen = new SKPaint()
{
Style = SKPaintStyle.Stroke,
StrokeWidth = 1.0f,
Color = SKColor.Parse( "#B0FFDD00" )
};
float horizontalScale = 1.0f;
float x = 0.0f;
float y = 0.0f;
SKPath path = new SKPath();
path.MoveTo( x, y );
for( int i = 0; i < 50; ++i )
{
x = (float)( i * 10 );
y += ( i % 10 == 0 ) ? -5.0f : (float)i * 0.8f;
path.LineTo( x, y );
}
// This one works fine.
SKMatrix scaleMatrix1 = SKMatrix.MakeScale( horizontalScale, 1.0f );
path.Transform( scaleMatrix1 );
SKMatrix translationMatrix1 = SKMatrix.MakeTranslation( 50.0f, 0.0f );
path.Transform( translationMatrix1 );
canvas.DrawPath( path, pen );
// This does not work as expected.
SKMatrix scaleMatrix2 = SKMatrix.MakeScale( horizontalScale, 1.0f );
SKMatrix translationMatrix2 = SKMatrix.MakeTranslation( 50.0f, 0.0f );
SKMatrix.PreConcat( ref translationMatrix2, scaleMatrix2 );
path.Transform( translationMatrix2 );
canvas.DrawPath( path, pen );
// Neither does this.
SKMatrix scaleMatrix3 = SKMatrix.MakeScale( horizontalScale, 1.0f );
SKMatrix translationMatrix3 = SKMatrix.MakeTranslation( 50.0f, 0.0f );
SKMatrix.PostConcat( ref translationMatrix3, scaleMatrix3 );
path.Transform( translationMatrix3 );
canvas.DrawPath( path, pen );
// Neither does this.
SKMatrix scaleMatrix4 = SKMatrix.MakeScale( horizontalScale, 1.0f );
SKMatrix translationMatrix4 = SKMatrix.MakeTranslation( 50.0f, 0.0f );
SKMatrix.PreConcat( ref scaleMatrix4, translationMatrix4 );
path.Transform( scaleMatrix4 );
canvas.DrawPath( path, pen );
// And neither does this.
SKMatrix scaleMatrix5 = SKMatrix.MakeScale( horizontalScale, 1.0f );
SKMatrix translationMatrix5 = SKMatrix.MakeTranslation( 50.0f, 0.0f );
SKMatrix.PostConcat( ref scaleMatrix5, translationMatrix5 );
path.Transform( scaleMatrix5 );
canvas.DrawPath( path, pen );