Matrix Inconsistency?
Lawrence D'Oliveiro <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Organization | Geek Central |
| Message-ID | <[email protected]> |
The docs for cairo_matrix_multiply(&result, &a, &b)
<https://www.cairographics.org/manual/cairo-cairo-matrix-t.html#cairo-matrix-multiply>
say “The effect of the resulting transformation is to first apply the
transformation in a to the coordinates and then apply the
transformation in b to the coordinates”, while the docs for
cairo_transform
<https://www.cairographics.org/manual/cairo-Transformations.html#cairo-transform>
say “The new transformation of user space takes place after any
existing transformation”.
It seems to me, then that the sequence
cairo_matrix_multiply(&resultmat, &mat_rotate, &mat_translate);
should put the same thing into resultmat as the sequence
cairo_identity_matrix(cr);
cairo_transform(cr, &mat_rotate);
cairo_transform(cr, &mat_translate);
cairo_get_matrix(cr, &resultmat);
but it does not. Given the following definitions for mat_rotate and
mat_translate:
cairo_matrix_init_rotate(&mat_rotate, M_PI / 4.0);
cairo_matrix_init_translate(&mat_translate, 1.0, 1.0);
I get the following output from my test program:
* matrix:
rotate × translate = [[0.707, -0.707, 1] [0.707, 0.707, 1] [0, 0, 1]]
translate × rotate = [[0.707, -0.707, 1.11e-16] [0.707, 0.707, 1.41] [0, 0, 1]]
* context:
rotate × translate = [[0.707, -0.707, 1.11e-16] [0.707, 0.707, 1.41] [0, 0, 1]]
translate × rotate = [[0.707, -0.707, 1] [0.707, 0.707, 1] [0, 0, 1]]
The output for the cairo_matrix calls looks the right way round,
that for the cairo_transform calls does not.
See the attached source for the full program.
--
cairo mailing list
[email protected]
https://lists.cairographics.org/mailman/listinfo/cairo
matrix_order.c
(text/x-c++src, 2.7 KB)
/*
Comparing <https://www.cairographics.org/manual/cairo-Transformations.html>
with <https://www.cairographics.org/manual/cairo-cairo-matrix-t.html>, is
the ordering of matrix operations consistent?
*/
#define _XOPEN_SOURCE 500 /* for M_PI, which is not part of standard C */
#include <math.h>
#include <stdio.h>
#include <cairo/cairo.h>
static void print_matrix
(
const cairo_matrix_t * mat,
FILE * out
)
{
#define ELT_FMT "%.3g"
fprintf
(
out,
"[[" ELT_FMT ", " ELT_FMT ", " ELT_FMT "]"
" [" ELT_FMT ", " ELT_FMT ", " ELT_FMT "]"
" [0, 0, 1]]",
mat->xx, mat->xy, mat->x0,
mat->yx, mat->yy, mat->y0
);
#undef ELT_FMT
} /*print_matrix*/
int main
(
int argc,
char ** argv
)
{
const int img_size = 10; /* dummy */
cairo_surface_t * const pix = cairo_image_surface_create
(
/*format =*/ CAIRO_FORMAT_RGB24,
/*width =*/ img_size,
/*height =*/ img_size
);
cairo_t * const cr = cairo_create(pix);
cairo_matrix_t mat_rotate, mat_translate, resultmat;
cairo_matrix_init_rotate(&mat_rotate, M_PI / 4.0);
cairo_matrix_init_translate(&mat_translate, 1.0, 1.0);
cairo_matrix_multiply(&resultmat, &mat_rotate, &mat_translate);
/*
According to the docs
<https://www.cairographics.org/manual/cairo-cairo-matrix-t.html#cairo-matrix-multiply>,
“The effect of [cairo_matrix_multiply(&result, &a, &b)] is to
first apply the transformation in a to the coordinates and then
apply the transformation in b to the coordinates.”
*/
fputs("* matrix:\nrotate × translate = ", stdout);
print_matrix(&resultmat, stdout);
fputs("\n", stdout);
cairo_matrix_multiply(&resultmat, &mat_translate, &mat_rotate);
fputs("translate × rotate = ", stdout);
print_matrix(&resultmat, stdout);
fputs("\n", stdout);
cairo_identity_matrix(cr);
cairo_transform(cr, &mat_rotate);
cairo_transform(cr, &mat_translate);
/*
According to the docs
<https://www.cairographics.org/manual/cairo-Transformations.html#cairo-transform>,
“The new transformation of user space takes place after any
existing transformation.”
*/
cairo_get_matrix(cr, &resultmat);
fputs("* context:\nrotate × translate = ", stdout);
print_matrix(&resultmat, stdout);
fputs("\n", stdout);
cairo_identity_matrix(cr);
cairo_transform(cr, &mat_translate);
cairo_transform(cr, &mat_rotate);
cairo_get_matrix(cr, &resultmat);
fputs("translate × rotate = ", stdout);
print_matrix(&resultmat, stdout);
fputs("\n", stdout);
return
0;
} /*main*/