>From ec018be621989234e3c570213084fe8705786e4c Mon Sep 17 00:00:00 2001
From: AwesomeAdam54321 <adam.f...@disroot.org>
Date: Sun, 16 Feb 2025 12:47:18 +0800
Subject: [PATCH] src: (math trigonometry): Add it.

* src/math/trigonometry.scm: New file.
* doc/guile-library.scm: Document it in the manual.
* unit-tests/math.trigonometry.scm: New unit test.
* src/Makefile.am: Register module.
* unit-tests/Makefile.am: Register unit test.
---
 doc/guile-library.scm            |  2 ++
 src/Makefile.am                  |  1 +
 src/math/trigonometry.scm        | 61 ++++++++++++++++++++++++++++++++
 unit-tests/Makefile.am           |  1 +
 unit-tests/math.trigonometry.scm | 44 +++++++++++++++++++++++
 5 files changed, 109 insertions(+)
 create mode 100644 src/math/trigonometry.scm
 create mode 100644 unit-tests/math.trigonometry.scm

diff --git a/doc/guile-library.scm b/doc/guile-library.scm
index 496c283..d9593b7 100644
--- a/doc/guile-library.scm
+++ b/doc/guile-library.scm
@@ -102,6 +102,8 @@ License\".")
      "A golden-section minimum finder")
     ((math primes)
      "Functions related to prime numbers and factorization")
+    ((math trigonometry)
+     "Functions related to motion trigonometry")
     ((os process)
      "Spawning processes and capturing their output")
     ((scheme documentation)
diff --git a/src/Makefile.am b/src/Makefile.am
index 889a575..507bbab 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -86,6 +86,7 @@ SOURCES = \
        logging/rotating-log.scm        \
        math/minima.scm                 \
        math/primes.scm                 \
+       math/trigonometry.scm           \
        match-bind.scm                  \
        md5.scm                         \
        os/process.scm                  \
diff --git a/src/math/trigonometry.scm b/src/math/trigonometry.scm
new file mode 100644
index 0000000..0afc047
--- /dev/null
+++ b/src/math/trigonometry.scm
@@ -0,0 +1,61 @@
+;; (math trigonometry) -- More exact trigonometry for motion
+;; Copyright (C) 2025  Adam Faiz <adam.f...@disroot.org>
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+;; @cindex normalise angle
+;; @cindex sine
+;; @cindex cosine
+;; @cindex angle, normalised
+;; @cindex angle, sine of
+;; @cindex angle, cosine of
+;; This module defines functions for computing the sine and cosine of an angle,
+;; as more robust versions of the built-in sin and cos functions in Guile.
+;; They return exact values for angles representing up, down, left and right,
+;; regardless of whether they're negative or how many rotations occurred.
+;;
+;;; Code:
+
+(define-module (math trigonometry)
+  #:use-module (scheme documentation)
+  #:export (normalise-angle
+            sine
+            cosine))
+
+(define (normalise-angle angle)
+  "Return a normalised angle where 0 <= angle < 360."
+  (define angle-from-north (remainder angle 360))
+  (+ angle-from-north
+     (if (< angle-from-north 0) 360 0)))
+
+(define (sine angle)
+  "Calculate the sine of an angle,
+with full precision for 90 degree increments."
+  (define normalised-angle (normalise-angle angle))
+  (cond ((or (= normalised-angle 0) (= normalised-angle 180)) 0)
+       ((= normalised-angle 90) 1)
+       ((= normalised-angle 270) -1)
+       (else (sin normalised-angle))))
+
+(define (cosine angle)
+  "Calculate the cosine of an angle,
+with full precision for 90 degree increments."
+  (define normalised-angle (normalise-angle angle))
+  (cond ((= normalised-angle 0) 1)
+       ((or (= normalised-angle 90) (= normalised-angle 270)) 0)
+       ((= normalised-angle 180) -1)
+       (else (cos normalised-angle))))
diff --git a/unit-tests/Makefile.am b/unit-tests/Makefile.am
index 00530ca..0a7ab37 100644
--- a/unit-tests/Makefile.am
+++ b/unit-tests/Makefile.am
@@ -58,6 +58,7 @@ TESTS= \
        match-bind.scm                  \
        math.minima.scm                 \
        math.primes.scm                 \
+       math.trigonometry.scm           \
        md5.scm                         \
        os.process.scm                  \
        search.basic.scm                \
diff --git a/unit-tests/math.trigonometry.scm b/unit-tests/math.trigonometry.scm
new file mode 100644
index 0000000..8c2a21e
--- /dev/null
+++ b/unit-tests/math.trigonometry.scm
@@ -0,0 +1,44 @@
+;;; ----------------------------------------------------------------------
+;;;    unit test
+;;;    Copyright (C) 2025 Adam Faiz <adam.f...@disroot.org>
+;;;
+;;;    This program is free software; you can redistribute it and/or modify
+;;;    it under the terms of the GNU General Public License as published by
+;;;    the Free Software Foundation; either version 3 of the License, or
+;;;    (at your option) any later version.
+;;;
+;;;    This program is distributed in the hope that it will be useful,
+;;;    but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;;    GNU General Public License for more details.
+;;;
+;;;    You should have received a copy of the GNU General Public License
+;;;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+;;; ----------------------------------------------------------------------
+
+(use-modules (math trigonometry)
+             (unit-test)
+             (oop goops))
+
+;; **********************************************************************
+;; Test of trigonometry
+;; **********************************************************************
+(define-class <test-trigonometry> (<test-case>)
+  (angles #:accessor test-angles))
+
+(define-method (set-up-test (self <test-trigonometry>))
+  (set! (test-angles self)
+        (list -720 -360 -270 -180 -90 -0
+              0    90    180  270 360 720)))
+
+(define-method (test-sine (self <test-trigonometry>))
+  (assert-equal (map sine (test-angles self))
+                (list 0 0 1 0 -1 0
+                      0 1 0 -1 0 0)))
+
+(define-method (test-cosine (self <test-trigonometry>))
+  (assert-equal (map cosine (test-angles self))
+                (list 1 1 0 -1 0 1
+                      1 0 -1 0 1 1)))
+
+(exit-with-summary (run-all-defined-test-cases))
-- 
2.46.0

Reply via email to