Author Topic: Cursor Rotate  (Read 4210 times)

0 Members and 1 Guest are viewing this topic.

novice

  • Guest
Cursor Rotate
« on: September 16, 2015, 03:09:31 pm »
I wrote some code to rotate my crosshairs so I can input text at an angle to match my drawings, more easily add dimensions at this set angle, etc. Super handy.

So here it is as it is:

Code - Auto/Visual Lisp: [Select]
  1. ;;cr = cursor rotate
  2. ;;(Set snap angle to angle of existing text string, dimension, or
  3. ;;line (set Snap To Object))
  4.  
  5. (defun C:CR ()
  6.  (setq ent (entget (car
  7.    (entsel "\nSelect a text string, dimension, line, arc, or circle: "))))
  8.  (setq tp1 (cdr (assoc 0 ent)))
  9.  (while (= tp1 "LWPOLYLINE")
  10.    (princ "\nThe selected entity is a POLYLINE. Try again...")
  11.    (setq ent (entget (car
  12.      (entsel "\nSelect a text string, dimension, line, arc, or circle: "))))
  13.    (setq tp1 (cdr (assoc 0 ent))))
  14.  
  15. (defun STTEXT ()
  16.  (setq ip (cdr (assoc 10 ent)))
  17.  (setq rang (cdr (assoc 50 ent)))
  18.  (setq dang (* (/ 180 pi) rang))
  19.  (command "snap" "r" ip dang)
  20.  (command "snap" "off")(princ))
  21.  
  22. (defun STLINE ()
  23.  (setq org (getvar "osmode"))
  24.  (setvar "osmode" 0)
  25.  (setq pt1 (cdr (assoc 10 ent)))
  26.  (setq pt2 (cdr (assoc 11 ent)))
  27.  (command "snap" "r" pt1 pt2)
  28.  (setvar "osmode" org)
  29.  (command "snap" "off")(princ))
  30.  
  31. (defun STDIM ()
  32.  (setq aor (cdr (assoc 70 ent)))
  33.  (if (= aor 33)
  34.    (progn (setq pt1 (cdr (assoc 13 ent)))
  35.      (setq pt2 (cdr (assoc 14 ent)))
  36.      (command "snap" "r" pt1 pt2)
  37.      (command "snap" "off")(princ))
  38.    (progn (setq rang (cdr (assoc 50 ent)))
  39.      (setq dang (* (/ 180 pi) rang))
  40.      (command "snap" "r" "0,0" dang)
  41.      (command "snap" "off")(princ))))
  42.  
  43. (defun STCURVE ()
  44.  (setq tp0 (cdr (assoc -1 ent)))
  45.  (redraw tp0 3)
  46.  (setq pt1 (getpoint "\nPick the point of tangency..."))
  47.  (redraw tp0 4)
  48.  (setq ctr (cdr (assoc 10 ent)))
  49.  (setq rang (angle pt1 ctr))
  50.  (setq dang (+ 90 (/ (* rang 180.0) pi)))
  51.  (command "snap" "r" pt1 dang)
  52.  (command "snap" "off")(princ))
  53.  
  54.  (cond ((= tp1 "TEXT") (STTEXT))
  55.        ((= tp1 "LINE") (STLINE))
  56.        ((= tp1 "DIMENSION") (STDIM))
  57.        ((= tp1 "ARC") (STCURVE))
  58.        ((= tp1 "CIRCLE") (STCURVE)))
  59.  (princ))
  60.  
  61. ;;cra = cursor rotate to specified angle
  62.  
  63. (defun C:CRA ()
  64.  (setq ang1 (getstring "Rotate cursor at what angle?: "))
  65.  (command "snap" "r" "0,0" ang1)
  66.  (command "snap" "off")(princ))
  67.  
  68. ;;cr2 = cursor rotate defined by two points
  69.  
  70. (defun c:CR2 ( / r e p1 p2)
  71.  (graphscr)
  72.  (initget "Entity")
  73.  (setq r
  74.  (getangle "\nSnap rotation angle/<Entity>: "))
  75.  (cond
  76.     (  (numberp r)
  77.       (setvar "snapang" r))
  78.     (  (and (or (not r) (eq r "Entity"))
  79.        (setq e (entsel))
  80.        (setq p1 (osnap (cadr e) "qui,end"))
  81.        (setq p2 (osnap (cadr e) "qui,mid")))
  82.   (setvar "snapang" (angle p1 p2)))
  83.     (t (princ "\nInvalid selection.")))
  84.  (princ)
  85. )

There's three commands in there - I'm fine with that (I aim low, I guess). But I don't know how to make this work when clicking on MTEXT or POLYLINES. I wish that weren't the case.

Ideally, I would abandon use of the CR2 command, if I could use an all-purpose CR command to also pick MTEXT, POLYLINES, BLOCKS (would extract angle data from the picked object nested in the block), etc.

Just throwing this out there...

Thanks,
Novice

ronjonp

  • Needs a day job
  • Posts: 6430
Re: Cursor Rotate
« Reply #1 on: September 16, 2015, 04:03:59 pm »
Maybe this will give you some ideas:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:rsa (/ a cp e p pa)
  2.  (if (setq e (entsel "\nPick object to match rotation: "))
  3.    (progn
  4.      (setq p (cadr e)
  5.    e (car e)
  6.      )
  7.      (cond ((vlax-property-available-p (vlax-ename->vla-object e) 'rotation)
  8.     (setvar 'snapang (vlax-get (vlax-ename->vla-object e) 'rotation))
  9.    )
  10.  (setq a (angle '(0 0) (vlax-curve-getfirstderiv e pa)))
  11.     )
  12.     (setvar 'snapang a)
  13.    )
  14.      )
  15.    )
  16.  )
  17.  (princ)
  18. )
BTW .. welcome to the swamp :)

Windows 10 x64 - AutoCAD /C3D 2018

Custom Build PC

novice

  • Guest
Re: Cursor Rotate
« Reply #2 on: September 16, 2015, 04:24:13 pm »
Wow... amazing. Thank you. Works fantastic, though I honestly don't have a clue what you did.

One thing I noticed is it gave me a wrong angle when I clicked on a block that had been rotated. It also didn't allow me to snap to a particular point on a circle, to get the tangent there.

I hope you know I'm not complaining!

Thanks for the kind welcome.

roy_043

  • Water Moccasin
  • Posts: 1513
  • BricsCAD 16
Re: Cursor Rotate
« Reply #3 on: September 17, 2015, 04:48:13 am »
One thing I noticed is it gave me a wrong angle when I clicked on a block that had been rotated.
The SNAPANG is expressed relative to the current UCS. So this can occur if you are not working in the WCS.
To get the rotation angle of the current UCS:
Code: [Select]
(angle '(0.0 0.0 0.0) (getvar 'ucsxdir))
I assume that this is a 2D only utility.

novice

  • Guest
Re: Cursor Rotate
« Reply #4 on: September 17, 2015, 08:17:53 am »
One thing I noticed is it gave me a wrong angle when I clicked on a block that had been rotated.
The SNAPANG is expressed relative to the current UCS. So this can occur if you are not working in the WCS.
To get the rotation angle of the current UCS:
Code: [Select]
(angle '(0.0 0.0 0.0) (getvar 'ucsxdir))
I assume that this is a 2D only utility.

I always work 2D, WCS.

ronjonp

  • Needs a day job
  • Posts: 6430
Re: Cursor Rotate
« Reply #5 on: September 17, 2015, 09:03:02 am »
Maybe post an example drawing.  I can't replicate the circle & block issue you're seeing.

Windows 10 x64 - AutoCAD /C3D 2018

Custom Build PC

Lee Mac

  • Seagull
  • Posts: 11851
  • AutoCAD 2015 Windows 7 London, England
Re: Cursor Rotate
« Reply #6 on: September 17, 2015, 09:38:13 am »
Maybe this will resolve the issues?

Code - Auto/Visual Lisp: [Select]
  1. (defun c:rsa ( / a e o p s z )
  2.    (while
  3.        (progn
  4.            (cond
  5.                (   (null (setq p (getpoint "\nPick point on object <exit>: ")))
  6.                    nil
  7.                )
  8.                (   (null (setq s (ssget "_C" (mapcar '- p '(1e-4 1e-4)) (mapcar '+ p '(1e-4 1e-4)))))
  9.                    (princ "\nPoint does not lie on an object.")
  10.                )
  11.                (   (progn
  12.                        (setq e (ssname s 0)
  13.                              o (vlax-ename->vla-object e)
  14.                              z (trans '(0 0 1) 1 0 t)
  15.                              a (angle '(0 0) (trans (getvar 'ucsxdir) 0 z t))
  16.                        )
  17.                        (vlax-property-available-p o 'rotation)
  18.                    )
  19.                    (not (setvar 'snapang (- (vla-get-rotation o) a)))
  20.                )
  21.                (   (vl-catch-all-error-p (setq p (vl-catch-all-apply 'vlax-curve-getclosestpointto (list e (trans p 1 0)))))
  22.                    (princ "\nIncompatible object selected.")
  23.                )
  24.                (   (not (setvar 'snapang (- (angle '(0 0) (trans (vlax-curve-getfirstderiv e (vlax-curve-getparamatpoint e p)) 0 z)) a))))
  25.            )
  26.        )
  27.    )
  28.    (princ)
  29. )

novice

  • Guest
Re: Cursor Rotate
« Reply #7 on: September 17, 2015, 10:38:14 am »
Maybe post an example drawing.  I can't replicate the circle & block issue you're seeing.

DWG file attached. The block this routine doesn't seem to work on is labeled "BLOCK1 (UNROTATED)".

The circle issue is just that when I pick the circle using your code, my crosshairs automatically rotate to the tangent of the circle where I selected it, without giving me the option of snapping to an exact point on the circle, for instance where it intersects a line. For comparison, the code I posted (my CR command) allows me to pick the circle first; then, pick an exact point on the circle.

novice

  • Guest
Re: Cursor Rotate
« Reply #8 on: September 17, 2015, 10:40:34 am »
Maybe this will resolve the issues?

Code - Auto/Visual Lisp: [Select]
  1. (defun c:rsa ( / a e o p s z )
  2.    (while
  3.        (progn
  4.            (cond
  5.                (   (null (setq p (getpoint "\nPick point on object <exit>: ")))
  6.                    nil
  7.                )
  8.                (   (null (setq s (ssget "_C" (mapcar '- p '(1e-4 1e-4)) (mapcar '+ p '(1e-4 1e-4)))))
  9.                    (princ "\nPoint does not lie on an object.")
  10.                )
  11.                (   (progn
  12.                        (setq e (ssname s 0)
  13.                              o (vlax-ename->vla-object e)
  14.                              z (trans '(0 0 1) 1 0 t)
  15.                              a (angle '(0 0) (trans (getvar 'ucsxdir) 0 z t))
  16.                        )
  17.                        (vlax-property-available-p o 'rotation)
  18.                    )
  19.                    (not (setvar 'snapang (- (vla-get-rotation o) a)))
  20.                )
  21.                (   (vl-catch-all-error-p (setq p (vl-catch-all-apply 'vlax-curve-getclosestpointto (list e (trans p 1 0)))))
  22.                    (princ "\nIncompatible object selected.")
  23.                )
  24.                (   (not (setvar 'snapang (- (angle '(0 0) (trans (vlax-curve-getfirstderiv e (vlax-curve-getparamatpoint e p)) 0 z)) a))))
  25.            )
  26.        )
  27.    )
  28.    (princ)
  29. )

This one has the same issue as ronjonp's, but in addition, I can't figure out how it works with MTEXT.

roy_043

  • Water Moccasin
  • Posts: 1513
  • BricsCAD 16
Re: Cursor Rotate
« Reply #9 on: September 17, 2015, 11:02:18 am »
DWG file attached. The block this routine doesn't seem to work on is labeled "BLOCK1 (UNROTATED)".
As you say: the block is not rotated (rotation=0.0) therefore the function should set the SNAPANG to 0.0, which it does. The fact that the block represents a rotated element is not relevant to the function.

novice

  • Guest
Re: Cursor Rotate
« Reply #10 on: September 17, 2015, 11:19:04 am »
DWG file attached. The block this routine doesn't seem to work on is labeled "BLOCK1 (UNROTATED)".
As you say: the block is not rotated (rotation=0.0) therefore the function should set the SNAPANG to 0.0, which it does. The fact that the block represents a rotated element is not relevant to the function.

I hope it's clear that I'm a novice! I'm not sure how to integrate your code into the main code. I mean, I assume what you're saying is that the code you offered should fix this problem?
« Last Edit: September 17, 2015, 11:39:48 am by novice »

roy_043

  • Water Moccasin
  • Posts: 1513
  • BricsCAD 16
Re: Cursor Rotate
« Reply #11 on: September 17, 2015, 12:42:23 pm »
DWG file attached. The block this routine doesn't seem to work on is labeled "BLOCK1 (UNROTATED)".
As you say: the block is not rotated (rotation=0.0) therefore the function should set the SNAPANG to 0.0, which it does. The fact that the block represents a rotated element is not relevant to the function.

I hope it's clear that I'm a novice! I'm not sure how to integrate your code into the main code. I mean, I assume what you're saying is that the code you offered should fix this problem?
No my suggestion won't fix the problem. Lee's code has incorporated this already. You are confused by the rotation of the content of the block as opposed to the rotation of the block itself.

roy_043

  • Water Moccasin
  • Posts: 1513
  • BricsCAD 16
Re: Cursor Rotate
« Reply #12 on: September 17, 2015, 12:47:12 pm »
@ Lee:
I find it strange that you use (trans) for the UCSXDIR but not for the block rotation. Or am I missing something?

Lee Mac

  • Seagull
  • Posts: 11851
  • AutoCAD 2015 Windows 7 London, England
Re: Cursor Rotate
« Reply #13 on: September 17, 2015, 12:53:10 pm »
@ Lee:
I find it strange that you use (trans) for the UCSXDIR but not for the block rotation. Or am I missing something?

I transform the UCSXDIR to be relative to the active UCS plane, and the code makes the assumption that the block resides in a plane parallel to the UCS plane - or have I missed your point?

roy_043

  • Water Moccasin
  • Posts: 1513
  • BricsCAD 16
Re: Cursor Rotate
« Reply #14 on: September 17, 2015, 01:13:06 pm »
@ Lee:
I find it strange that you use (trans) for the UCSXDIR but not for the block rotation. Or am I missing something?

I transform the UCSXDIR to be relative to the active UCS plane, and the code makes the assumption that the block resides in a plane parallel to the UCS plane - or have I missed your point?
No, but I did not make that assumption.