+(define-public PI-OVER-TWO (/ PI 2))
+
+(define-public THREE-PI-OVER-TWO (* 3 PI-OVER-TWO))
+
+(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)))
+
+(define-public (angle-0-2pi angle)
+ "Take @var{angle} (in radians) and maps it between 0 and 2pi."
+ (cyclic-base-value angle TWO-PI))
+
+(define-public (angle-0-360 angle)
+ "Take @var{angle} (in degrees) and maps it between 0 and 360 degrees."
+ (cyclic-base-value angle 360.0))
+
+(define-public PI-OVER-180 (/ PI 180))
+
+(define-public (degrees->radians angle-degrees)
+ "Convert the given angle from degrees to radians."
+ (* angle-degrees PI-OVER-180))
+
+(define-public (ellipse-radius x-radius y-radius angle)
+ (/
+ (* x-radius y-radius)
+ (sqrt
+ (+ (* (expt y-radius 2)
+ (* (cos angle) (cos angle)))
+ (* (expt x-radius 2)
+ (* (sin angle) (sin angle)))))))
+
+(define-public (polar->rectangular radius angle-in-degrees)
+ "Return polar coordinates (@var{radius}, @var{angle-in-degrees})
+as rectangular coordinates @ode{(x-length . y-length)}."
+
+ (let ((complex (make-polar
+ radius
+ (degrees->radians angle-in-degrees))))
+ (cons
+ (real-part complex)
+ (imag-part complex))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; string
+
+(define-public (string-endswith s suffix)
+ (equal? suffix (substring s
+ (max 0 (- (string-length s) (string-length suffix)))
+ (string-length s))))
+
+(define-public (string-startswith s prefix)
+ (equal? prefix (substring s 0 (min (string-length s) (string-length prefix)))))