[cairo] Uniform Line Widths

Behdad Esfahbod behdad at behdad.org
Tue Apr 15 12:58:44 PDT 2008


On Mon, 2008-04-07 at 15:42 -0400, Bobby Salazar wrote:
> I am experiencing a problem with the code you attached to the below message. Specifically, it doesn't work with certain transformation matrices.
> 
> In the function get_singular_values(), if the translation matrix is:
> 
> 	xx	9.8000000000000
> 	yx	0.00000000000000
> 	xy	0.00000000000000
> 	yy	9.8000000000000
> 	x0	348.00000000000
> 	y0	0.00000000000000
> 
> Then the function computes invalid numbers for the major and minor singular values.
> 
> This is what it calculates:
> 
> a = 96.040000000000
> b = 96.040000000000
> k = 0.00000000000000
> a_b = 192.08000000000
> delta = -1.#IND000000000
> 
> And since delta comes out wrong, everything else that uses it does also.

Found a bug in delta computation.  Also simplified the computations a
bit.  You can find it in cairo/doc/tutorial/src/singular.c now.  Try
with git master.

behdad

> Do you know what the appropriate fix would be?
> 
> > -----Original Message-----
> > From: behdad at behdad.org
> > Sent: Fri, 22 Feb 2008 07:00:11 -0500
> > To: bobby8934 at inbox.com
> > Subject: Re: [cairo] Uniform Line Widths
> > 
> > On Fri, 2008-02-22 at 02:36 -0500, Bobby Salazar wrote:
> >> Ok, that is much simpler than I thought, and works good too.
> > 
> > Good.
> > 
> >> However, my code is written so that the pre-set line width is correct
> >> for the currently applied transformation matrix.
> > 
> > Well, that can't be the case.  The pen at the applied transformation is
> > an ellipse (which causes the non-uniform line width).  Which diameter of
> > the ellipse is the desired line width you want?  Most probably the
> > smallest.
> > 
> > Depending on your answer, the solution would be different.  The max and
> > min of the diameter/pen-width are twice the semi-major and semi-minor
> > axes of the ellipse, which are equal to the singular values of the
> > non-translation parts of the matrix.  See:
> > 
> >   http://en.wikipedia.org/wiki/Semi-major_axis
> >   http://www.ee.ic.ac.uk/hp/staff/www/matrix/decomp.html#SVD
> > 
> > Quoting there: "The non-zero singular values of A are the square roots
> > of the non-zero eigenvalues of A⁺ A." where A⁺ is A-transpose.
> > 
> > Lets see.  Let M be the cairo transformation matrix in question:
> > 
> >       ⌈xx xy⌉
> >   M = |yx yy|
> >       ⌊x0 y0⌋
> > 
> > The non-translation part is:
> > 
> >   A = ⌈xx xy⌉
> >       ⌊yx yy⌋
> > 
> >   A⁺ A = ⌈xx yx⌉⌈xx xy⌉ = ⌈xx²+yx²     xx*xy+yx*yy⌉
> >          ⌊xy yy⌋⌊yx yy⌋   ⌊xx*xy+yx*yy     xy²+yy²⌋
> > 
> > Name those:
> > 
> >   B = A⁺ A = ⌈a k⌉
> >              ⌊k b⌋
> > 
> > The eigenvalues of B satisfy:
> > 
> >   λ² - (a+b).λ + a.b - k² = 0
> > 
> > The eigenvalues are:
> >                __________________
> >       (a+b) ± √(a+b)² - 4(a.b-k²)
> >   λ = ---------------------------
> >                   2
> > 
> > And the Singular values are the root of λs.
> > 
> > That's all.  Not as easy and fast as you expected I assume.  See the
> > attached code and output.
> > 
> > 
> >> If I then set the transformation matrix to be the identity matrix, the
> >> line width is not correct. Is there an equally simple method of
> >> mapping a certain line width from any arbitrary transformation matrix
> >> into the same pixel sized width it would if the identity matrix were
> >> used? I hope that last sentenced makes sense...
> > 
> > You need to think what the intended pen size in your application is and
> > reorder your code to not have to go through this.
> > 
> > Cheers,
> > 
> > behdad
> > 
> > 
> > PS. Anyone should feel free to put this on cairographics.org/samples or
> > a separate page of its own or whereever that it will be useful!
> > 
> > 
> >> Thanks!
> >> 
> >>> -----Original Message-----
> >>> From: behdad at behdad.org
> >>> Sent: Wed, 20 Feb 2008 14:17:11 -0500
> >>> To: bobby8934 at inbox.com
> >>> Subject: Re: [cairo] Uniform Line Widths
> >>> 
> >>> On Wed, 2008-02-20 at 10:39 -0800, Bobby Salazar wrote:
> >>>> I currently have a function that accepts a cairo context (with a path
> >>>> already set) and strokes the path with a pre-set width and color. The
> >>>> context can have any arbitrary transformation already applied to it.
> >>>> So
> >>>> given this situation, how would I ensure that I get a uniform line
> >>>> width
> >>>> from the stroke even when they may have applied a deforming scale to
> >>>> the
> >>>> context? Any ideas would be appreciated!
> >>> 
> >>> Something like:
> >>> 
> >>>   cairo_save (cr);
> >>>   cairo_identity_matrix (cr);
> >>>   cairo_set_line_width (cr, width);
> >>>   cairo_stroke (cr);
> >>>   cairo_restore (cr);
> >>> 
> >>> 
> >>>> Thanks!
> >>> 
> >>> Have fun with cairo!
> >>> --
> >>> behdad
> >>> http://behdad.org/
> >>> 
> >>> "Those who would give up Essential Liberty to purchase a little
> >>>  Temporary Safety, deserve neither Liberty nor Safety."
> >>>         -- Benjamin Franklin, 1759
> >> 
> >> ____________________________________________________________
> >> FREE 3D MARINE AQUARIUM SCREENSAVER - Watch dolphins, sharks & orcas on
> >> your desktop!
> >> Check it out at http://www.inbox.com/marineaquarium
> >> _______________________________________________
> >> cairo mailing list
> >> cairo at cairographics.org
> >> http://lists.cairographics.org/mailman/listinfo/cairo
> > --
> > behdad
> > http://behdad.org/
> > 
> > "Those who would give up Essential Liberty to purchase a little
> >  Temporary Safety, deserve neither Liberty nor Safety."
> >         -- Benjamin Franklin, 1759
> _______________________________________________
> cairo mailing list
> cairo at cairographics.org
> http://lists.cairographics.org/mailman/listinfo/cairo
-- 
behdad
http://behdad.org/

"Those who would give up Essential Liberty to purchase a little
 Temporary Safety, deserve neither Liberty nor Safety."
        -- Benjamin Franklin, 1759



More information about the cairo mailing list