lilypond-user
[Top][All Lists]

## Re: How to get X/Y-extent of a bezier-curve?

 From: David Kastrup Subject: Re: How to get X/Y-extent of a bezier-curve? Date: Fri, 09 Oct 2015 14:44:32 +0200 User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux)

Thomas Morley <address@hidden> writes:

> 2015-10-09 8:20 GMT+02:00 David Kastrup <address@hidden>:
>>
>>> 2015-10-07 14:08 GMT+02:00 Thomas Morley <address@hidden>:
>>>
>>>> The code in my initial mail uses coord-rotate (not
>>>> ly:stencil-rotate-absolute as in Jans suggestion)
>>>>
>>>> Ofcourse it was heavily simplified, maybe best to put up a patch to
>>>> have the full code for more detailed discussion.
>>>
>>> I have to postpone uploading the patch, there are some glitches ...
>>>
>>> And one thing which has driven me crazy, before I found the culprit:
>>> coord-rotate' has a problem which can be demonstrated with:
>>>
>>> (display (coord-rotate '(10 . 0) (/ PI 2)))
>>>
>>> Expected:   (0 . 10)
>>> Actually:  (6.12323399573677e-16 . 10.0)
>>>
>>> What's the best method to get the zero?
>>
>> coord-translate is written awfully (almost any intermediate use of atan
>> is an indicator of unnecessary contortions) but that's not the problem
>> here.  The problem is that GUILE stores floating point number as double
>> numbers (64 bits), and the MPU does its calculations, including
>> trigonometry, using long double arithmetic (80 bits on x86).
>> Consequently, there is no representation of PI in GUILE that would lead
>> to the expected results.
>
> Ok, thanks for the explanation.
>
>> When angles are represented un GUILE, you are probably indeed best off
>> using degrees rather than radians since small multiples of 45 are
>> exactly representable at any number resolution available to GUILE.
>
> Well, coord-rotate uses sin and cos for the final result. They both
> expect their argument as radians. Converting them with
> degrees->radians' involves PI again.
> So far the obvious ...
>
> Consequently I tried to redefine coord-rotate without depending on PI
> or at least without trigonometric functions.
> Up to now without result.
> Actually, I have no clue how to.

Oh, that won't work.  But sin(0) and cos(0) are exact.  What one can do
is to divide the given number by PI/4, and truncate to get the octant in
question.

Then you do something like

cos (x), sin (x) for octants 0, 7
-sin (x-PI/2), -cos (x-PI/2) for octants 1, 2
-cos (x-PI), -sin (x-PI) for octants 3, 4
sin (x-3PI/2), cos (x-3PI/2) for octants 5, 6

and get the proper 0 and 1 for GUILE's ideas of PI, PI/2 and 3PI/2.  Or,
probably saner, for GUILE's ideas of 180, 90, and 270.  Namely work with
degrees even when dividing into octants and only convert to radians at
the very last moment.  When you do this stuff separately for every
octant, you get exact results where you really need them.

Probably the best you can do without reverting to C altogether.

>> The code used in ly:stencil-rotate-absolute looks like it might work
>> (though I'd write (a * (M_PI / 180.0)) rather than (a * M_PI /
>> 180.0)).
>
> If I understand this correctly (and I probably don't), I don't see how
> it would help.

stencil-rotate-absolute takes its angle in degrees and converts into
radians in a manner that seems more likely not to lose the necessary
precision.

--
David Kastrup