[Pixman] [PATCH 01/15] demos/scale: Compute filter size using boundary of xformed ellipse, not rectangle
Bill Spitzak
spitzak at gmail.com
Thu Dec 17 13:02:26 PST 2015
Well that was a pain to figure out again (it is tricky to get p and x and y
cancelled out of the calculation) but does this make any sense:
Calculate bounding box of radius-1 circle in xy transformed to uv:
Transform x,y to u,v by this matrix calculation:
|u| |a c| |x|
|v| = |b d|*|y|
Horizontal component:
u = ax+cy (1)
x,y describes a radius-1 circle, p is angle to the point:
p = 0..2*pi
x = cos(p)
y = sin(p)
x^2+y^2 = 1
dx/dp = -sin(p) = -y
dy/dp = cos(p) = x
Figure out derivative of (1) relative to p:
du/dp = a(dx/dp) + c(dy/dp)
= -ay + cx
The min and max u are when du/dp is zero:
-ay + cx = 0
cx = ay
c = ay/x (2)
y = cx/a (3)
Substitute (2) into (1) and simplify:
u = ax + ay^2/x
= a(x^2+y^2)/x
= a/x (because x^2+y^2 = 1)
x = a/u (4)
Substitute (4) into (3) and simplify:
y = c(a/u)/a
y = c/u (5)
Square (4) and (5) and add:
x^2+y^2 = (a^2+c^2)/u^2
But x^2+y^2 is 1:
1 = (a^2+c^2)/u^2
u^2 = a^2+c^2
u = hypot(a,c)
Similarily the max/min of v is at:
v = hypot(b,d)
On Thu, Dec 17, 2015 at 1:52 AM, Oded Gabbay <oded.gabbay at gmail.com> wrote:
> On Sat, Dec 12, 2015 at 8:06 PM, <spitzak at gmail.com> wrote:
> > From: Bill Spitzak <spitzak at gmail.com>
> >
> > This is much more accurate and less blurry. In particular the filtering
> does
> > not change as the image is rotated.
> > ---
> > demos/scale.c | 43 ++-----------------------------------------
> > 1 file changed, 2 insertions(+), 41 deletions(-)
> >
> > diff --git a/demos/scale.c b/demos/scale.c
> > index d00307e..71c7791 100644
> > --- a/demos/scale.c
> > +++ b/demos/scale.c
> > @@ -55,50 +55,11 @@ get_widget (app_t *app, const char *name)
> > return widget;
> > }
> >
> > -static double
> > -min4 (double a, double b, double c, double d)
> > -{
> > - double m1, m2;
> > -
> > - m1 = MIN (a, b);
> > - m2 = MIN (c, d);
> > - return MIN (m1, m2);
> > -}
> > -
> > -static double
> > -max4 (double a, double b, double c, double d)
> > -{
> > - double m1, m2;
> > -
> > - m1 = MAX (a, b);
> > - m2 = MAX (c, d);
> > - return MAX (m1, m2);
> > -}
> > -
> > static void
> > compute_extents (pixman_f_transform_t *trans, double *sx, double *sy)
> > {
> > - double min_x, max_x, min_y, max_y;
> > - pixman_f_vector_t v[4] =
> > - {
> > - { { 1, 1, 1 } },
> > - { { -1, 1, 1 } },
> > - { { -1, -1, 1 } },
> > - { { 1, -1, 1 } },
> > - };
> > -
> > - pixman_f_transform_point (trans, &v[0]);
> > - pixman_f_transform_point (trans, &v[1]);
> > - pixman_f_transform_point (trans, &v[2]);
> > - pixman_f_transform_point (trans, &v[3]);
> > -
> > - min_x = min4 (v[0].v[0], v[1].v[0], v[2].v[0], v[3].v[0]);
> > - max_x = max4 (v[0].v[0], v[1].v[0], v[2].v[0], v[3].v[0]);
> > - min_y = min4 (v[0].v[1], v[1].v[1], v[2].v[1], v[3].v[1]);
> > - max_y = max4 (v[0].v[1], v[1].v[1], v[2].v[1], v[3].v[1]);
> > -
> > - *sx = (max_x - min_x) / 2.0;
> > - *sy = (max_y - min_y) / 2.0;
> > + *sx = hypot (trans->m[0][0], trans->m[0][1]) / trans->m[2][2];
> > + *sy = hypot (trans->m[1][0], trans->m[1][1]) / trans->m[2][2];
> > }
> >
> > typedef struct
> > --
> > 1.9.1
> >
> > _______________________________________________
> > Pixman mailing list
> > Pixman at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/pixman
>
> Could you please add some comment in the code about where this
> calculation comes from (reference to some mathematical
> equation/proof), and detail the mapping of the variables in the code
> to the arguments of the mathematical equation ?
>
> Otherwise, this patch is:
>
> Reviewed-by: Oded Gabbay <oded.gabbay at gmail.com>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/pixman/attachments/20151217/46799f1b/attachment.html>
More information about the Pixman
mailing list