-
Notifications
You must be signed in to change notification settings - Fork 48
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
Add a transform() method to Path and segments #101
base: master
Are you sure you want to change the base?
Conversation
8920910
to
c119d0f
Compare
Skews don't work right on curves yet. |
This won't work on arcs. It's simply not enough to convert the arc start and end points. If you, for example apply a scale by -1 you must invert the sweep flag, a bit of a rotation would require that you actually change the rotation bit but only if the arc is sort of non-circular. I don't even think I got arcs that work correctly with skews. Since I opted for an internal parameterization of |
Good point about the sweep flag, I hadn't thought about that. I think arcs might have to be beziers when skewing, but I haven't looked at getting beziers right yet. |
I don't really see how you re-parameterize it afterwards. You could certainly replace the arcs with cubic or quads and those would skew perfectly fine. I think you actually need to solve it as a pretty large and complex equation. Given these values what does this matrix do to each of these values. My solution of just turning (https://www.w3.org/TR/SVG2/implnote.html#ArcParameterizationAlternatives) I think you might need to basically convert the formula with regards to t for the entire svg arc. Multiply it by your particular matrix and them simplify it back to arc values perhaps with values I believe it may actually be akin to: Which is a very useful set of equations to do 3x3 matrix perspective warping mapping 4 points to another 4 points. Which was done using lean. But, in theory you need to know how the matrix affects each value of the parameterization. |
Yeah, you are right, I drew out some skewed shapes yesterday and I thought the beziers looked bad, but now I have written tests that confirm them point by point, and they are actually fine, it's only the arcs that are the problem. I guess the nicest would be to somehow apply the matrix in a way that changes the ellipticity (is that a word) and rotates them to make a skew. But I'm not 100% sure that would work, and yeah, the easiest is probably just to convert the arcs to beziers and skew later. I'll think about that after some more coffee. |
Looks like it is doable, once you decode the arcane maths: https://math.stackexchange.com/questions/2068583/when-you-skew-an-ellipse-how-do-you-calculate-the-angle-of-rotation-and-the-new |
Yeah, I would prefer source code in Klingon to the answer in mathy-english. What's annoying is the person answering that question could probably write the five lines of code it would take. But, convincing them to help make a computer do a practical thing takes a distant 2nd fiddle to explaining the obviousness of the conjectures involved. I've gone pretty deep into learning some Here's an ellipse with a skew applied and a perspective applied to that (inkscape, skew, object to path, path effects, perspective). As you obviously guess there's no There should entirely be a set of equations that explains what happens to each of the arc parameters when you feed the arc into an affine matrix. Start: transformed.
|
There's no g and h in SVG, though, so I don't need to implement them, luckily. If the interface doesn't return a new PathSegment, but a list of new PathSegments, that's at least theoretically doable. But I doubt very many people are going to use this transform function at all. I basically just want to close the two last tickets. :-D I'm not sure if there is an order defined for the functions, when you implement a matrix, though. A shear and then rotate would be different from a rotate and then a shear... I'll have to read through the SVG spec to see if there's an order defined. |
8704615
to
c8e4a18
Compare
Okay, yes. If somebody calls shear/rotate for your arc, return some bezier curves for that. That actually sounds approximately great. The order is pre-cat in the list. So > from svgelements import *
> Matrix("rotate(5)") * Matrix("translate(20,20)") == Matrix("translate(20, 20) rotate(5)")
True
> m = Matrix("translate(20, 20) rotate(5)")
> m = Matrix()
> m.pre_translate(20,20)
> m.pre_rotate(Angle.degrees(5))
> m == "translate(20, 20) rotate(5)"
True
> Matrix() * "translate(20,20)" * "rotate(5)" == "translate(20,20) rotate(5)"
False Or at least that's what was needed to pass the test my Basically But you're probably good if you do matrix parsing tests. And ensure that the orders match. WC3: |
Well, suddenly while testing an x-skew and a y-skew created a rotation, but the wrong direction, so yeah, mine brain is definitely struggling. But it's going forward. |
ac7aa53
to
c34d5c9
Compare
c34d5c9
to
c02e252
Compare
No description provided.