Jump to content

Create a object in an Rectang


RBrigido

Recommended Posts

I'm trying to create a lisp routine that gives me the bottom left corner of a rectangle as a base, and then creates a circle at that point.

 

I tried in several ways but I can't perform this act. I tried to search for a rectangle by its coordinates, but I only get the coordinates of the point where the rectangle was created, not by the lower left corner.

 

 

Quote

(defun c:xaa ()
  (setq sel (car (entsel "\nSelect an object: "))) ; Prompt for selecting an object
  (setq obj (vlax-ename->vla-object sel)) ; Get the selected object
  (setq point (vlax-curve-getclosestpointto obj (vlax-curve-getstartpoint obj))) ; Get the starting point of the object
  (setq x (rtos (car point))) ; Convert the X coordinate to a string
  (setq y (rtos (cadr point))) ; Convert the Y coordinate to a string
  (setq z (rtos (caddr point))) ; Convert the Z coordinate to a string
  (princ (strcat "The coordinates of the selected object are: \nX: " x "\nY: " y "\nZ: " z))
  (princ)
)

 

Can anyone give me a light?

Link to comment
Share on other sites

Try this:

I think the hints are:

Use (entget.....) to get the rectangle entity description rather than vla- methods, and then get the coordinates from that (loads of examples for both online)

Sort the vertices up and down (or left and right) and then again in the other direction. This is for the case that the rectangle isn't aligned to the UCS, else just take the smallest values for X and Y from all 4 points.

 

This would also work OK for triangles, but for more sides I think you would need to define what is the lower left corner better as the shape rotates.

 

 

(defun RectanglePoints ( / MyEnt MyVert LowerVrtx UpperVrtx SortVert SortHor )

;Get user to select rectangle. Could do ssget and apply polyline filter + E, N
  (setq MyEnt (entget (car (entsel "Select Rectangle"))))

;Get the vertices of the polyline
  (setq MyVrtx (mapcar 'cdr (vl-remove-if-not '(lambda (x) (vl-position (car x) '(10 11))) MyEnt)))

;Check it is a rectangle
  (if (= (length MyVrtx) 4)
    (progn

;Sort vertices / split into upper and lower,
;;https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/sort-a-list-of-points/td-p/2560085
      (setq SortVert (vl-sort MyVrtx '(lambda(pt1 pt2) (< (cadr pt1) (cadr pt2)))))
      (setq LowerVrtx (list (nth 0 SortVert) (nth 1 SortVert)))
      (setq UpperVrtx (list (nth 2 SortVert) (nth 3 SortVert)))

;Sort upper and lower by left & right, create a single list of all vertices
      (setq SortHor (append (vl-sort LowerVrtx '(lambda(pt1 pt2) (< (car pt1) (car pt2)))) (vl-sort UpperVrtx '(lambda(pt1 pt2) (< (car pt1) (car pt2)))) ))

;List the vertices
;;Choose the corner you want. Nth x to make all 4 consistent rather than car, cdr.....
      (nth 0 SortHor) ;Lower Left
      (nth 1 SortHor) ;Lower Right
      (nth 2 SortHor) ;Upper Left
      (nth 3 SortHor) ;Upper Right

(setq Return (nth 0 SortHor) )

    ) ; end progn
    (progn
      (princ "Selection is not 4 sided object. ")
(setq Return (cdr (assoc 10 MyEnt))) ; return 1st point of the selected entity instead ; returning something just to stop future errors maybe
    )
  ) ; end if vrtx length = 4
  
)

 

Edited by Steven P
Link to comment
Share on other sites

Have a look at this link: https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/rectangle-corner-points/td-p/9501488

 

It stores it in *pts* but you can modify the function to where it only gives you the least value in the list. 

Maybe do a vl-sort function to the output.

 

I'd do something like:

(setq test1 *pts*)
(setq test2 (vl-sort test1 '(lambda (e1 e2) (< (car e1) (car e2)))))
(setq test3 (vl-sort test2 '(lambda (e1 e2) (< (cadr e1)(cadr e2)))))

(setq lower-left-point (car test3)

It would basically give you the lowest x and y value from the list.

Link to comment
Share on other sites

Hi guys,

 

I'm coming back here to say that I found a solution for my issue.

 

Quote

(defun c:xaa ()
  (setq ent (car (nentsel "\nSelect a viewport: ")))

        (setq center (cdr (assoc 10 (entget ent))))
        (setq width (/ (cdr (assoc 40 (entget ent))) 2.0))
        (setq height (/ (cdr (assoc 41 (entget ent))) 2.0))
        (setq pt1 (- (car center) width))
        (setq pt2 (- (cadr center) height))
        (setq pt1-offset (+ pt1 22))
        (setq pt2-offset (+ pt2 22))
  
        (setq point (list pt1-offset pt2-offset 0.0))
        (command "_POINT" point)

  (princ)

 

 

In this case:
 

  • (setq ent (car (nentsel "\nSelect a viewport: "))) - This line prompts the user to select a viewport and stores the selected entity in the variable ent. The function nentsel is used to get a user selection of an entity.
  • (setq center (cdr (assoc 10 (entget ent)))) - Here, the entget function is used to retrieve a list of attributes for the selected entity (ent). Then, the assoc function is used to find the attribute with code 10, which represents the center of the viewport. The center coordinate is stored in the variable center.
  • (setq width (/ (cdr (assoc 40 (entget ent))) 2.0)) - Here, the attribute with code 40 is obtained to determine the width of the selected viewport. The value is divided by 2.0 and stored in the variable width.
  • (setq height (/ (cdr (assoc 41 (entget ent))) 2.0)) - Similarly, the attribute with code 41 is obtained to determine the height of the selected viewport. The value is divided by 2.0 and stored in the variable height.
  • (setq pt1 (- (car center) width)) - It calculates the X coordinate of the top-left point of the viewport by subtracting half of the width (width) from the X coordinate of the center (car center).
  • (setq pt2 (- (cadr center) height)) - It calculates the Y coordinate of the top-left point of the viewport by subtracting half of the height (height) from the Y coordinate of the center (cadr center).
  • (setq pt1-offset (+ pt1 22)) - It adds an offset of 22 units to the calculated X coordinate (pt1) to create a rightward offset.
  • (setq pt2-offset (+ pt2 22)) - It adds an offset of 22 units to the calculated Y coordinate (pt2) to create an upward offset.
  • (setq point (list pt1-offset pt2-offset 0.0)) - It creates a list containing the X, Y, and Z coordinates of the point to be created. The Z value is set to 0.0.
  • (command "_POINT" point) - It executes the "_POINT" command in AutoCAD, creating a point at the specified coordinates given by the point list.

In my head, I will use that code to insert a Scale Bar. What will be great to use a standard displacement on the corner.

 

I hope it could be useful to someone else.

 

Many thanks

Rodrigo Brigido.

  • Like 1
Link to comment
Share on other sites

Just a comment to avoid confusion in the future.... solutions above were as the question, selecting a Rectangle lower left coordinate, where the OP eventually wanted to select a viewport -lower left coordinate which requires a slightly different solution, which is the solution they suggest at the end.

 

Thanks for posting what you found - useful

Link to comment
Share on other sites

This is what I used to show Viewport in Model space.

 

--Edit

"Use to" I Work with Solidworks now.

 

;;----------------------------------------------------------------------------;;
;; Creates Viewport outline and moves it to Model space
(defun C:VP2M (/ SS vp elist MiscOn cen c40 c41 LL UR)
  (vl-load-com)
  (if (setq SS (ssget "_X" (list '(0 . "viewport") (cons 410 (getvar 'ctab)))))
    (foreach vp (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS)))
      (setq elist (entget vp))
      (if (> (cdr (assoc '69 elist)) 1)           ; skip display viewport
        (progn
          (if (= (cdr (assoc '68 elist)) 0)       ; is viewport active?
            (progn
              (setq MiscOn 'NO)
              (vl-cmdf "._Mview" "_on" "_si" vp)  ; activate viewport
            )
            (setq MiscOn 'YES)
          )
          (setq cen (cdr (assoc '10 elist))
                c40 (cdr (assoc '40 elist))       ;length
                c41 (cdr (assoc '41 elist))       ;width
                LL (list (- (car cen) (/ c40 2)) (- (cadr cen) (/ c41 2)))
                UR (list (+ (car cen) (/ c40 2)) (+ (cadr cen) (/ c41 2)))
          )
          (vl-cmdf "_.Pspace")
          (vl-cmdf "_.Rectangle" LL UR)
          (vl-cmdf "_.Chspace" "_Last" "")
          (vl-cmdf "_.Pspace")
          (if (eq MiscOn 'NO)
            (vl-cmdf "_.Mview" "_off" "_si" vp)   ; deactivate viewport
          )
        )
      )
    )
  )
  ;(setvar 'Tilemode 1) ;switch to model space
  (princ)
)

 

Edited by mhupp
  • Like 1
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...