Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Zoom into a set of coordinates depending depending on selection

49 REPLIES 49
SOLVED
Reply
Message 1 of 50
kameron1967
1708 Views, 49 Replies

Zoom into a set of coordinates depending depending on selection

Hi guys,

 

I wonder if anyone can do a routine that zooms into a coordinate, based on input.  So for 1A, it would zoom into the coordinate for 1A.

 

1A = 1,1

1B = 1,2

1C = 1,3

1D = 1,4

 

I will try to attempt one shortly and will post it within 1 hour.  Thanks in advance.

49 REPLIES 49
Message 2 of 50
_Tharwat
in reply to: kameron1967

This ... ?

 

(defun c:TesT (/ rep)
  (initget "1A 1B 1C 1D")
  (if (setq rep (getkword "\n Specify your input [1A 1B 1C 1D] :"))
    (cond ((eq rep "1A")
           (command "_.zoom" (list 0.99 0.99 0.) (list 1.01 1.01 0.))
          )
          ((eq rep "1B")
           (command "_.zoom" (list 0.99 1.99 0.) (list 1.01 2.01 0.))
          )
          ((eq rep "1C")
           (command "_.zoom" (list 0.99 2.99 0.) (list 1.01 3.01 0.))
          )
          ((eq rep "1D")
           (command "_.zoom" (list 0.99 3.99 0.) (list 1.01 4.01 0.))
          )
    )
    (princ)
  )
  (princ)
)

 Tharwat

Message 3 of 50
kameron1967
in reply to: _Tharwat

That worked great, TharwaT313!  I will populate the routine, but that's exactly what I was looking for.  Thank you!!  🙂

Message 4 of 50
_Tharwat
in reply to: kameron1967

I am happy to hear that . Smiley Happy

 

You're welcome .

 

Tharwat

Message 5 of 50
alanjt_
in reply to: _Tharwat

(defun c:TEst (/ zoom)
  (vl-load-com)
  (initget "A B C D")
  (if (setq zoom (getkword "\nSpecify zoom point [A/B/C/D]: "))
    (vlax-invoke
      (vlax-get-acad-object)
      'zoomcenter
      (list 1. (- (ascii zoom) 64) 0.)
      50.
    )
  )
  (princ)
)

 I took out the preceding "1" to make specifying the zoom point quicker and easier.

Message 6 of 50
alanjt_
in reply to: alanjt_

or this...

 

(defun c:TEst (/ zoom)
  (vl-load-com)
  (initget "1A 1B 1C 1D")
  (if (setq zoom (cdr (assoc (getkword "\nSpecify zoom point [1A/1B/1C/1D]: ")
                             '(("1A" 1. 1. 0.)
                               ("1B" 1. 2. 0.)
                               ("1C" 1. 3. 0.)
                               ("1D" 1. 4. 0.)
                              )
                      )
                 )
      )
    (vlax-invoke
      (vlax-get-acad-object)
      'zoomcenter
      zoom
      50.
    )
  )
  (princ)
)

 

Message 7 of 50
_Tharwat
in reply to: kameron1967

Since the coordinates are less then 1.0 so the 50. would appear the coordinate faraway , so to replace with 0.9 would look more closer and clearier .

Message 8 of 50
alanjt_
in reply to: _Tharwat


@TharwaT313 wrote:

Since the coordinates are less then 1.0 so the 50. would appear the coordinate faraway , so to replace with 0.9 would look more closer and clearier .


50 was just an arbitrary zoom scale factor I chose. It can be changed to anything greter than zero. Hell, make it one.

Message 9 of 50
kameron1967
in reply to: alanjt_

You're both awesome.  Thank you, alanjt! 

Message 10 of 50
pbejse
in reply to: kameron1967

Another variant using ZoomWindow (alanjt code)

 

(defun c:TEst (/ zoom)
  (vl-load-com)
  (if (not size)
            (setq dist 1.00))
      (setq size (cond
                       ((getreal
                              (strcat "\nEnter Distance <"
                                      (rtos size 2 2)
                                      ">: ")))
                       (size)))
  (initget "1A 1B 1C 1D")
  (if (setq zoom (cdr (assoc (getkword "\nSpecify zoom point [1A/1B/1C/1D]: ")
                             '(("1A" 1. 1. 0.)
                               ("1B" 1. 2. 0.)
                               ("1C" 1. 3. 0.)
                               ("1D" 1. 4. 0.)
                              )
                      )
                 )
      )
    
    (vlax-invoke
      (vlax-get-acad-object)
      'ZoomWindow
      (polar zoom (* pi 0.25) (* size (sqrt 2)))
      (polar zoom (* pi 1.25) (* size (sqrt 2)))
    )
  )
  (princ)
)

 

Message 11 of 50
alanjt_
in reply to: pbejse

(defun c:TEst (/ _lst2str zoomlist zoom)
  (vl-load-com)

  (setq zoomlist '(("1A" 1. 1. 0.)
                   ("1B" 1. 2. 0.)
                   ("1C" 1. 3. 0.)
                   ("1D" 1. 4. 0.)
                  )
  )

  (defun _lst2str (l s)
    (apply 'strcat (cdr (apply 'append (mapcar (function (lambda (i) (list s (car i)))) l))))
  )

  (initget (_lst2str zoomlist " "))
  (if (setq zoom (cdr (assoc
                        (getkword (strcat "\nSpecify zoom point [" (_lst2str zoomlist "/") "]: "))
                        zoomlist
                      )
                 )
      )
    (vlax-invoke
      (cond (*Acad*)
            ((setq *Acad* (vlax-get-acad-object)))
      )
      'zoomcenter
      zoom
      (* (getvar 'VIEWSIZE) 0.02)
    )
  )
  (princ)
)

 

Message 12 of 50
kameron1967
in reply to: alanjt_

Thanks, alanjt and Tharwat313 - you too pbejse for contributing in streamlining the routine to work for everyone.  Cheers and happy holidays to everyone! 🙂

Message 13 of 50
Kent1Cooper
in reply to: kameron1967


@kameron1967 wrote:

....  I will populate the routine, but that's exactly what I was looking for. ....


If by "populate the routine" you mean you'll build all the number-letter combinations you might need, with their Zoom coordinates all spelled out separately, that's more work than I think you need to do.  If they're always 1-unit increments in both directions between positions you want, try this, which picks up on alanjt's concept of using the ASCII code for the letter to figure out the number for the Z coordinate, and expands it to a universal application:
 

(defun C:ZC (/ zc); = Zoom to Coordinates
  (if
    (setq zc (getstring "\nSpecify Number-Letter zoom coordinate [e.g. 1A, 27G, etc.]: "))
    (if ; then
      (and
        (<= (strlen (setq zc (strcase zc))) 3)
        (< 47 (ascii (substr zc 1 1)) 58); 1st between 0 & 9
        (if (= (strlen zc) 3); two-digit numerical portion
          (< 47 (ascii (substr zc 2 1)) 58); 2nd [if any] between 0 & 9
          T ; no second digit
        ); if
        (< 64 (ascii (substr zc (strlen zc))) 91); last between A & Z
      ); and
      (command ; then -- Zoom to it
        "_.zoom" "_c"

        "_none"
        (list
          (atoi (substr zc 1 (1- (strlen zc)))); X coordinate
          (- (ascii (substr zc (strlen zc))) 64); Y coordinate
          0
        ); list
        1 ; height for non-vertically-overlapping viewed areas -- adjust if desired
      ); command
      (prompt "\nInvalid entry."); else
    ); if
  ); if
  (princ)
)

 

That covers all possible locations from 0A through 99Z -- 26 rows and 100 columns.  It wouldn't be hard to make it allow three-digit numerical parts [for 1000 possible columns], and/or both upper- and lower-case letter parts [for 52 possible rows].  It could be adjusted for a spacing between columns of other than 1 unit [since your original example only has one column of positions -- I have assumed 1-unit spacing for those as for the rows].  You could also adjust it to not just report invalid input, but ask again.

Kent Cooper, AIA
Message 14 of 50
alanjt_
in reply to: Kent1Cooper

FYI Kent. initget doesn't work with getstring.

Message 15 of 50
kameron1967
in reply to: kameron1967

Hi pbejse - Just so you'd know, I tested your code and it gave me this error:  ERROR: bad argument type: numberp: nil

 

 

Message 16 of 50
Kent1Cooper
in reply to: alanjt_


@alanjt_ wrote:

FYI Kent. initget doesn't work with getstring.


Whoops -- that was just a copy/paste holdover [from your first post, actually] that I didn't look back closely enough to notice was still there and eliminate [after all, it didn't prevent the routine from working].  Thanks for noticing it so soon, because I was still allowed into my previous post, so I've edited it out now, for those who wonder what this is all about.

Kent Cooper, AIA
Message 17 of 50
alanjt_
in reply to: Kent1Cooper

Right on. If you look at the last bit of code I posted, you can see that I followed a similar idea in that the user can add much point data the zoomlist variable and it will always be acceptalbe and displayed with getkword+iniget.

Message 18 of 50
kameron1967
in reply to: Kent1Cooper

Kent - I like your idea as well.  I see where that could be applied.  I wonder though if we can specify the xy coordinate where the grid begins.  The coordinate is based on the origin at present, but to apply it to real situation, we'd want to set the starting point (1A) at let's say 100, 200 and have it go negative direction.  So for X or -X direction, A would be at 90, B woud be at 80 and so on.  As for the Y direction, 1 would be at the 190 and 2 would be at 180 and so on.

 

If we can account for the gap distances for both X or Y direction between each grid lines as well as specify the original grid starting point - your routine would be more applicable. 

 

Sorry - I don't mind working the long way with the ones that were provided, but if you think it's a doable task, I'd love to see it. 

Message 19 of 50
kameron1967
in reply to: alanjt_

Alanjt - yours did pick up on the selecitons without me having to create a separate list.  However, I still get an error on it.  I tried to copy/paste line by line as your code is not in a "code" format.  It pastes into one single line.  If you could update it, perhaps it will run without a glitch.

 

Thanks in advance.

Message 20 of 50
Kent1Cooper
in reply to: alanjt_


@alanjt_ wrote:

Right on. If you look at the last bit of code I posted, you can see that I followed a similar idea in that the user can add much point data the zoomlist variable and it will always be acceptalbe and displayed with getkword+iniget.


That approach would certainly be better than mine in certain circumstances, for example if not all positions whose designations start with "1" are at an X value of 1, and/or not all those whose designations end in "C" are at a Y value of 3 -- you can spell out the specific location for every position individually.  But then, that does mean that you must spell out the specific location for every position individually.  Imagine the zoomlist to cover 2600 possible positions!
 

Even if the spacing between columns of positions isn't 1 as it is for the rows [at least the few rows in the original example], as long as it's regular, it could be handled in a universal way with a multiplier on the X coordinate of the Zoom center location.  And even if it's not regular, as long as all positions in each column are vertically aligned, it could be handled in a universal way with a simpler list of just the X coordinates of the columns, e.g. '(1 2 3.5 5 8 9 ...), and the values could be extracted using (nth), and similarly with the letter-designated row locations.  Something like that would still be able to cover a very much larger number of positions in far less code than spelling out every possible position separately.

Kent Cooper, AIA

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost