Jump to content

AutoLISP: Saving user chosen two points into variables when using the AutoCAD “rectangle” command.


RLispLearner

Recommended Posts

Is there a way to save variables of the “first corner point” and “other corner point” when a user picks first point, then types in the length and width (with dynamic input on) when using the “Rectangle” command?

 

Example:

Command: RECTANGLE

Specify first corner point or [Chamfer/Elevation/Fillet/Thickness/Width]:

Specify other corner point or [Area/Dimensions/Rotation]: @20',15' 

 

I want to replace what I have below with the “Rectangle” command so user can type in length and width they need. The user will want the length and width to be whole numbers (Ex: 13, 15, 20, 23...etc) which can be done when using the rectangle command. Right now they have to draw a rectangle they want in whole numbers first. Then use the routine and snap to the corners of that rectangle.  Hoping to combine all in one routine.

 

What I have now:

 (setq firstpick (getpoint "\nEnter first corner: "))

(setq secondpick (getcorner firstpick "\nEnter cross corner: "))

; Get all four corners of user drawn rectangle

(setq pt1 firstpick)

(setq pt3 secondpick)

(setq pt2 (list (car pt1) (cadr pt3)))

(setq pt4 (list (car pt3) (cadr pt1)))

; Get the Area drawn and save in variable “myrecarea”

 (setq mylength (distance pt1 pt2)); length

(setq mywidth (distance pt1 pt4)); width

(setq myrecarea (* mylength mywidth)); Get area of rectangle (length x width)

 

 

 

 

 

I want to replace with using the “Rectangle” command (if possible) so user can type in length and width. Not sure how to extract those points and save as variables...

(setq firstpick (command "rectangle"))(?)

(setq secondpick (?)

; Get all four corners of user drawn rectangle

(setq pt1 firstpick)

(setq pt3 secondpick)

(setq pt2 (list (car pt1) (cadr pt3)))

(setq pt4 (list (car pt3) (cadr pt1)))

; Get the Area drawn and save in variable “myrecarea”

 (setq mylength (distance pt1 pt2)); length

(setq mywidth (distance pt1 pt4)); width

(setq myrecarea (* mylength mywidth)); Get area of rectangle (length x width)

 

*The Area size  will determine what is drawn later in the routine…

 

 

One last question,

Is it possible to save everything drawn in a routine in a block? Not sure how the block naming would work if routine run several times in a single drawing without overwriting the original block.

 

 

Any assistance is greatly appreciated!

 

 

Link to comment
Share on other sites

I think your making this more complicated then it has to be. your inputting the length with @21',15'

 

(defun C:myrecarea (/ l w pt)
  (vl-load-com)
  (setq l (rtos (getdist "\nRectangle Lenght: ")2 0))
  (setq w (rtos (getdist "\nRectangle Width: ")2 0))
  (if (setq pt1 (getpoint "\nPick Bottom Left Corner: "))
    (command "_.Rectangle" pt1 (strcat "@" l "," w))
  )
  (setq myrecarea (vla-get-area (vlax-ename->vla-object (entlast)))) 
  (princ)
)
  ;or caculate pt2
  (setq l (getdist "\nRectangle Lenght: "))
  (setq w (getdist "\nRectangle Width: "))
  (if (setq pt1 (getpoint "\nPick Bottom Left Corner: "))
  (setq pt2 (list (+ (car pt1) l) (+ (cadr pt1) w)))
  (command "_.Rectangle" pt1 pt2)
  (setq myrecarea (* l w))

 

To answer your second question.

(setq SS (ssadd)) ;whatever your adding to needs to be defined before you can add to it.
....
(setq LastEnt (entlast)) ;any entity after this line of code that is edited or created will be added to the selection set.
....
;this is right before your block command
(if (setq en (entnext LastEnt))
  (while en
    (ssadd en SS)
    (setq en (entnext en))
  )
)
(vl-cmdf "_.Block" blkname "_non" PT1 SS "")

 

random block naming here

Edited by mhupp
Link to comment
Share on other sites

Thank you for your quick response! What you gave me works but having trouble making it work with the rest of my routine, so I tried to modify it.  I originally used the variables pt1 through pt4 (the four corners of the rectangle) as given points to create various lines as my routine runs. Trying to keep them in place as the four corner points.  I tried this modification but didn't get it to work yet.

 

  (vl-load-com)
  (setq l (rtos (getdist "\nRectangle Lenght: ")2 0))
  (setq w (rtos (getdist "\nRectangle Width: ")2 0))
  (if (setq pt1 (getpoint "\nPick Bottom Left Corner: "))
    ;(command "_.Rectangle" pt1 (strcat "@" l "," w))
  )
  ;or caculate pt3
  (setq pt3 (list (+ (car pt1) l) (+ (cadr pt1) w)))
  (command "_.Rectangle" pt1 pt3)
  (setq myrecarea (vla-get-area (vlax-ename->vla-object (entlast)))) 
  (setq pt2 (list (car pt1) (cadr pt3)))
  (setq pt4 (list (car pt3) (cadr pt1)))

 

Any idea how to keep my variables pt1, pt2, pt3, pt4 as the four corners of the rectangle? If I can do that,  I think the rest of the routine should run just fine...

Note: I changed your pt2 into pt3 and put back in my old code to get the other corners and have all four variables pt1, pt2, pt3, pt4..

I guess I'm not doing something right...

 

Thanks!

 

Link to comment
Share on other sites

  
  (vl-load-com) ;not needed if you dont use vla-get-zrea
  (setq l (getdist "\nRectangle Lenght: ")) ;have to remove rtos to keep them integers so they can be used to calculate pt3
  (setq w (getdist "\nRectangle Width: "))  ;getdist allows for 2' if you used getint you would have to input 24
  (if (setq pt1 (getpoint "\nPick Bottom Left Corner: "))
    (setq pt3 (list (+ (car pt1) l) (+ (cadr pt1) w)))
    (setq pt2 (list (car pt3) (cadr pt1)))
    (setq pt4 (list (car pt1) (cadr pt3))) 
  )
  (command "_.Rectangle" pt1 pt3)
  (setq myrecarea (vla-get-area (vlax-ename->vla-object (entlast)))) 
  ;or (setq myrecarea (* l w)) ;dont have to calculate length and width user already defined them
  ;like (setq myrecarea (* mylength mywidth)); Get area of rectangle (length x width)
)

 

their isnt a need for the four points. but if you want it here thy are.

Link to comment
Share on other sites

My take using mhupp code. Make sure Multi getvals.lsp is in a support directory, if you dont know what that means post and will provide more info. 

 

image.png.0d3fb01cd9639a4db18defc4bfc799bf.png

 

(vl-load-com) ;not needed if you dont use vla-get-area

(if (not AH:getvalsm)(load "Multi Getvals.lsp"))
(setq ans (AH:getvalsm (list "Enter values " "Length " 5 4 "10" "Width " 5 4 "5")))
(setq l (atoi (car ans)) W (atoi (cadr ans)))

;  (setq l (getdist "\nRectangle Lenght: ")) ;have to remove rtos to keep them integers so they can be used to calculate pt3
;  (setq w (getdist "\nRectangle Width: "))  ;getdist allows for 2' if you used getint you would have to input 24

(if (setq pt1 (getpoint "\nPick Bottom Left Corner: "))
   (setq pt3 (list (+ (car pt1) l) (+ (cadr pt1) w))
    pt2 (list (car pt3) (cadr pt1))
    pt4 (list (car pt1) (cadr pt3)))
)
  
(command "_.Rectangle" pt1 pt3)
  
(setq myrecarea (vla-get-area (vlax-ename->vla-object (entlast)))) 
;or (setq myrecarea (* l w)) ;dont have to calculate length and width user already defined them

 

Multi GETVALS.lsp

 

 

 

 

  • Like 1
Link to comment
Share on other sites

Thanks to all! I'll work on these solutions above and see where I can get.

 

I did get some code from Devitg in another forum and he gave me this to try:

  (VL-LOAD-COM)
  (VL-CMDF "rectangle" pause pause "")
  (setq rectangle-obj (VLAX-ENAME->VLA-OBJECT (entlast)))
  (VLA-GETBOUNDINGBOX rectangle-obj 'dl 'ur)
  (setq pt1 (VLAX-SAFEARRAY->LIST dl))
  (setq pt3 (VLAX-SAFEARRAY->LIST ur))

 

It seems to work. I'm just needing pt2 and pt4 to complete all four corners of the rectangle but haven't gotten the various iterations I've tried to work yet. I keep getting errors unfortunately. I need all four points (pt1, pt2, pt3, pt4) since my routine uses them to build everything off of. Will keep trying though.

 

Lots of great code from everyone and its very much appreciated!

 

Thanks guys!

Link to comment
Share on other sites

Have you considered drawing RECTANGLE and then use (entget (entlast)) combo?

 

(defun c:myrect ( / el recx plucs pl )
  (setq el (entlast))
  (vl-cmdf "_.RECTANGLE" "\\" "\\") ;;; last "" were not good where you used RECTANGLE command call - here removed ;;; mod. M.R. ;;;
  (while (< 0 (getvar 'cmdactive))  ;;; this snippet needed, just in case ^^^ statement wrongly percepted ;;;
    (vl-cmdf "")
  )
  (if (not (eq el (setq el (entlast))))
    (progn
      (setq recx (entget el))
      (setq plucs (mapcar '(lambda ( p ) (trans (list (car p) (cadr p) (cdr (assoc 38 recx))) el 1)) (mapcar 'cdr (vl-remove-if '(lambda ( x ) (/= (car x) 10)) recx))))
      (mapcar 'set (setq pl (list 'p1 'p2 'p3 'p4)) plucs)
      (mapcar '(lambda ( x ) (prompt "\n") (prompt (vl-princ-to-string x)) (prompt " = ") (princ (eval x))) pl)
      (prompt "\n")
      (prompt "\nGlobal variables referencing rectangle corner points generated...")
      (prompt "\nArea = ") (princ (rtos (* (distance p1 p2) (distance p2 p3)) 2 20))
    )
  )
  (princ)
)

 

 

Link to comment
Share on other sites

Sorry for the late reply. Thank you everyone for all your input and I will work on these solutions...

🙂

 

Thanks!

 

 

Link to comment
Share on other sites

Hey Everyone

For the "rectangle" part, I tried this code below written by Ken1Cooper and it seems to work for what I need. Not fully tested yet but so far so good...

 

(defun C:RSCP () ; = Rectangle, Save Corner Points

    (command-s "_.rectang"); [must be without Fillet or Chamfer options]

    (setq

        pt1 (vlax-curve-getPointAtParam (entlast) 0)

        pt2 (vlax-curve-getPointAtParam (entlast) 1)

        pt3 (vlax-curve-getPointAtParam (entlast) 2)

        pt4 (vlax-curve-getPointAtParam (entlast) 3)

    ); setq

    (princ)

); defun

 

If the tests work, I will try to tackle the various blocking solutions posted and see what I can do on that part next..

Thanks to everyone for all your help!!!

Link to comment
Share on other sites

???   so draw a rectang 

 

(setq co-ord (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget (entlast)))))

 

1st point (nth 0 co-ord)

2nd point (nth 1 co-ord)

3rd point (nth 2 co-ord)

4th point (nth 3 co-ord)

Link to comment
Share on other sites

6 hours ago, BIGAL said:

???   so draw a rectang 

 

(setq co-ord (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget (entlast)))))

 

1st point (nth 0 co-ord)

2nd point (nth 1 co-ord)

3rd point (nth 2 co-ord)

4th point (nth 3 co-ord)

Also

(setq co-ord (mapcar 'cdr (vl-remove-if '(lambda (x) (/= (car x) 10)) (entget (entlast)))))

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...