DD to DMS

DD to DMS

RickfromtheNorth
Advocate Advocate
1,242 Views
7 Replies
Message 1 of 8

DD to DMS

RickfromtheNorth
Advocate
Advocate

Hi need some help, I'm sure it's an easy one. I have this function to convert from DD to DMS but I want it to round to 5 seconds. Would love a hand with this.

Thanks

(defun degtodms (a)
  (setq crvdeg (fix a))
  ;(princ crvdeg)
  (setq remain (- a crvdeg))
  (setq remain (* remain 60))
  (setq crvmin (fix remain))
  (setq remain (- remain crvmin))
  (setq remain (* remain 60))
  ;(princ crvmin)
  (setq crvsec (fix remain))
  (setq remain (- remain crvsec))
  (setq remain (* remain 10))
  (setq res (fix remain))
  ;(princ crvsec)
  ;(princ res)
  (if (>= res 5) (setq crvsec (+ crvsec 1)))
  (if (= crvsec 60) (progn
    (setq crvsec 0) (setq crvmin (+ crvmin 1)))
  )
  (if (= crvmin 60) (progn
    (setq crvmin 0) (setq crvdeg (+ crvdeg 1)))
  )
  (setq crvdeg (rtos crvdeg 2 0))
  (setq crvmin (rtos crvmin 2 0))
  (if (= (strlen crvmin) 1)
    (setq crvmin (strcat "0" crvmin))
  )
  (setq crvsec (rtos crvsec 2 0))
  (if (= (strlen crvsec) 1)
    (setq crvsec (strcat "0" crvsec))
  )
  (setq a (strcat crvdeg "." crvmin crvsec))
)
0 Likes
Accepted solutions (1)
1,243 Views
7 Replies
Replies (7)
Message 2 of 8

CodeDing
Mentor
Mentor

@RickfromtheNorth ,

 

I tested a little bit. This seems to be working for me:

 

Command: (DD2DMS-5SEC 54.321)
Actual:    54°19'15"
Converted: 54°19'15"
Command: (DD2DMS-5SEC 54.456)
Actual:    54°27'21"
Converted: 54°27'20"
Command: (DD2DMS-5SEC 54.458)
Actual:    54°27'28"
Converted: 54°27'30"
Command: (DD2DMS-5SEC 54.468)
Actual:    54°28'04"
Converted: 54°28'05"
Command: (DD2DMS-5SEC 54.466)
Actual:    54°27'57"
Converted: 54°27'55"
Command: (DD2DMS-5SEC 54.4665)
Actual:    54°27'59"
Converted: 54°28'00"

 

 

(defun DD2DMS-5Sec (deg / Pad2 d m s tmp r)
  (defun Pad2 (str / )
    (strcat (substr "00" (1+ (strlen str))) str)
  );defun
  (setq d (fix deg)
        m (fix (setq tmp (* 60.0 (- deg d))))
        s (fix (* 60.0 (- tmp m)))
  );setq
  (setq r (rem s 5))
  (if (< r 2.5)
    (setq s (- s r))
  ;else
    (progn
      (setq s (+ s (- 5 r)))
      (if (= 60 s)
        (setq s 0 m (1+ m))
      );if
      (if (= 60 m)
        (setq m 0 d (1+ d))
      );if
    );progn
  );if
  (strcat
    (Pad2 (rtos d 2 0)) "°"
    (Pad2 (rtos m 2 0)) "'"
    (Pad2 (rtos s 2 0)) "\""
  );strcat
);defun

 

EDIT TO CODE:

- Renamed the function to appropriate name (instead of 5min, lol)

- Added minute check to add degree if necessary

 

Best,

~DD

0 Likes
Message 3 of 8

RickfromtheNorth
Advocate
Advocate

Hi thanks for the changes but I would prefer not changing all the variables I'll just include all my code to see if it can be fixed without renaming all my variables and functions. Finding rounding errors using this fix command that carries through multiple times. I need to get Value for A "Angle in DD" to 6 decimal places then this might work.

(defun valu (a b) (cdr (assoc a b)))
;;;Converts angle in cartesian to polar angle
(defun angcor  (xa)
  (cond	((minusp xa) (angcor (+ xa (* 2 pi))))
	(xa)))
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;FROM DECIMAL DEGREES TO DEGREES MINUTES SECONDS
(defun degtodms (a)
  (setq crvdeg (fix a)) ; crvdeg = 67
  (setq remain (- a crvdeg)) ; remain = 0.838767 should be
  (setq remain (* remain 60)); remain = 50.32602 should be
  (setq crvmin (fix remain)); crvmin = 50
  (setq remain (- remain crvmin)); remain = 0.32602 should be
  (setq remain (* remain 60)); remain = 19.5612 should be
  (setq crvsec (fix remain)); crvsec= 19
  (setq remain (- remain crvsec)); remain = 0.5612 should be
  (setq remain (* remain 10)); remain=5.612 should be
  (setq res (fix remain))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  (if (>= res 5) (setq crvsec (+ crvsec 1)))
  (if (= crvsec 60) (progn
    (setq crvsec 0) (setq crvmin (+ crvmin 1)))
  )
  (if (= crvmin 60) (progn
    (setq crvmin 0) (setq crvdeg (+ crvdeg 1)))
  )
  (setq crvdeg (rtos crvdeg 2 0))
  (setq crvmin (rtos crvmin 2 0))
  (if (= (strlen crvmin) 1)
    (setq crvmin (strcat "0" crvmin))
  )
  (setq crvsec (rtos crvsec 2 0))
  (if (= (strlen crvsec) 1)
    (setq crvsec (strcat "0" crvsec))
  )
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;MAIN PROGRAM
(defun c:curvelabletest (/ p1 p2 p3 x x1 y)
  (prompt "\nPick Arc or Circle:  ")
  (setq ent (entget (car (entsel))))
  (if (or 
        (= (valu 0 ent) "ARC")
        (= (valu 0 ent) "CIRCLE")
      )
    (progn
      (setq p1 (getpoint (valu 10 ent) "\nSelect the Beginning of the Curve."))
      (setq p2 (getpoint (valu 10 ent) "\nSelect the End of the Curve."))
      (setq p3 (valu 10 ent))
      (setq x (angcor (- (angcor (angle p3 p1)) (angcor (angle p3 p2)))))
      (setq x1 (/ x 2))
      (setq y (distance p1 p3))
      (setq y (* y (exp-get-csf-convert)));apply scale factor
      (setq rad (strcat "R = " (rtos y 2 2)))
      (setq dlt (atof (angtos (- (dtr 90) x) 0 6)))
      (setq dlt2 (degtodms dlt))
      (setq dlt (strcat "\\U+0394 = " crvdeg "%%d" crvmin "'" crvsec "\""))
      (if (minusp x)
        (setq arclen (strcat "A = " (rtos (abs (* (+ 6.2831853072 x) y)) 2 2)))
        (setq arclen (strcat "A = " (rtos (abs (* x y)) 2 2)))
      )
      (setq inspt (getpoint "\nSelect an insertion point for the text. "))
      (command "TEXT" "M" inspt "90" rad)
      (command "TEXT" "" arclen)
      (command "TEXT" "" dlt)
    )
    (princ "\nItem is not a Circle or Arc...")
  )
(princ)
)

 

0 Likes
Message 4 of 8

Jeff_M
Consultant
Consultant

@RickfromtheNorth  The below works when selecting the start and end points of the arc to label Clockwise, I leave it to you to add the code needed to work when selecting in CCW. I used the code @CodeDing posted as it is much cleaner to read and functions well. Also, the line to apply a scale factor is commented out since you did not provide that function and I needed to test without it.

(defun c:curvelabletest (/ p1 p2 p3 x entlength y arclen dlt ent inspt rad)
  (prompt "\nPick Arc or Circle:  ")
  (setq ent (entget (car (entsel))))
  (if (or 
        (= (valu 0 ent) "ARC")
        (= (valu 0 ent) "CIRCLE")
      )
    (progn
      (setq p1 (getpoint (valu 10 ent) "\nSelect the Beginning of the Curve."))
      (setq p2 (getpoint (valu 10 ent) "\nSelect the End of the Curve."))
      (setq p3 (valu 10 ent))
      (setq entlength (vla-get-arclength (vlax-ename->vla-object (valu -1 ent))))
      (setq x (angcor (- (angle p3 p1) (angle p3 p2))))    
      (setq y (distance p1 p3))
      ;;(setq y (* y (exp-get-csf-convert)));apply scale factor
      (setq rad (strcat "R = " (rtos y 2 2)))
      (setq dlt (atof (angtos x 0 6)))
      ;;using DD2DMS-5Sec by Code Ding as posted to the C3D Customization forum
      (setq dlt (strcat "\\U+0394 = "(DD2DMS-5Sec dlt)))
      (setq arclen (strcat "A = " (rtos (abs (* x y)) 2 2)))
      (setq inspt (getpoint "\nSelect an insertion point for the text. "))
      (command "TEXT" "M" inspt "90" rad)
      (command "TEXT" "" arclen)
      (command "TEXT" "" dlt)
    )
    (princ "\nItem is not a Circle or Arc...")
  )
(princ)
)

 

Jeff_M, also a frequent Swamper
EESignature
Message 5 of 8

RickfromtheNorth
Advocate
Advocate

Hi, ok I have combined these together and do not get the proper Delta either way I select it. CW or CCW. I should get as an example 67%%d50'20"

(defun angcor  (xa)
  (cond	((minusp xa) (angcor (+ xa (* 2 pi))))
	(xa)))
(defun c:curvelabletestnew (/ p1 p2 p3 x entlength y arclen dlt ent inspt rad)
  (prompt "\nPick Arc or Circle:  ")
  (setq ent (entget (car (entsel))))
  (if (or 
        (= (valu 0 ent) "ARC")
        (= (valu 0 ent) "CIRCLE")
      )
    (progn
      (setq p1 (getpoint (valu 10 ent) "\nSelect the Beginning of the Curve."))
      (setq p2 (getpoint (valu 10 ent) "\nSelect the End of the Curve."))
      (setq p3 (valu 10 ent))
      (setq entlength (vla-get-arclength (vlax-ename->vla-object (valu -1 ent))))
      (setq x (angcor (- (angle p3 p1) (angle p3 p2))))    
      (setq y (distance p1 p3))
      (setq y (* y (exp-get-csf-convert)));apply scale factor
      (setq rad (strcat "R = " (rtos y 2 2)))
      (setq dlt (atof (angtos x 0 6)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 (defun DD2DMS-5Sec (deg / Pad2 d m s tmp r)
  (defun Pad2 (str / )
    (strcat (substr "00" (1+ (strlen str))) str)
  );defun
  (setq d (fix deg)
        m (fix (setq tmp (* 60.0 (- deg d))))
        s (fix (* 60.0 (- tmp m)))
  );setq
  (setq r (rem s 5))
  (if (< r 2.5)
    (setq s (- s r))
  ;else
    (progn
      (setq s (+ s (- 5 r)))
      (if (= 60 s)
        (setq s 0 m (1+ m))
      );if
      (if (= 60 m)
        (setq m 0 d (1+ d))
      );if
    );progn
  );if
  (strcat
    (Pad2 (rtos d 2 0)) "°"
    (Pad2 (rtos m 2 0)) "'"
    (Pad2 (rtos s 2 0)) "\""
  );strcat
);defun
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      (setq dlt (strcat "\\U+0394 = "(DD2DMS-5Sec dlt)))
      (setq arclen (strcat "A = " (rtos (abs (* x y)) 2 2)))
      (setq inspt (getpoint "\nSelect an insertion point for the text. "))
      (command "TEXT" "M" inspt "90" rad)
      (command "TEXT" "" arclen)
      (command "TEXT" "" dlt)
    )
    (princ "\nItem is not a Circle or Arc...")
  )
(princ)
)

RickfromtheNorth_0-1740670401171.png

 

0 Likes
Message 6 of 8

RickfromtheNorth
Advocate
Advocate

Seems Like I'm getting the complimentary angle or something.

0 Likes
Message 7 of 8

RickfromtheNorth
Advocate
Advocate
Accepted solution

So I got this to work now, need to figure out how to get proper angle if I pick in CCW direction.

(defun valu (a b) (cdr (assoc a b)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Checks
(defun angcor  (xa)
  (cond	((minusp xa) (angcor (+ xa (* 2 pi))))
	(xa)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun DD2DMS-5Sec (deg / Pad2 d m s tmp r)
  (defun Pad2 (str / )
    (strcat (substr "00" (1+ (strlen str))) str)
  );defun
  (setq d (fix deg)
        m (fix (setq tmp (* 60.0 (- deg d))))
        s (fix (* 60.0 (- tmp m)))
  );setq
  (setq r (rem s 5))
  (if (< r 2.5)
    (setq s (- s r))
  ;else
    (progn
      (setq s (+ s (- 5 r)))
      (if (= 60 s)
        (setq s 0 m (1+ m))
      );if
      (if (= 60 m)
        (setq m 0 d (1+ d))
      );if
    );progn
  );if
  (strcat
    (Pad2 (rtos d 2 0)) "°"
    (Pad2 (rtos m 2 0)) "'"
    (Pad2 (rtos s 2 0)) "\""
  );strcat
);defun
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Main program
(defun c:test10 (/ p1 p2 p3 x entlength y arclen dlt ent inspt rad)
  (prompt "\nPick Arc or Circle:  ")
  (setq ent (entget (car (entsel))))
  (if (or 
        (= (valu 0 ent) "ARC")
        (= (valu 0 ent) "CIRCLE")
      )
    (progn
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;User input
      (setq p1 (getpoint (valu 10 ent) "\nSelect the Beginning of the Curve."));user input
      (setq p2 (getpoint (valu 10 ent) "\nSelect the End of the Curve."));user input
      (setq p3 (valu 10 ent)); Center of arc of circle
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Arc
      (setq entlength (vla-get-arclength (vlax-ename->vla-object (valu -1 ent)))); arclength from entity
      (setq arclen (strcat "A = " (rtos (* entlength (exp-get-csf-convert)) 2 2))) ; Arclength text with scale factor
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Radius
      (setq y (distance p1 p3)) ; radius calc
      (setq y (* y (exp-get-csf-convert)));apply scale factor to radius
      (setq rad (strcat "R = " (rtos y 2 2))); Radius Text
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Delta
      (setq x (angcor (- (angcor (angle p3 p1)) (angcor (angle p3 p2))))); angle difference in 
      (setq dlt (atof (angtos (- (dtr 90) x) 0 6)));Delta angle in DD
      (princ dlt)
      (setq dlt (strcat "\\U+0394 = " (DD2DMS-5Sec dlt)));Delta text calling DMS and Rounding to 5 seconds
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Text output
      (setq inspt (getpoint "\nSelect an insertion point for the text. "))
      (command "TEXT" "M" inspt "90" rad)
      (command "TEXT" "" arclen)
      (command "TEXT" "" dlt)
    )
    (princ "\nItem is not a Circle or Arc...")
  )
(princ)
)


     
0 Likes
Message 8 of 8

RickfromtheNorth
Advocate
Advocate

Got it all figured now, Thanks to Jeff and CodeDing

0 Likes