robertbon 发表于 2022-7-5 19:11:43

That works perfectly, thanks for your help and explanations guys.

Happy Hobbit 发表于 2022-7-5 19:14:13

 
I'm looking to create a similar lisp to the above which inserts a pre-defined mtext string at a given coordinates to use within a separate lisp that I a developing. The mtext will be zero width, text height 2, justified ml & a rotation of zero. This is what I have so far, but I'm stuck :-(
 

(defun c:insmtx ( / a b pt width words )(Setq width 0) (setq pt (getpoint " 0.0 ")) (setq a "Bacon &") (setq b "Eggs")(setq words (strcat "A \n" "B")) (command "mtext" pt "h" "2" "j" "ml" "R" "0" "S" "STANDARD" "W" width pause "" "" words ""))
 
Btw I don't really want to insert 'bacon & eggs' into my drawing
- Humble Harry

Lee Mac 发表于 2022-7-5 19:17:54

A couple of points to note:
 


[*]Use a conditional expression (if / cond) to test whether the getpoint expression returns a valid point, else, if the user presses Enter or right-clicks at the prompt, getpoint will return nil but the program will still continue (and will likely error).

 


[*]The expression (strcat "A \n" "B") is concatenating two literal strings, and will simply return the string "A \nB". If you are looking to concatenate the two variables defined earlier in the code, these will need to appear outside of any quotation marks, i.e. (strcat a " \n" b)

 


[*]Some AutoCAD commands can be reliably called from AutoLISP (and sometimes there is no other option), however, certain commands can have unpredictable command prompts (such as the MLEADER command), and so I would suggest using entmake/entmakex or a Visual LISP method where possible.

 
Here are my suggestions for your code:

(defun c:insmtx ( / ins )   ;; Define function, declare local variables   (if ;; If the following expression returns a non-nil value       (setq ins ;; Bound the value returned by the following expression to the 'ins' symbol and return this value         (getpoint "\nSpecify insertion point: ") ;; Prompt the user to specify an insertion point for the MText       ) ;; end setq       (entmake ;; Append the following DXF data to the drawing database         (list ;; Construct a list containing the following DXF data            '(000 . "MTEXT")          ;; Entity type            '(100 . "AcDbEntity")   ;; Subclass marker            '(100 . "AcDbMText")      ;; Subclass marker               (cons 10 ins)            ;; Insertion point            '(001 . "Bacon & \nEggs") ;; Content            '(040 . 2.0)            ;; Height            '(071 . 4)                ;; Justification         ) ;; end list       ) ;; end entmake       ;; Else the user did not provide a valid point       (princ "\nNo insertion point given, goodbye.")   ) ;; end if   (princ) ;; Suppress the output of the value returned by the last evaluated expression) ;; end defun
Here is a DXF reference to help you to understand the meaning of each DXF group; and here is the reference for the MTEXT entity type.
 
There are other improvements which could be implemented to account for changes to the UCS, the above should at least provide a good starting point for a beginner.

Happy Hobbit 发表于 2022-7-5 19:22:24

Wow, I never thought it would have to be so complicated. Thank you very much Lee.
 
Please can you tell me how the resultant of a polar function – within the main lisp I am writing – could be incorporated into this code?
 
Say the resultant is 5,5 My guesstimate is that it would go in the getpoint statement.
Obviously the coordinate would be in a variable
Variable = myvar = 5,5
 
i.e

(getpoint myvar)
 
By the way, is your name actually an acronym for ‘Lisps Excellent Examples Made Always Cleverly’? :-)

Lee Mac 发表于 2022-7-5 19:23:44

 
It doesn't have to be, but then it also doesn't have to be robust... the above may initially look daunting, but is relatively simple when studied.
 
 
You're most welcome.
 
 
The getpoint function is used to prompt the user to specify a point; this function will then return the given point, or nil if the user presses enter or right-clicks at the prompt.
 
If you already have the insertion point (i.e. a list of two or three numerical values), you needn't use the getpoint function (as there is no need to prompt the user), but instead you can simply supply the point as the DXF group 10 value within the list supplied to entmake.
 
The optional point argument for getpoint will cause a 'rubber-band' to be displayed between the cursor and the given point (as a visual aid for the user when specifying a point which relates to another point).
 
 
Haha! Very good

Happy Hobbit 发表于 2022-7-5 19:27:39

Thank you very much indeed Lee, you've helped me learn at lot
 
I've sussed it I think. I created a polar function to vaguely mimic the one(s) in the main code
 

(setq ins (polar '(1 1) 0.785398 1.414214))
 
Which gives 2.0 2.0
 
Then put in:
 

(cons 10 ins)
 
voila! The text is at 2,2

Lee Mac 发表于 2022-7-5 19:29:52

You're welcome Harry.
 
Of course, if the insertion point is a fixed coordinate, the DXF group 10 can be represented as a literal expression, e.g.:

'(10 2.0 2.0 0.0)(More information about this here)
 
Alternatively, you can calculate the new position more cleanly using mapcar, e.g.:

(cons 10 (mapcar '+ '(1.0 1.0) '(1.0 1.0)))Of course, given that all data is known in the above example, the above expression is redundant, but I assume that you are obtaining the initial point through other means.

Happy Hobbit 发表于 2022-7-5 19:34:49

Sorry about the delay in replying, I've been away for a few days.
 
Unfortunately the coordinates aren’t fixed but vary according to where the entity being draw is placed.
 
I’ve got around that by referencing a part of the new entity (a) then offsetting the mtext with polar:
 

(setq a-ins (polar a pi 1))
 
Then using ‘a-ins’ for the insertion point for the mtext
 
It works although it’s a little scruffy

Lee Mac 发表于 2022-7-5 19:38:21

 
There are many ways to achieve the same result in AutoLISP, and that's not too scruffy at all!
 
If you are using the a-ins variable only once, you could omit it entirely and pass the result of the polar expression directly to the cons function, e.g.:

      (entmake ;; Append the following DXF data to the drawing database         (list ;; Construct a list containing the following DXF data            '(000 . "MTEXT")          ;; Entity type            '(100 . "AcDbEntity")   ;; Subclass marker            '(100 . "AcDbMText")      ;; Subclass marker               (cons 10 (polar a pi 1)) ;; Insertion point            '(001 . "Bacon & \nEggs") ;; Content            '(040 . 2.0)            ;; Height            '(071 . 4)                ;; Justification         ) ;; end list       ) ;; end entmake
 
Other ways to calculate the new position could be:

(cons (1- (car a)) (cdr a))

(mapcar '- a '(1 0 0))
But polar is likely to be the cleanest in this case.

Happy Hobbit 发表于 2022-7-5 19:40:57

I like the following:
 

(cons 10 (polar a pi 1)) ;; Insertion point
 
I must admit I hadn't thought of that
 
It is only used once, so I'll try that.
 
Although I'm intrigued by the other two options, I'll have to look them up to understand them.
 
car = beginning of list (what list?)
 
cdr = end of list (what list?)
 
As for mapcar, forget it
页: 1 [2]
查看完整版本: Carriage return in lisp-create