Re: [Pixman] [PATCH 01/15] demos/scale: Compute filter size using boundary of xformed ellipse, not rectangle

2015-12-20 Thread Oded Gabbay
On Thu, Dec 17, 2015 at 11:02 PM, Bill Spitzak  wrote:
> 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)
>
>
Nice.
So please just add that as a comment inside the code above your calls
to hypot for posterity.

Oded

> On Thu, Dec 17, 2015 at 1:52 AM, Oded Gabbay  wrote:
>>
>> On Sat, Dec 12, 2015 at 8:06 PM,   wrote:
>> > From: Bill Spitzak 
>> >
>> > 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, [0]);
>> > -pixman_f_transform_point (trans, [1]);
>> > -pixman_f_transform_point (trans, [2]);
>> > -pixman_f_transform_point (trans, [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@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 
>
>
___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


Re: [Pixman] [PATCH 01/15] demos/scale: Compute filter size using boundary of xformed ellipse, not rectangle

2015-12-17 Thread Oded Gabbay
On Sat, Dec 12, 2015 at 8:06 PM,   wrote:
> From: Bill Spitzak 
>
> 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, [0]);
> -pixman_f_transform_point (trans, [1]);
> -pixman_f_transform_point (trans, [2]);
> -pixman_f_transform_point (trans, [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@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 
___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


Re: [Pixman] [PATCH 01/15] demos/scale: Compute filter size using boundary of xformed ellipse, not rectangle

2015-12-17 Thread Bill Spitzak
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  wrote:

> On Sat, Dec 12, 2015 at 8:06 PM,   wrote:
> > From: Bill Spitzak 
> >
> > 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, [0]);
> > -pixman_f_transform_point (trans, [1]);
> > -pixman_f_transform_point (trans, [2]);
> > -pixman_f_transform_point (trans, [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@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 
>
___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman