Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non affine transform #925

Closed
leoshusar opened this issue Jun 28, 2023 · 1 comment
Closed

Non affine transform #925

leoshusar opened this issue Jun 28, 2023 · 1 comment

Comments

@leoshusar
Copy link

Hi! Is non affine transformation impossible in Win2D? I found this MAUI issue with the same question without response.

I'm not a mathematician, so I've been currently struggling rewriting my SkiaSharp transformation (which I also found on the internet):

public static SKMatrix ComputeMatrix(SKSize size, SKPoint upperLeft, SKPoint upperRight, SKPoint lowerLeft, SKPoint lowerRight)
{
    // Scale transform
    var S = SKMatrix.CreateScale(1 / size.Width, 1 / size.Height);

    // Affine transform
    var A = new SKMatrix
    {
        ScaleX = upperRight.X - upperLeft.X,
        SkewY = upperRight.Y - upperLeft.Y,
        SkewX = lowerLeft.X - upperLeft.X,
        ScaleY = lowerLeft.Y - upperLeft.Y,
        TransX = upperLeft.X,
        TransY = upperLeft.Y,
        Persp2 = 1
    };

    // Non-Affine transform
    A.TryInvert(out var inverseA);
    var abPoint = inverseA.MapPoint(lowerRight);
    var a = abPoint.X;
    var b = abPoint.Y;

    var scaleX = a / (a + b - 1);
    var scaleY = b / (a + b - 1);

    var N = new SKMatrix
    {
        ScaleX = scaleX,
        ScaleY = scaleY,
        Persp0 = scaleX - 1,
        Persp1 = scaleY - 1,
        Persp2 = 1
    };

    // Multiply S * N * A
    var result = SKMatrix.CreateIdentity();
    result = result.PostConcat(S);
    result = result.PostConcat(N);
    result = result.PostConcat(A);

    return result;
}

to System.Numerics implementation, but I realized Matrix3x2 lacks the perspective elements so I have no way to complete it.

My use case is I'm making a projector calibration where you set corner points and the whole canvas would fit into those points. I wanted to compute the matrix and set it to the drawing session like drawingSession.Transform = matrix similarly to how I did it in SkiaSharp before. But since Matrix3x2 is too small... unless there is some math magic I don't know about, this is currently impossible?

If so, please take this as a feature request.

@getrou
Copy link
Member

getrou commented Jul 24, 2023

You are correct that perspective transforms are not possible with a Matrix3x2. There are tricks you could use, where you increase the X and Y scale of an image based on some "Z" value, or using a custom effect, but it isn't inherently built into Win2D.

The Composition layer allows for this, using Visual.TransformMatrix (which is 4x4), and has some interop with Win2D, but Win2D itself is scoped to 2D rendering.

@getrou getrou closed this as completed Nov 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants