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.
Solved! Go to Solution.
Solved by Kent1Cooper. Go to Solution.
Solved by alanjt_. Go to Solution.
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
That worked great, TharwaT313! I will populate the routine, but that's exactly what I was looking for. Thank you!! 🙂
(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.
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) )
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 .
@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.
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) )
(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)
)
Thanks, alanjt and Tharwat313 - you too pbejse for contributing in streamlining the routine to work for everyone. Cheers and happy holidays to everyone! 🙂
@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.
Hi pbejse - Just so you'd know, I tested your code and it gave me this error: ERROR: bad argument type: numberp: nil
@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.
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.
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.
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.
@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.