Author Topic: Inverse Sine of an Angle  (Read 6596 times)

0 Members and 1 Guest are viewing this topic.

crowellsr

  • Guest
Inverse Sine of an Angle
« on: March 26, 2007, 05:05:17 PM »
Is there a way to calculate the angle that corresponds to a calculated sine value in LISP. I have yet to see a function for it and would rather not reinvent the wheel if there is already a way to do it.

Thanks

Steve

uncoolperson

  • Guest
Re: Inverse Sine of an Angle
« Reply #1 on: March 26, 2007, 05:12:37 PM »
you mean like arcsin?

Code: [Select]
asin(real)
« Last Edit: March 26, 2007, 05:36:42 PM by uncoolperson »

crowellsr

  • Guest
Re: Inverse Sine of an Angle
« Reply #2 on: March 26, 2007, 05:47:19 PM »
Yeah I think thats what it is called. It is the function that gives you the angle from a sine value.

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: Inverse Sine of an Angle
« Reply #3 on: March 26, 2007, 07:26:17 PM »
Trig functions posted to the Adesk newsgroups by Jon Fleming c.1997:
Code: [Select]
;;; the trigonometric functions not included with autolisp.
;;; jon fleming, may 20 1997.
;;; note that some of the functions (arcsecant and arccosecant)
;;; use other functions defined in this file.
;;; note that none of these functions check for valid
;;; arguments.  passing valid arguments is the responsibility
;;; of the calling program.
;;; 9.7e307 was determined experimentally to be the largest
;;; number that can be generated in autolisp (in r14).
;;;--------------------------------------------------------
;;; tangent accepts any angle in radians, and returns the
;;; tangent in the range -9.7e307+epsilon to 9.7e307 inclusive
(defun tan (z / cosz)
(if (zerop (setq cosz (cos z)))
9.7e307
(/ (sin z) cosz)
)
)

;;; secant accepts any angle in radians, and returns the
;;; secant in the ranges -9.7e307+epsilon to -1.0 inclusive
;;; and 1.0 to 9.7e307 inclusive
(defun sec (z / cosz)
(if (zerop (setq cosz (cos z)))
9.7e307
(/ 1.0 cosz)
) ;_ end if

)

;;; cosecant accepts any angle in radians, and returns the
;;; cosecant in the ranges -9.7e307+epsilon to -1.0 inclusive
;;; and 1.0 to 9.7e307 inclusive
(defun csc (z / sinz)
(if (zerop (setq sinz (sin z)))
9.7e307
(/ 1.0 sinz)
)
)

;;; arcsine (inverse sine) accepts an argument in the range
;;; -1.0 to 1.0 inclusive, and returns an angle in radians in
;;; the range (-pi/2) to (pi/2) inclusive.
(defun asin (z /)
(atan z (sqrt (- 1.0 (* z z))))
)

;;; arccosine (inverse cosine) accepts an argument in the
;;; range -1.0 to 1.0 inclusive, and returns an angle in
;;; radians in the range pi to 0 inclusive
(defun acos (z /)
(atan (sqrt (- 1.0 (* z z))) z)
)

;;; arcsecant (inverse secant) accepts an argument in
;;; one of two ranges: minus infinity to -1 inclusive or
;;; 1 to infinity inclusive, and returns an angle in
;;; radians in the range pi to 0 inclusive (except
;;; exactly pi/2 will never be returned on a computer
;;; with finite numerical precision)
(defun asec (z /)
(acos (/ 1.0 z))
)

;;; arccosecant (inverse cosecant) accepts an argument
;;; in one of two ranges: minus infinity to -1 inclusive or
;;; 1 to infinity inclusive, and returns an angle in
;;; radians in the range -pi/2 to pi/2 inclusive (except
;;; exactly 0.0 will never be returned on a computer
;;; with finite numerical precision)
(defun acsc (z /)
(asin (/ 1.0 z))
)

;;; arccotangent (inverse cotangent) accepts an argument
;;; in the range minus infinity to plus infinity
;;; inclusive and returns an angle in radians in the;;; range pi to 0 inclusive.
(defun acot (z /)
(- (/ pi 2.0) (atan z))
)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Inverse Sine of an Angle
« Reply #4 on: March 26, 2007, 08:52:14 PM »
There are a couple of values that will crash asin, so ...

Code: [Select]
(defun asin (num)
  (cond ((> (abs num) 1.0)
         (alert (strcat " Arc-sine error in (CTAU:asin ." "\n Spitting the dummy"))
         (exit)
        )
        ((zerop num) 0.0)
        ((= num 1.0) *pi/2*)
        ((= num -1.0) (- *pi/2*))
        (t (atan num (sqrt (- 1.0 (* num num)))))
  )
)

*pi/2* is a constant I use.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Inverse Sine of an Angle
« Reply #5 on: March 27, 2007, 02:30:41 AM »
Hi,

Here's my way.
Because, on 3D working acad can loose some precision (i.e. here), I use a "fuzz" for num values very closed but upper to 1 or lower to -1.

Code: [Select]
(defun ASIN (num)
  (cond
    ((equal num 1 1e-9) (/ pi 2))
    ((equal num -1 1e-9) (/ pi -2))
    ((< -1 num 1)
     (atan num (sqrt (- 1 (expt num 2))))
    )
  )
)

(defun ACOS (num)
  (cond
    ((equal num 1 1e-9) 0.0)
    ((equal num -1 1e-9) pi)
    ((< -1 num 1)
     (atan (sqrt (- 1 (expt num 2))) num)
    )
  )
)
Speaking English as a French Frog

uncoolperson

  • Guest
Re: Inverse Sine of an Angle
« Reply #6 on: March 27, 2007, 10:07:10 AM »
you mean like arcsin?

Code: [Select]
asin(real)

i was looking in general autocad help... that's for use with 'cal
sorry

HofCAD

  • Guest
Re: Inverse Sine of an Angle
« Reply #7 on: March 28, 2007, 02:26:22 PM »
Is there a way to calculate the angle that corresponds to a calculated sine value in LISP. I have yet to see a function for it and would rather not reinvent the wheel if there is already a way to do it.
Thanks Steve

Dear Steve,


Code: [Select]
(defun $geomcal()
(if (null cal)
(if (> (atoi (substr (getvar "ACADVER") 1 2)) 13)
(arxload "geomcal") (xload "geomcal")))
)

(defun asind_CAL(x);in degrees
($geomcal)
(setq x (c:cal "ASIN (x)"))
)

(defun asin_CAL(x) ;in radians
($geomcal)
(setq x (c:cal "D2R (ASIN (x))"))
)

HofCAD CSI

terrycadd

  • Guest
Re: Inverse Sine of an Angle
« Reply #8 on: April 02, 2007, 03:01:33 PM »
Here is a TRI function that I wrote last year for calculating the sides and angles of right and oblique triangles. The function is fairly easy to use.  It has six arguments: Side s1, Side s2, Side s3, Angle a, Angle b, and Angle c.  Angles are in radians.  It returns a 1 based list so you can use the ‘nth’ function to retrieve your results.  To display the text help information, just type (tri ? ? ? ? ? ?) on the command line as follows:
Note: This displays better using a courier or mono-spaced font.
Command: (tri ? ? ? ? ? ?)
tri error: (tri nil nil nil nil nil nil)
Only 2 or 3 valid arguments can be passed to tri function.
tri - Calculates the sides and angles of a triangle
Arguments: 6             |\                /\
  s1 = Side s1           |a\              /a \
  s2 = Side s2           |  \            /    \
  s3 = Side s3        s2 |   \ s3    s2 /      \ s3
  a = Angle a radians    |    \        /        \
  b = Angle b radians    |c___b\      /c________b\
  c = Angle c radians      s1              s1

Syntax example: (tri 3 ? ? 0.643501 ? ?);where ? = nil
Returns: (list nil 3.0 4.0 5.0 0.643501 0.927295 1.5708)
Note: For right triangles only supply the argument values for 2 sides,
or 1 side and 1 angle. Use ? or nil for the Angle c argument value.
For oblique triangles only supply argument values for 3 sides,
or 2 sides and 1 angle, or 1 side and 2 angles.
Code: [Select]
;-------------------------------------------------------------------------------
; tri - Calculates the sides and angles of a triangle
; Arguments: 6             |                 /\
;   s1 = Side s1           |\               /a \
;   s2 = Side s2           |a\             /    \
;   s3 = Side s3        s2 |  \ s3     s2 /      \ s3
;   a = Angle a radians    |   \         /        \
;   b = Angle b radians    |c__b\       /c________b\
;   c = Angle c radians      s1              s1
; Syntax example: (tri 3 ? ? 0.643501 ? ?);where ? = nil
; Returns: (list nil 3.0 4.0 5.0 0.643501 0.927295 1.5708);nth 1 based list
; Note: For right triangles only supply the argument values for 2 sides, or
; 1 side and 1 angle. Use ? or nil for the Angle c argument value. For oblique
; triangles only supply argument values for 3 sides, or 2 sides and 1 angle,
; or 1 side and 2 angles.
; Programming example usages:
; (setq Side2 (nth 2 (tri 3 ? ? 0.643501 ? ?))) = 4.0
; (setq AngleB (nth 5 (tri 3 ? ? 0.643501 ? ?))) = 0.927295
;-------------------------------------------------------------------------------
(defun tri (s1 s2 s3 a b c / acos asin e1 e2 e3 e4 e5 e6 j k negative passed tan)
  ;-----------------------------------------------------------------------------
  ; acos
  ; Arguments: 1
  ;   x = real number between 0 and 1. May be passed as the sum of dividing two
  ;       sides of a right triangle.
  ; Returns: acos of x, the radian degrees between sides of a right triangle
  ;-----------------------------------------------------------------------------
  (defun acos (x)
    (atan (/ (sqrt (- 1 (* x x))) x))
  );defun acos
  ;-----------------------------------------------------------------------------
  ; asin
  ; Arguments: 1
  ;   sine = real number between -1 to 1
  ; Returns: arcsin of sine
  ;-----------------------------------------------------------------------------
  (defun asin (sine / cosine)
    (setq cosine (sqrt (- 1.0 (expt sine 2))))
    (if (zerop cosine)
      (setq cosine 0.000000000000000000000000000001)
    );if
    (atan (/ sine cosine))
  );defun asin
  ;-----------------------------------------------------------------------------
  ; tan
  ; Arguments: 1
  ;   radians = Radian degrees
  ; Returns: Tangent of radian degrees
  ;-----------------------------------------------------------------------------
  (defun tan (radians)
    (/ (sin radians) (cos radians))
  );defun tan
  ;-----------------------------------------------------------------------------
  ; Start of main function
  ;-----------------------------------------------------------------------------
  (if (= (type s1)'INT)(setq s1 (float s1))) (if (<= s1 0)(setq s1 nil))
  (if (= (type s2)'INT)(setq s2 (float s2))) (if (<= s2 0)(setq s2 nil))
  (if (= (type s3)'INT)(setq s3 (float s3))) (if (<= s3 0)(setq s3 nil))
  (if (= (type a)'INT)(setq a (float a))) (if (<= a 0)(setq a nil))
  (if (= (type b)'INT)(setq b (float b))) (if (<= b 0)(setq b nil))
  (if (= (type c)'INT)(setq c (float c))) (if (<= c 0)(setq c nil))
  (setq e1 s1 e2 s2 e3 s3 e4 a e5 b e6 c passed t)
  (cond
    ((and (= (type s1)'REAL)(= (type s2)'REAL)(/= (type s3)'REAL)(/= (type a)'REAL)(/= (type b)'REAL)(/= (type c)'REAL))
      (setq a (atan (/ s1 s2)) c (* pi 0.5) b (- c a) s3 (/ s1 (sin a)))
    );case s1 s2
    ((and (/= (type s1)'REAL)(= (type s2)'REAL)(= (type s3)'REAL)(/= (type a)'REAL)(/= (type b)'REAL)(/= (type c)'REAL))
      (setq a (acos (/ s2 s3)) c (* pi 0.5) b (- c a) s1 (* s2 (tan a)))
    );case s2 s3
    ((and (= (type s1)'REAL)(/= (type s2)'REAL)(= (type s3)'REAL)(/= (type a)'REAL)(/= (type b)'REAL)(/= (type c)'REAL))
      (setq b (acos (/ s1 s3)) c (* pi 0.5) a (- c b) s2 (* s3 (sin b)))
    );case s1 s3
    ((and (= (type s1)'REAL)(/= (type s2)'REAL)(/= (type s3)'REAL)(= (type a)'REAL)(/= (type b)'REAL)(/= (type c)'REAL))
      (setq c (* pi 0.5) b (- c a) s2 (/ s1 (tan a)) s3 (/ s1 (sin a)))
    );case s1 a
    ((and (= (type s1)'REAL)(/= (type s2)'REAL)(/= (type s3)'REAL)(/= (type a)'REAL)(= (type b)'REAL)(/= (type c)'REAL))
      (setq c (* pi 0.5) a (- c b) s2 (* s1 (tan b)) s3 (/ s1 (cos b)))
    );case s1 b
    ((and (/= (type s1)'REAL)(= (type s2)'REAL)(/= (type s3)'REAL)(= (type a)'REAL)(/= (type b)'REAL)(/= (type c)'REAL))
      (setq c (* pi 0.5) b (- c a) s1 (* s2 (tan a)) s3 (/ s2 (cos a)))
    );case s2 a
    ((and (/= (type s1)'REAL)(= (type s2)'REAL)(/= (type s3)'REAL)(/= (type a)'REAL)(= (type b)'REAL)(/= (type c)'REAL))
      (setq c (* pi 0.5) a (- c b) s1 (/ s2 (tan b)) s3 (/ s2 (sin b)))
    );case s2 b
    ((and (/= (type s1)'REAL)(/= (type s2)'REAL)(= (type s3)'REAL)(= (type a)'REAL)(/= (type b)'REAL)(/= (type c)'REAL))
      (setq c (* pi 0.5) b (- c a) s1 (* s3 (sin a)) s2 (* s3 (cos a)))
    );case s3 a
    ((and (/= (type s1)'REAL)(/= (type s2)'REAL)(= (type s3)'REAL)(/= (type a)'REAL)(= (type b)'REAL)(/= (type c)'REAL))
      (setq c (* pi 0.5) a (- c b) s1 (* s3 (cos b)) s2 (* s3 (sin b)))
    );case s3 b
    ((and (= (type s1)'REAL)(= (type s2)'REAL)(= (type s3)'REAL)(/= (type a)'REAL)(/= (type b)'REAL)(/= (type c)'REAL))
      (setq j (/ (+ s1 s2 s3) 2.0) k (sqrt (/ (* (- j s1)(- j s2)(- j s3)) j)) a (* 2 (atan (/ k (- j s1)))) b (* 2 (atan (/ k (- j s2)))) c (- pi (+ a b)))
    );case s1 s2 s3
    ((and (= (type s1)'REAL)(/= (type s2)'REAL)(/= (type s3)'REAL)(= (type a)'REAL)(= (type b)'REAL)(/= (type c)'REAL))
      (setq c (- pi (+ a b)) s2 (/ (* s1 (sin b)) (sin a)) s3 (/ (* s1 (sin c)) (sin a)))
    );case s1 a b
    ((and (/= (type s1)'REAL)(= (type s2)'REAL)(/= (type s3)'REAL)(/= (type a)'REAL)(= (type b)'REAL)(= (type c)'REAL))
      (setq a (- pi (+ b c)) s1 (/ (* s2 (sin a)) (sin b)) s3 (/ (* s2 (sin c)) (sin b)))
    );case s2 b c
    ((and (/= (type s1)'REAL)(/= (type s2)'REAL)(= (type s3)'REAL)(= (type a)'REAL)(/= (type b)'REAL)(= (type c)'REAL))
      (setq b (- pi (+ a c)) s1 (/ (* s3 (sin a)) (sin c)) s2 (/ (* s3 (sin b)) (sin c)))
    );case s3 a c
    ((and (= (type s1)'REAL)(/= (type s2)'REAL)(/= (type s3)'REAL)(= (type a)'REAL)(/= (type b)'REAL)(= (type c)'REAL))
      (setq b (- pi (+ a c)) s2 (/ (* s1 (sin b)) (sin a)) s3 (/ (* s1 (sin c)) (sin a)))
    );case s1 a c
    ((and (/= (type s1)'REAL)(= (type s2)'REAL)(/= (type s3)'REAL)(= (type a)'REAL)(= (type b)'REAL)(/= (type c)'REAL))
      (setq c (- pi (+ a b)) s1 (/ (* s2 (sin a)) (sin b)) s3 (/ (* s2 (sin c)) (sin b)))
    );case s2 a b
    ((and (/= (type s1)'REAL)(/= (type s2)'REAL)(= (type s3)'REAL)(/= (type a)'REAL)(= (type b)'REAL)(= (type c)'REAL))
      (setq a (- pi (+ b c)) s1 (/ (* s3 (sin a)) (sin c)) s2 (/ (* s3 (sin b)) (sin c)))
    );case s3 b c
    ((and (= (type s1)'REAL)(/= (type s2)'REAL)(/= (type s3)'REAL)(/= (type a)'REAL)(= (type b)'REAL)(= (type c)'REAL))
      (setq a (- pi (+ b c)) s2 (/ (* s1 (sin b)) (sin a)) s3 (/ (* s1 (sin c)) (sin a)))
    );case s1 b c
    ((and (/= (type s1)'REAL)(= (type s2)'REAL)(/= (type s3)'REAL)(= (type a)'REAL)(/= (type b)'REAL)(= (type c)'REAL))
      (setq b (- pi (+ a c)) s1 (/ (* s2 (sin a)) (sin b)) s3 (/ (* s2 (sin c)) (sin b)))
    );case s2 a c
    ((and (/= (type s1)'REAL)(/= (type s2)'REAL)(= (type s3)'REAL)(= (type a)'REAL)(= (type b)'REAL)(/= (type c)'REAL))
      (setq c (- pi (+ a b)) s1 (/ (* s3 (sin a)) (sin c)) s2 (/ (* s3 (sin b)) (sin c)))
    );case s3 a b
    ((and (= (type s1)'REAL)(= (type s2)'REAL)(/= (type s3)'REAL)(/= (type a)'REAL)(/= (type b)'REAL)(= (type c)'REAL))
      (setq a (atan (/ (* s1 (sin c)) (- s2 (* s1 (cos c))))) b (- pi (+ a c)) s3 (/ (* s1 (sin c)) (sin a)))
    );case s1 s2 c
    ((and (/= (type s1)'REAL)(= (type s2)'REAL)(= (type s3)'REAL)(= (type a)'REAL)(/= (type b)'REAL)(/= (type c)'REAL))
      (setq b (atan (/ (* s2 (sin a)) (- s3 (* s2 (cos a))))) c (- pi (+ a b)) s1 (/ (* s2 (sin a)) (sin b)))
    );case s2 s3 a
    ((and (= (type s1)'REAL)(/= (type s2)'REAL)(= (type s3)'REAL)(/= (type a)'REAL)(= (type b)'REAL)(/= (type c)'REAL))
      (setq c (atan (/ (* s3 (sin b)) (- s1 (* s3 (cos b))))) a (- pi (+ b c)) s2 (/ (* s3 (sin b)) (sin c)))
    );case s1 s3 b
    ((and (= (type s1)'REAL)(= (type s2)'REAL)(/= (type s3)'REAL)(= (type a)'REAL)(/= (type b)'REAL)(/= (type c)'REAL))
      (setq b (asin (/ (* s2 (sin a)) s1)) c (- pi (+ a b)) s3 (/ (* s1 (sin c)) (sin a)))
    );case s1 s2 a
    ((and (/= (type s1)'REAL)(= (type s2)'REAL)(= (type s3)'REAL)(/= (type a)'REAL)(= (type b)'REAL)(/= (type c)'REAL))
      (setq c (asin (/ (* s3 (sin b)) s2)) a (- pi (+ b c)) s1 (/ (* s2 (sin a)) (sin b)))
    );case s2 s3 b
    ((and (= (type s1)'REAL)(/= (type s2)'REAL)(= (type s3)'REAL)(/= (type a)'REAL)(/= (type b)'REAL)(= (type c)'REAL))
      (setq a (asin (/ (* s1 (sin c)) s3)) b (- pi (+ a c)) s2 (/ (* s3 (sin b)) (sin c)))
    );case s1 s3 c
    ((and (= (type s1)'REAL)(= (type s2)'REAL)(/= (type s3)'REAL)(/= (type a)'REAL)(= (type b)'REAL)(/= (type c)'REAL))
      (setq a (asin (/ (* s1 (sin b)) s2)) c (- pi (+ a b)) s3 (/ (* s2 (sin c)) (sin b)))
    );case s1 s2 b
    ((and (/= (type s1)'REAL)(= (type s2)'REAL)(= (type s3)'REAL)(/= (type a)'REAL)(/= (type b)'REAL)(= (type c)'REAL))
      (setq b (asin (/ (* s2 (sin c)) s3)) a (- pi (+ b c)) s1 (/ (* s3 (sin a)) (sin c)))
    );case s2 s3 c
    ((and (= (type s1)'REAL)(/= (type s2)'REAL)(= (type s3)'REAL)(= (type a)'REAL)(/= (type b)'REAL)(/= (type c)'REAL))
      (setq c (asin (/ (* s3 (sin a)) s1)) b (- pi (+ a c)) s2 (/ (* s1 (sin b)) (sin a)))
    );case s1 s3 a
    (t (setq passed nil)
    );case errors
  );cond
  (foreach item (list s1 s2 s3 a b c)
    (if (= (type item)'REAL) (if (<= Item 0)(setq negative t)))
  );foreach
  (if (or (not passed) negative)
    (progn
      (textscr)(princ "\ntri error: (tri ")(princ e1)(princ " ")(princ e2)(princ " ")(princ e3)(princ " ")(princ e4)(princ " ")(princ e5)(princ " ")(princ e6)(princ ")")
      (if negative (progn (princ "\nResults: s1 = ")(princ s1)(princ ", s2 = ")(princ s2)(princ ", s3 = ")(princ s3)(princ "\n         a = ")(princ a)(princ ", b = ")(princ b)(princ ", c = ")(princ c)))
      (princ "\nOnly 2 or 3 valid arguments can be passed to tri function.\n")
      (princ "\ntri - Calculates the sides and angles of a triangle")
      (princ "\nArguments: 6             |\\                /\\ ");Text display depends on users font
      (princ "\n  s1 = Side s1           |a\\              /a \\ ")
      (princ "\n  s2 = Side s2           |  \\            /    \\ ")
      (princ "\n  s3 = Side s3        s2 |   \\ s3    s2 /      \\ s3")
      (princ "\n  a = Angle a radians    |    \\        /        \\ ")
      (princ "\n  b = Angle b radians    |c___b\\      /c________b\\ ")
      (princ "\n  c = Angle c radians      s1              s1")
      (princ "\nSyntax example: (tri 3 ? ? 0.643501 ? ?);where ? = nil")
      (princ "\nReturns: (list nil 3.0 4.0 5.0 0.643501 0.927295 1.5708)")
      (princ "\nNote: For right triangles only supply the argument values for 2 sides,")
      (princ "\nor 1 side and 1 angle. Use ? or nil for the Angle c argument value.")
      (princ "\nFor oblique triangles only supply argument values for 3 sides,")
      (princ "\nor 2 sides and 1 angle, or 1 side and 2 angles.")
      (exit)
    );progn
  );if
  (list nil s1 s2 s3 a b c);nth 1 based list
);defun tri
I think I've included everything.  If not let me know.