Re: Shouldn't Cairo use/offer degrees rather than radians?

Ray Gardener <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
Why not leave the Cairo API alone and implement a utility library analogous
to GLU for OpenGL and that way handy degree-based transform functions
can be put there.

Ray




On 7/11/2017 3:42 PM, Bill Spitzak wrote:
> Your matrix for 45 degrees has equal values in all 4 entries. When
> this matrix is mulitplied by itself you get a matrix made of
> 0.9999999999999998 and 0.0. (That value is actually
> 1.0-2.220446049250313e-16).
>
> If you use the normal sin and cos values (which are unequal to each
> other) you get 1.0 and 2.220446049250313e-16 which is the same
> magnitude of error.
>
> However squaring 0.9999999999999998 gets a number further away from
> 1.0, while squaring 2.220446049250313e-16 goes closer to zero. For
> many operations (such as further multiplies, getting the determinant,
> etc) this means the second matrix is more accurate.
>
>>> You wanted two rotates by 45 degrees to be perfect.
>> Uh, no?  Two rotates by 45 degrees illustrate a _compromise_.  The
>> degree of rotation will generally be a perfect 90 degrees because of all
>> rotation matrix elements having the same magnitude, the total magnitude
>> (determinant of the scaling matrix I think) will lightly be slightly
>> more wrong than the magnitude of the radian API (which likely also fails
>> to be 1 due to sin/cos of M_PI/4 in floating point also being
>> approximations).
> As I tried to show above the answer current Cairo gets for pi/4 is
> better than the one you get for 45 degrees. Your function could be
> improved by using sin and cos rather than trying to do sin(pi/2-a) in
> place of cos in order to make sin and cos equal for 45 degrees.
>
>> Did you even read the patch and its rationale?  Or are you making up
>> that straw man on the fly?  Multiples of 90 degrees are perfect.  There
>> are currently several fast paths in Cairo's code paths which actually
>> _check_ for that kind of perfection.
> I agree there are fast paths that are not allowing such errors in the
> matrix, and that changing cairo_rotate to detect angles near n*pi/2
> and produce 1.0 and 0.0 would probably be a much faster fix than
> trying to track down all the fast path mistakes. It would also remove
> suprises in the matrix for users.
>
>
>>> The exact same value is stored whether the rotation is sent as degrees
>>> or radians.
>> DID YOU LOOK AT THE PATCH?????  I cannot believe you did when you state
>> this.
> Yes your patch in effect finds the quadrant the angle is in. It
> substitutes sin(pi/2-x) for cos(x) in order to make a right angle have
> a cos of 0.0, however as stated above I believe this is a mistake as
> the determinant of the matrix is not 1.0 for other angles.
>
> My version instead finds the closest axis (or the quadrant if you
> rotate by 45 degrees). The angle passed to sin/cos is in the range
> -pi/4..pi/4. This allows the normal sin/cos functions to be used. Here
> it is (in python sorry):
>
> from math import *
> M_PI_2 = pi/2
>
> # this is needed to avoid producing negative zero:
> def neg(x):
>    return -x if x else 0.0
>
> def sincos(a):
>    axis = round(a / M_PI_2)
>    fromaxis = a - axis * M_PI_2
>    s = sin(fromaxis)
>    c = cos(fromaxis)
>    x = int(axis) & 3
>    if   (x==0): return(     s,     c)
>    elif (x==1): return(     c, neg(s))
>    elif (x==2): return(neg(s), neg(c))
>    else:        return(neg(c), s)
>
> If you think degrees would help then substitute 90 for M_PI_2 and put
> fromaxis*(M_PI_2/90) to the sin and cos function calls. Though
> intuitively it seems like 90*round(a/90) is somehow more accurate than
> M_PI_2*round(a/M_PI_2) I have not been able to find a value where this
> actually happens so I don't believe the degree version is necessary.
>
>>> 2. Add an api to rotate so the x axis passes through an x,y point (and
>>> possibly scales by hypot(x,y)). This would provide an "accurate"
>>> rotate for a whole lot of cases that actually come up in real
>>> graphics.
>> For multiples of 90 degrees, you can "trivially" just specify the
>> transform matrix, yet nobody does.  This is not how people think, and we
>> are talking about an API for people.
> I propose cairo_rotate_atan(x) and cairo_rotate_atan2(x,y) which are
> exactly the same as cairo_rotate(atan(x)) and cairo_rotate(atan2(x,y))
> except for greater accuracy. The hope is that it is obvious how to fix
> code that is using atan to get the angle. You are right that no matter
> what happens, lots of code is going to continue to use
> cairo_rotate(M_PI/2), so I think fixing that function is a good idea.


-- 
cairo mailing list
[email protected]
https://lists.cairographics.org/mailman/listinfo/cairo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.