Jump to content

Looking for some AutoLISP help - creating a new routine


Recommended Posts

Posted

I'm somewhat new to writing my own routines, but have 25 years with AutoCAD. I'm looking to accomplish the following with a routine and I don't know where to start:

  1. Select two points to create a rectangle in memory - this rectangle shall not be drawn or printed, or should be erased after execution of the command
  2. Extract the width and height of the rectangle
  3. Add a user defined distance/dimension to the width and height of the rectangle - same number for both with and height
  4. Display the new width/height as mtext in the middle of the two points selected in step 1 in the format of, say xx x/x" x yy y/y"
    1. the reason for mtext is because I want the result to show stacked fractions. Fields do not allow for stacking fractions

Any thoughts or ideas are greatly appreciated. Thank you.

Posted (edited)
(defun c:rectdim ( / pt1 pt2 width height delta new-width new-height midpt mtext-string)
  ;; Step 1: Select two points
  (setq pt1 (getpoint "\nSelect first corner: "))
  (setq pt2 (getpoint pt1 "\nSelect opposite corner: "))

  ;; Step 2: Extract the width and height
  (setq width (abs (- (car pt2) (car pt1))))
  (setq height (abs (- (cadr pt2) (cadr pt1))))

  ;; Step 3: Add a user-defined distance
  (setq delta (getreal "\nEnter the distance to add to both width and height: "))
  (setq new-width (+ width delta))
  (setq new-height (+ height delta))

  ;; Calculate the middle point
  (setq midpt (list (/ (+ (car pt1) (car pt2)) 2) (/ (+ (cadr pt1) (cadr pt2)) 2)))

  ;; Step 4: Create the MText string
  (setq mtext-string (strcat (rtos new-width 2 2) " x " (rtos new-height 2 2)))

  ;; Create MText
  (entmake
    (list
      (cons 0 "MTEXT")
      (cons 10 midpt)
      (cons 40 2.5) ;; Height of text
      (cons 1 mtext-string)
      (cons 7 "Standard")
      (cons 71 1)
      (cons 72 1)
    )
  )
  ;; Erase the rectangle (if drawn for reference)
  ;; Optionally you can add code here to draw and then erase the rectangle if necessary

  (princ)
)

 

Edited by SLW210
Added Code Tags!!
Posted

Started to give you some pointers, but elidon has already done the heavy lifting. I assume he's correct that the new rectangle is even spaced on all sides from the original.

 

I would only add that you need to be careful about your UCS. You can't always assume the user is in World Coordinates, if that's where your label is going. Keep an eye on other system variables as well, users are tricky that way. You can always save the current state of a variable and restore it when you're done.

Posted

Thank you so much for writing that out, I'm digesting it now. It appears the routine completes without showing the mtext. After entering a distance to add, the command completes with no text.

Posted (edited)

Generating a multitext entity from DXF codes is harder than it looks. These are the codes that worked for me:

(0 . "MTEXT")  (100 . "AcDbEntity") (8 . <layer>) (100 . "AcDbMtext") (10 . <location>) (40 . <height>) (71 . <justification>) (1 . <contents>) (7 . <style>)

(50 . 0) (90 . 3) (63 . 256) (45 . 1.1) (441 . 0)

 

These codes may not give you exactly what you need, but they should give you a valid entity. This one has a border with a background color fill. Here is some exhaustive info about multitexts, and the first link on that page will give you the DXF codes and what they mean.

 

Edit: To clarify, the only item that needs a code is the justification. The others are values you'd expect to provide, e.g. text height.

Edited by CyberAngel
Posted
1 hour ago, CyberAngel said:

Generating a multitext entity from DXF codes is harder than it looks. These are the codes that worked for me:

(0 . "MTEXT")  (100 . "AcDbEntity") (8 . <layer>) (100 . "AcDbMtext") (10 . <location>) (40 . <height>) (71 . <justification>) (1 . <contents>) (7 . <style>)

(50 . 0) (90 . 3) (63 . 256) (45 . 1.1) (441 . 0)

 

These codes may not give you exactly what you need, but they should give you a valid entity. This one has a border with a background color fill. Here is some exhaustive info about multitexts, and the first link on that page will give you the DXF codes and what they mean.

 

Using ChatGPT and the above information, this almost works, I just need the decimals to convert to stacked fractions if possible.

 

(defun c:rectdims ()
  (setq p1 nil
        p2 nil
        width 0.0
        height 0.0
        added-dim 0.0
        new-width 0.0
        new-height 0.0
        mid-point nil
        text-string ""
        rotation-angle (* 45.0 (/ pi 180.0)) ; Rotation angle in radians
        text-height 2.25                     ; Text height in inches
        )

  (prompt "\nSelect two points to define the rectangle: ")

  (while (not (and p1 p2))
    (setq p1 (getpoint "\nSelect first point: "))
    (setq p2 (getpoint "\nSelect second point: ")))

  ; Calculate width and height
  (setq width (abs (- (car p2) (car p1)))
        height (abs (- (cadr p2) (cadr p1))))

  ; Ask for user-defined dimension to add
  (setq added-dim (getreal "\nEnter dimension to add (in inches): "))

  ; Calculate new dimensions
  (setq new-width (+ width added-dim)
        new-height (+ height added-dim))

  ; Calculate midpoint
  (setq mid-point (list (/ (+ (car p1) (car p2)) 2.0)
                        (/ (+ (cadr p1) (cadr p2)) 2.0)
                        0.0))  ; Z-coordinate (0.0 for 2D)

  ; Format the text to display with stacked fractions
  (setq text-string (strcat
                     "" (rtos new-width 2 2) "\"x" ; Format width with stacked fraction
                     "" (rtos new-height 2 2) "\"" ; Format height with stacked fraction
                     ))

  ; Start a new command session
  (command "_UNDO" "_BEGIN")

  ; Create MTEXT entity using entmake
  (setq mtext-entity
        (entmake
         (list
          '(0 . "MTEXT")
          '(100 . "AcDbEntity")
          '(8 . "0") ; Change to desired layer name or use current layer
          '(100 . "AcDbMText")
          (cons 10 mid-point) ; Insertion point
          (cons 40 text-height) ; Text height
          (cons 1 text-string) ; Text contents
          '(7 . "Century Gothic") ; Text style, change if needed
          (cons 50 rotation-angle) ; Text rotation angle
          '(71 . 5) ; Justification: middle center (1)
          )))

  ; End the command session and erase temporary objects
  (command "_UNDO" "_END")

  (princ)
)

 

Posted

Okay, there's a system variable MTEXTAUTOSTACK, which you can store, turn on when the function starts, and restore when you're done.

Posted

My $0.05

 

(setq p2 (getpoint p1 "\nSelect second point: "))

(setq p2 (getcorner p1 "\nSelect second point: "))

 

  • Like 1
Posted (edited)

@70melbatoast FWIW

 

You can also calculate width and height like so:

(mapcar 'abs (mapcar '- p1 p2))

And the 2D midpoint:

(mapcar '/ (mapcar '+ p1 p2) '(2 2))

 

Edited by ronjonp

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...