[cairo] Shouldn't Cairo use/offer degrees rather than radians?
Bill Spitzak
spitzak at gmail.com
Tue Jul 11 17:50:15 UTC 2017
On Mon, Jul 10, 2017 at 10:10 PM, David Kastrup <dak at gnu.org> wrote:
> Gregor Mückl <GregorMueckl at gmx.de> writes:
>
>> Don't pin this only on the compiler, at least on x86. The old x87
>> compatible FPU instructions (obsolete in 64 bit mode) use internal
>> registers with significant longer mantissa than a double. The length
>> of the mantissa was not even fixed between implementations. However,
>> storing values from the FPU to memory results in truncation in this
>> case. This was "fixed" in SSE and newer intruction sets that are now
>> fixed at 32 bits for floats and 64 bits for doubles for internal
>> registers.
>>
>> I believe that this thread is starting to demonstrate that hunting for
>> numeric precision beyond a certain point using floating point
>> arithmetic is a fool's errand.
>
> The proposed code for setting angles in degrees is numerically precise
> at right angles for any floating point representation.
>
> Stuff like M_PI/2 or even M_PI will always result in hunts for numeric
> precision since pi does not have an exact floating point representation.
>
> This thread was about a proposed user interface that makes hunting for
> numeric precision a non-issue for the most prominent cases while
> representing angles in a common human-accessible format that other
> graphic systems and formats use as well.
>
> So the conclusion "let's not bother offering something better because we
> cannot conclusively figure out how bad the current situation is on
> different systems respectively" is not really what I was pitching for.
The problem is that it is not better, and providing the api will
mislead people into thinking it is better.
You wanted two rotates by 45 degrees to be perfect. However that is
not how Cairo is implemented and changing it would require
considerable effort for no real win. A rotate of 45 degrees is turned
into a matrix containing sqrt(2)/2 which is not stored accurately. The
exact same value is stored whether the rotation is sent as degrees or
radians.
Any implementation that blindly does sin(angle*(M_PI/180)) will
produce the exact same error for right angles whether they are given
in degrees or radians. So simply making the api be degrees with the
easiest implementation will not fix anything.
I would like to make a more limited request of Cairo:
1. Change cairo_matrix_init_rotate to detect multiples of M_PI_2 and
produce integers. From what I can see subtracting M_PI_2*n where n is
rint(angle/M_PI_2), and then doing sin/cos works pretty good. This
will prevent surprises in the resulting matrix. I tested some stuff in
gnuplot and any discontinuity in the plots is below 2e-16.
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.
More information about the cairo
mailing list