solve-triangle.lisp 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. ;;;; solve-triangle.lisp
  2. (defpackage #:solve-triangle
  3. (:use :cl)
  4. (:export #:solve-asa
  5. #:solve-ssa))
  6. (in-package #:solve-triangle)
  7. ;; SAA, ASA -- Law of Sines
  8. ;; SSA -- Law of Sines, (or 0 1 2) solutions
  9. ;; SAS -- Law of Cosines
  10. ;; SSS -- Law of Cosines
  11. (defun between-p (lower number upper)
  12. (and (>= number lower)
  13. (<= number upper)))
  14. (defun solve-asa (anglea sidea angleb)
  15. "Solve a ASA triangle using the method of sines. Angles assumed to be in degrees."
  16. (let* ((anglec (- 180 anglea angleb))
  17. (sideb (/ (* (sin angleb)
  18. sidea)
  19. (sin anglea)))
  20. (sidec (/ (* (sin anglec)
  21. sidea)
  22. (sin anglea))))
  23. (list :angle-a anglea
  24. :angle-b angleb
  25. :angle-c anglec
  26. :side-a sidea
  27. :side-b sideb
  28. :side-c sidec)))
  29. (defun solve-ssa (sidea sideb anglea)
  30. "Solve an SSA triangle using the method of sines. Angles are assumed to be in degrees."
  31. (let ((sinb (/ (* sideb (sin anglea))
  32. sidea)))
  33. (if (between-p -1 sinb 1)
  34. (let* ((angleb (asin sinb))
  35. (anglec (- 180 anglea angleb))
  36. (sidec (asin (/ (* (sin anglec) sidea)
  37. (sin anglea)))))
  38. (if (< (+ anglea angleb))
  39. (let* ((angleb-prime (- 180 angleb))
  40. (anglec-prime (- 180 anglea angleb-prime))
  41. (sidec-prime (/ (* (sin anglec-prime) sidea)
  42. (sin anglea))))
  43. (values (list :angle-a anglea
  44. :angle-b angleb
  45. :angle-c anglec
  46. :side-a sidea
  47. :side-b sideb
  48. :sidec sidec)
  49. (list :angle-a anglea
  50. :angle-b angleb-prime
  51. :angle-c anglec-prime
  52. :sidea sidea
  53. :sideb sideb
  54. :sidec sidec-prime)))
  55. (values (list :angle-a anglea
  56. :angle-b angleb
  57. :angle-c anglec
  58. :side-a sidea
  59. :side-b sideb
  60. :sidec sidec)
  61. nil)))
  62. (values nil nil))))