GraphiteEditor / Graphite

2D vector & raster editor that melds traditional layers & tools with a modern node-based, non-destructive, procedural workflow.
https://graphite.rs
Apache License 2.0
7.44k stars 394 forks source link

Perspective skew on the transform cage #1271

Open Keavon opened 1 year ago

Keavon commented 1 year ago

This lets the user skew the perspective of the rectangle with some arbitrary affine transform. The user can access this by dragging a corner of the transform cage while holding Ctrl.

0HyperCube commented 1 year ago

I do not believe this is possible with an Affine2.

You wish to allow the user to transform a unit square with vertices at (0,0) (1,0) (1,1) (0,1) into any arbitrary quadrilateral.

An affine transformation represented by a translation (which must be used to transform the point at the origin ). There is also a two by two matrix. The first column of the matrix (i) is the result of the transform of the vector (1,0) and the second column (j) is the result of the transformation of the vector (0,1). The transformation of the vector (1,1) is always equal to i+j (the two columns added together).

A visual proof that there is often no linear transformation to any arbitary points: image Note that during a linear transformation, the thin black grid lines must remain parallel and evenly spaced.

Keavon commented 1 year ago

I think we can mandate no convex concave angles, so the right image would be clamped to forming a triangle. Does that work with an affine transform?

0HyperCube commented 1 year ago

Only sometimes, see the following stack exchange answer: https://math.stackexchange.com/a/614375

Keavon commented 1 year ago

Is an affine transform a subset of a perspective transform? Should we consider switching our transforms to perspective transforms?

0HyperCube commented 1 year ago

Our current 2D affine transformations are a subset of perspective transformations.

Keavon commented 1 year ago

Ok, that's helpful to know. Are you aware of any impediments to switching to the superset, and do you know how much effort (and affected code) would be involved in such a refactor?

0HyperCube commented 7 months ago

@Keavon Search for DAffine2 - you will find 308 occurrences in 50 files.

0HyperCube commented 1 month ago

@Keavon another issue is that we frequently transform a bézier curve by an affine transform to be another bézier curve. However it is not possible with a perspective transform unless a more general NURBS is used as output.

Keavon commented 1 month ago

That's an interesting challenge. From a bit of research it looks like rational Bezier curves are needed to represent perspective transforms, which is a special case of a regular Bezier curve. And rational Beziers are special cases of NURBS (see here). So I wonder if we want to just support all of NURBS and have a hierarchy of data complexity/purity, then build Bezier-rs functionality to approximate NURBS as Bezier segments similar to some of the existing algorithms it already has involving approximations like reduce, offset, and arcs.

There's this video on projective geometry which gives a taste of homogeneous coordinates that I found helpful in starting to understand these concepts:

Further reading: