浏览代码

Finished writing ssa solver

Samuel W. Flint 11 年之前
父节点
当前提交
d53af9b8a7
共有 1 个文件被更改,包括 36 次插入17 次删除
  1. 36 17
      solve-triangle.lisp

+ 36 - 17
solve-triangle.lisp

@@ -11,6 +11,10 @@
 ;; SAS -- Law of Cosines
 ;; SAS -- Law of Cosines
 ;; SSS -- Law of Cosines
 ;; SSS -- Law of Cosines
 
 
+(defun between-p (lower number upper)
+  (and (>= number lower)
+     (<= number upper)))
+
 (defun solve-asa (anglea sidea angleb)
 (defun solve-asa (anglea sidea angleb)
   "Solve a ASA triangle using the method of sines.  Angles assumed to be in degrees."
   "Solve a ASA triangle using the method of sines.  Angles assumed to be in degrees."
   (let* ((anglec (- 180 anglea angleb))
   (let* ((anglec (- 180 anglea angleb))
@@ -29,20 +33,35 @@
 
 
 (defun solve-ssa (sidea sideb anglea)
 (defun solve-ssa (sidea sideb anglea)
   "Solve an SSA triangle using the method of sines.  Angles are assumed to be in degrees."
   "Solve an SSA triangle using the method of sines.  Angles are assumed to be in degrees."
-  (let ((angleb (asin (/ (* sideb (sin anglea))
-                         sidea))))
-    (cond
-      ((< 1 angleb) nil)
-      (())))
-  (let* ((angleb (asin (/ (* sideb (sin anglea))
-                          sidea)))
-         (anglec (- 180 anglea angleb))
-         (sidec (/ (* (sin anglec)
-                      sidea)
-                   (sin anglea))))
-    (list :angle-a anglea
-          :angle-b angleb
-          :angle-c anglec
-          :side-a sidea
-          :side-b sideb
-          :side-c sidec)))
+  (let ((sinb (/ (* sideb (sin anglea))
+                 sidea)))
+    (if (between-p -1 sinb 1)
+        (let* ((angleb (asin sinb))
+               (anglec (- 180 anglea angleb))
+               (sidec (asin (/ (* (sin anglec) sidea)
+                               (sin anglea)))))
+          (if (< (+ anglea angleb))
+              (let* ((angleb-prime (- 180 angleb))
+                     (anglec-prime (- 180 anglea angleb-prime))
+                     (sidec-prime (/ (* (sin anglec-prime) sidea)
+                                     (sin anglea))))
+                (values (list :angle-a anglea
+                            :angle-b angleb
+                            :angle-c anglec
+                            :side-a sidea
+                            :side-b sideb
+                            :sidec sidec)
+                        (list :angle-a anglea
+                              :angle-b angleb-prime
+                              :angle-c anglec-prime
+                              :sidea sidea
+                              :sideb sideb
+                              :sidec sidec-prime)))
+              (values (list :angle-a anglea
+                            :angle-b angleb
+                            :angle-c anglec
+                            :side-a sidea
+                            :side-b sideb
+                            :sidec sidec)
+                      nil)))
+        (values nil nil))))