[cairo] Shouldn't Cairo use/offer degrees rather than radians?
dak at gnu.org
Tue Jun 27 12:35:50 UTC 2017
Simon Budig <simon at budig.de> writes:
> Hi David.
> David Kastrup (dak at gnu.org) wrote:
>> PostScript uses degrees. PDF uses degrees. Either have a numerically
>> stable presentation of right angles, the most important angles a
>> rectilinear coordinate system can work with.
> You're (in my book) wrong about PDF. PDF does not have a generic
> "rotate" operator, it always uses transformation matrices for this
> purpose, leaving it up to the application developer to pick his tools.
Correct for transformation matrices. But there is, for example,
ItalicAngle number (Required) The angle, expressed in degrees counterclockwise from
the vertical, of the dominant vertical strokes of the font.
EXAMPLE 4 The 9-o’clock position is 90 degrees, and the 3-
o’clock position is –90 degrees.
The value shall be negative for fonts that slope to the right, as almost
all italic fonts do.
> There is a /Rotate-entry in various object dictionaries, that accepts
> 0/90/180/270 as value, however, these are the *only* values accepted,
> they basically work as an enum, specifying the paper orientation. Using
> this as an argument for degrees in cairo is comparing apples and
Except that in the vast majority of cairo_rotate involving M_PI, the
values _are_ actually working as an enum specifying orientation. Which
is the actual problem: multiples of 90 are much more robust as an enum
than numerically unrepresentable values.
>> In contrast, Cairo uses radians. For every floating point format, PI/4
>> has different multiples, as opposed to 45. You don't get guarantees
>> (1.5*M_PI/2 - M_PI) == 0.5 * M_PI
>> which means that detecting almost any kind of right angle reliably is a
> I am not sure what you're trying to prove that "==" returns false when
> comparing -0.7854 to 1.5708...
Sigh. Remove the /2 here. 1.5*M_PI - M_PI == 0.5*M_PI may or may not
be true. 270.0 - 180.0 == 90.0 is true in all kinds of floating point
numbers available on computers these days.
> returns "equal!" for me. However, I see your point that this is not
> guaranteed, and that floating point math can give unexpected results.
> Yeah, whenever you're dealing with floating point numbers, the "=="
> operator is mostly useless, unless you know *very* exactly what you're
> doing. But exchanging M_PI with 180.0 doesn't change that.
It does change it because 180.0 has an exact representation with lots of
trailing zeros in any floating point format in active use. rational
multiples of pi do not have an exaxt representation in any floating
point format in active use.
> Obviously using integer degrees is too limiting for a library like
> cairo, so we're always dealing with floats. And then there is no point
> to offering degrees.
The point is that exact multiples of right angles are representable.
The point is that _every_ _single_ use of cairo_rotate with a
non-arbitrary angle in the Cairo codebase itself has to factor in M_PI
in some manner. The point is that
is unable to produce the transform matrix
[ 0 1 0
-1 0 0 ]
with any argument you give it.
>> So why not provide degrees (and use them internally) for Cairo?
> a) 6.12323e-17 is sufficiently zero for basically all usecases
So the argument is "being a little wrong is fine". Why settle for that?
> b) the math library trigonometric functions are based on radians
So what? The output formats (PostScript and SVG then) use degrees.
> c) degrees are easily made available by a tiny macro.
Which produces matrices that are "a little wrong" with "sufficiently
Radians suck in floating point when multiples of right angles are of
particular importance. Rotations (where everything is expressed in
multiples of 2pi radians) would work better (and wrap around
particularly nicely for fixed-point). But they aren't in wide-spread
use. So degrees are an obvious choice, in particular since it is the
choice of graphics formats.
More information about the cairo