<div dir="ltr">I had some nice images that made the message too big, but actually arrived at some conclusions that don't use the images anyway. Basically my thoughts on this:<div><br></div><div>1. Although only a 3x3 matrix is needed to specify an perspective transform, if you want to use 3D rotations you need to use 4x4 matrix. This is because the result of a rotation depends on the position of the camera from the rotation origin and also the projection (ie fov) being used, and describing that requires more than 9 numbers. I feel supporting 4x4 matrix is not a good idea and thus supporting 3D rotations is not a good idea.</div><div><br></div><div>2. It looks like perspective could be supported by premultiplying by the matrix [[1 0 0] [0 1 0] [px py 1]] (in row-major order such that cairo_matrix_t is [[xx xy x0] [yx yy y0] [0 0 1]]. px is 1/x where x is the location of the vanishing point on the x axis, and py is 1/y for the y axis. I think Cairo needs to track the w and not normalize after each matrix multiply.</div><div><br></div><div>3. It may be useless to specify z in 3D transforms. At first I thought it was completely useless, but it does appear that multiplying the matrix by [x y z] produces movement that looks perpendicular to the xy plane where z=1 is the plane, while z=0 is the distance the camera is from the plane.</div><div><br></div><div>4. Perspective produces all kinds of questions about font and line width. IMHO it should *not* be applied to these, as the result is the same as what could be achieved by drawing a surface and the projecting that. Also it would break every stroke and font optimization.</div><div><br></div><div>5. I then concluded that a far more useful api is that perspective *only* changes the mapping of source images and has no effect on anything else. This limits it to what I think is the only useful part of 3D transforms. A proposed method that would be useful to a lot of software is to allow four (I incorrectly said 3) xy->uv pairs to be specified. These say that the position uv in the source lands at xy in the CTM. This would allow a client to do it's own 3d transforms and then correctly texture-map a quad by setting the uv of the corners. You could also do three xy->uvw mappings which would allow a client to texture-map a triangle.</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 19, 2018 at 3:36 PM, Bryce Harrington <span dir="ltr"><<a href="mailto:bryce@osg.samsung.com" target="_blank">bryce@osg.samsung.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Wed, Jan 10, 2018 at 02:13:39PM -0500, <a href="mailto:cecashon@aol.com">cecashon@aol.com</a> wrote:<br>
><br>
><br>
> Hi Bryce,<br>
><br>
> A 3x3 matrix should might work for quaternion rotations. In the sample<br>
> code this is reduced to a 2x2 matrix, or four variables for each<br>
> circle rotation, by using initial reference points but that wouldn't<br>
> work in general to preserve rotations. There would be a need to keep<br>
> the z component of a plane to make the rotations additive. If you<br>
> assumed z=0 then a first rotation would work but not a second or it<br>
> wouldn't work as expected.<br>
><br>
<br>
The code I've been hacking on adds to Cairo a 3x3 matrix with the 9th<br>
element fixed to 1 (so effectively is an 8-element matrix).  If that<br>
last element is needed, it shouldn't be too hard to add in subsequently;<br>
I've hidden the matrix definition internally so it'd be no API break to<br>
change, just making sure all the math accounts for the transformation.<br>
<br>
> This probably is something difficult to add to Cairo. There are a lot<br>
> of places that the cairo_matrix_t touches in the code. Also I think<br>
> there would be a need for a new matrix for quaternion rotations and if<br>
> that is done then you run into further difficulties such as the order<br>
> of matrix multiplication. A lot of speculation at this point.<br>
<br>
Yes, it is proving to be rather difficult.  Actually, just expanding the<br>
cairo_matrix_t definition to include projection wasn't too bad, but<br>
keeping the cairo_matrix_t API intact and adding projection as a new<br>
matrix type is rather invasive - everywhere that uses cairo_matrix_t<br>
needs updated to handle a cairo_matrix3_t.<br>
<br>
But, I'm working my way through it, and I think once that's in place<br>
then I think the quaternion rotation is doable.  Since internally Cairo<br>
assumes a 2D surface (Z=0), perhaps some flattening operation would<br>
allow using 9-elements externally and avoid a lot of logical mess by<br>
using 8 internally.<br>
<br>
> I got going on this to figure out 3d rotations using Cairo's api. I<br>
> could get some special case rotations in 3d but not something that<br>
> would work for a gyro. Working on putting together a little gyro<br>
> widget with Cairo and GTK.<br>
><br>
> I am not familiar with the internals of Cairo. I have looked around a<br>
> little but I don't have a test setup with the current version. Do you<br>
> have any suggestions for putting together a test setup? I would be<br>
> interested in getting a test build set up that I could experiment<br>
> with. Also to take a look at what you have going with projections.<br>
<br>
Depends on what operating system you're on.<br>
<br>
If you're on Linux it's just `apt-get build-dep libcairo2-dev` or the<br>
equivalent for your distro to install the build dependencies, checkout<br>
the code from git, and build it.  See INSTALL and README.<br>
<br>
There's more tips on the download page and elsewhere, although can't<br>
vouch for how current the directions are:<br>
<br>
    <a href="https://cairographics.org/download/" rel="noreferrer" target="_blank">https://cairographics.org/<wbr>download/</a><br>
    <a href="https://cairographics.org/end_to_end_build_for_win32/" rel="noreferrer" target="_blank">https://cairographics.org/end_<wbr>to_end_build_for_win32/</a><br>
<br>
For experimenting with the matrix code, the good thing is that even just<br>
the image backend will be suitable, so don't have to worry about driver<br>
issues at least.  :-)<br>
<div class="HOEnZb"><div class="h5"><br>
Bryce<br>
--<br>
cairo mailing list<br>
<a href="mailto:cairo@cairographics.org">cairo@cairographics.org</a><br>
<a href="https://lists.cairographics.org/mailman/listinfo/cairo" rel="noreferrer" target="_blank">https://lists.cairographics.<wbr>org/mailman/listinfo/cairo</a></div></div></blockquote></div><br></div>