Author Topic: Inaccurate result when calculating angle  (Read 2828 times)

0 Members and 1 Guest are viewing this topic.

Augusto

  • Newt
  • Posts: 75
Inaccurate result when calculating angle
« on: January 29, 2019, 07:00:28 AM »
Hello guys!
When calculating the angle I am getting undesired result and I am not understanding where the error is.  :embarrassed:
Any suggestion?

Code: [Select]
(defun c:test (/ p1 p2 pt1 pt2)
  (defun DTR (a)
    (* PI (/ a 180.0))
  ) ;_ >defun
  (setq p1 (getpoint "p1")) ;'(0.0 0.0 0.0)
  (setq p2 (getpoint "p2")) ;'(0.0 1.0 0.0)
  (setq pt1 (polar p1 (DTR (angle p1 p2)) 1.0)) ;'(0.999624 0.0274121 0.0)
  (setq pt2 (polar p2 (DTR (angle p1 p2)) 1.0)) ;'(0.999624 1.02741 0.0)
  (command "line" pt1 pt2 "")
) ;_ >defun

I'm embarrassed, because this is a very simple matter, but it really is the first time I see this happen.
Thank you.

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: Inaccurate result when calculating angle
« Reply #1 on: January 29, 2019, 07:06:29 AM »
You shouldn't use (DTR) function inside (polar p ang dist)... ang value for (polar) should be in radians and (angle p1 p2) returns just that - angle in radians...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Augusto

  • Newt
  • Posts: 75
Re: Inaccurate result when calculating angle
« Reply #2 on: January 29, 2019, 07:18:22 AM »
You shouldn't use (DTR) function inside (polar p ang dist)... ang value for (polar) should be in radians and (angle p1 p2) returns just that - angle in radians...

Reviewing autolisp help I could actually see that the angle function return is in radians, but when I execute the function I'm getting an incorrect number in the same way.

Code: [Select]
(defun c:test (/ p1 p2 pt1 pt2)
  (setq p1 (getpoint "p1")) ;'(0.0 0.0 0.0)
  (setq p2 (getpoint "p2")) ;'(0.0 1.0 0.0)
  (setq pt1 (polar p1 (angle p1 p2) 1)) ;'(6.12323e-017 1.0 0.0)
  (setq pt2 (polar p2 (angle p1 p2) 1)) ;'(6.12323e-017 2.0 0.0)
  (command "line" pt1 pt2 "")
) ;_ >defun


I really was confused.  :nerdyembarassed:

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Inaccurate result when calculating angle
« Reply #3 on: January 29, 2019, 08:07:13 AM »
The number 6.12323e-017 = 0.0000000000000000612323 is a result of the rounding that occurs at the limit of precision of the double-precision floating-point format, caused by the inability to represent all decimal numbers with infinite precision in binary.

Such issues will always arise and will arise in a numbering system of any base (only, affecting different numbers for each base) because it would require an infinite amount of memory to represent all numerical values accurately. This impacts any programming language and is not limited to AutoLISP - one must simply acknowledge that the issue can arise and take care accordingly to include a level of tolerance when comparing doubles (reals in AutoLISP).

Augusto

  • Newt
  • Posts: 75
Re: Inaccurate result when calculating angle
« Reply #4 on: January 29, 2019, 08:36:57 AM »
Many thanks for the explanation Lee and ribarm.
Excuse me for taking your time with simple things. In this case it was malpractice on my part.
My wish was to design the line simulating an offset and I was able to solve it that way.
Code: [Select]
;(polar p1 (-(angle p1 p2)(* 0.5 pi)) 1.0)

(defun c:test (/ p1 p2 pt1 pt2)
  (setq p1 '(0.0 0.0 0.0))
  (setq p2 '(0.0 1.0 0.0))
  (setq pt1 (polar p1 (setq ang (- (angle p1 p2) (* 0.5 pi))) 1.0))
  (setq pt2 (polar p2 ang 1.0))
  (command "line" pt1 pt2 "")
) ;_ >defun

Is there a better way to address this issue?
Most likely in the future I will have to analyze the correct side for point projection.

Augusto

  • Newt
  • Posts: 75
Re: Inaccurate result when calculating angle
« Reply #5 on: January 29, 2019, 08:56:24 AM »
Lee,
I found this feature on your site and I believe it will work for me.

http://www.lee-mac.com/clockwisep.html

Thanks

Augusto

  • Newt
  • Posts: 75
Re: Inaccurate result when calculating angle
« Reply #6 on: January 29, 2019, 11:24:25 AM »
Could anyone suggest improvement for this code?

Code: [Select]
(defun c:test(/ pt p1 p2 p3 p4 pt1 pt2 pt3 pt4 dwgobj oldOSMOD)
  (vl-load-com)
 
  (defun *error* (errmsg)
    (if
      (not
(wcmatch errmsg
"Function cancelled,quit / exit abort,console break,end"
) ;_ >wcmatch
      ) ;_ >not
       (princ (strcat "\nError: " errmsg))
    ) ;_ >if
    (vla-endundomark dwgobj)
    (if oldOSMOD
      (setvar 'OSMODE oldOSMOD)
    ) ;_ >if
    (princ)
  ) ;_ >defun

  ;; Circle Tangents 
  ;; Author:  Lee Mac, Copyright © 2014  -  www.lee-mac.com
  (defun grarc (cen pt1 pt2 / ang rad)
    (setq ctan:res 60  ;; arc resolution (int > 0)
  ctan:2pi (+ pi pi)
  ctan:inc (/ ctan:2pi ctan:res)
    ) ;_ >setq   
    (setq ang (angle cen pt1)
  rad (distance cen pt1)
    ) ;_ >setq
    (repeat (fix (/ (rem (+ (- (angle cen pt2) ang) ctan:2pi) ctan:2pi)
    ctan:inc
) ;_ >/
    ) ;_ >fix
      (grdraw pt1
      (setq pt1 (polar cen (setq ang (+ ang ctan:inc)) rad))
      1
      ) ;_ >grdraw
    ) ;_ >repeat
    (grdraw pt1 pt2 1)
  ) ;_ >defun
 
  ;; Clockwise-p  -  Lee Mac
  ;; Returns T if p1,p2,p3 are clockwise oriented
  (defun LM:Clockwise-p (p1 p2 p3)
    ((lambda (n) (< (car (trans p2 0 n)) (car (trans p1 0 n))))
      (mapcar '- p1 p3)
    )
  ) ;_ >defun

  ;; Project Point onto Line  -  Lee Mac
  ;; Projects pt onto the line defined by p1,p2
  (defun LM:ProjectPointToLine (pt p1 p2 / nm)
    (setq nm (mapcar '- p2 p1)
  p1 (trans p1 0 nm)
  pt (trans pt 0 nm)
    ) ;_ >setq
    (trans (list (car p1) (cadr p1) (caddr pt)) nm 0)
  ) ;_ >defun

  (setq dwgobj (vla-get-activedocument (vlax-get-acad-object)))
  (vla-startundomark dwgobj)
  (setq p1 (getpoint "p1"))
  (setq p2 (getpoint "p2"))
  (setq p3 (getpoint "p3"))
  (setq p4 (getpoint "p4"))
  (setq oldOSMOD (getvar 'OSMODE))
  (setvar 'OSMODE 0)

  (if (LM:Clockwise-p p1 p2 p4)
    (setq pt1 (polar p1 (setq ang (- (angle p1 p2) (* 0.5 pi))) 1.0))
    (setq pt1 (polar p1 (setq ang (+ (angle p1 p2) (* 0.5 pi))) 1.0))
  ) ;_ >if
  (setq pt2 (polar p2 ang 1.0))

  (if (setq isClockwise(LM:Clockwise-p p3 p4 p1))
    (setq pt3 (polar p3 (setq ang (- (angle p3 p4) (* 0.5 pi))) 1.0))
    (setq pt3 (polar p3 (setq ang (+ (angle p3 p4) (* 0.5 pi))) 1.0))
  ) ;_ >if
  (setq pt4 (polar p4 ang 1.0))
  (setq pt (inters pt1 pt2 pt3 pt4))
  (if isClockwise
    (grarc
      pt
      (LM:ProjectPointToLine pt p3 p4)
      (LM:ProjectPointToLine pt p1 p2)
    ) ;_ >grarc
    (grarc
      pt
      (LM:ProjectPointToLine pt p1 p2)
      (LM:ProjectPointToLine pt p3 p4)     
    )
    )
  (*error* "end")
)