From cf11a6cd3300b5ed7e6cbe8c461adebc3bab1618 Mon Sep 17 00:00:00 2001 From: Thomas Morley Date: Tue, 20 Oct 2015 00:42:09 +0200 Subject: [PATCH 1/1] modify coord-rotate to get exact values for (sin PI) etc issue 4640 Done by switching to appropiate values for the angle and/or switching sin to cos and vice versa Also changing cyclic-base-value from using nested if to cond for better readability --- scm/lily-library.scm | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/scm/lily-library.scm b/scm/lily-library.scm index 0bfce9eb0c..574b85437e 100644 --- a/scm/lily-library.scm +++ b/scm/lily-library.scm @@ -707,13 +707,30 @@ right (@var{dir}=+1)." (define-public (coord-scale coordinate amount) (coord-operation * amount coordinate)) -(define-public (coord-rotate coordinate angle) - (let ((c (cos angle)) - (s (sin angle)) - (x (coord-x coordinate)) - (y (coord-y coordinate))) - (cons (- (* c x) (* s y)) - (+ (* s x) (* c y))))) +(define-public (coord-rotate coordinate angle-in-radians) + ;; getting around (sin PI) not being exactly zero by switching to cos at + ;; appropiate angles and/or taking the negative value (vice versa for cos) + (let* ((quadrant (inexact->exact (round (/ angle-in-radians (/ PI 2))))) + (moved-angle (- angle-in-radians (* quadrant (/ PI 2)))) + (s (sin moved-angle)) + (c (cos moved-angle)) + (x (coord-x coordinate)) + (y (coord-y coordinate))) + (case (modulo quadrant 4) + ((0) ;; -45 .. 45 + (cons (- (* c x) (* s y)) + (+ (* s x) (* c y)))) + ((1) ;; 45 .. 135 + (cons (- (* (- s) x) (* c y)) + (+ (* c x) (* (- s) y)))) + ((2) ;; 135 .. 225 + (cons (- (* (- c) x) (* (- s) y)) + (+ (* (- s) x) (* (- c) y)))) + ((3) ;; 225 .. 315 + (cons (- (* s x) (* (- c) y)) + (+ (* (- c) x) (* s y)))) + ;; for other angles (modulo quadrant 4) returns one of the above cases + ))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; trig @@ -728,11 +745,11 @@ right (@var{dir}=+1)." (define-public (cyclic-base-value value cycle) "Take @var{value} and modulo-maps it between 0 and base @var{cycle}." - (if (< value 0) - (cyclic-base-value (+ value cycle) cycle) - (if (>= value cycle) - (cyclic-base-value (- value cycle) cycle) - value))) + (cond ((< value 0) + (cyclic-base-value (+ value cycle) cycle)) + ((>= value cycle) + (cyclic-base-value (- value cycle) cycle)) + (else value))) (define-public (angle-0-2pi angle) "Take @var{angle} (in radians) and maps it between 0 and 2pi." -- 2.39.2