CivilTechSource Posted Monday at 12:13 PM Posted Monday at 12:13 PM Hi, This might have been resolved before. But has anyone wrote a lisp or function that calculates the text anchor point based on the rotation of the text? Currently I have a lisp that will prompt the user to select FFL and then will calculate 150mm drop and prompt the user to select point to insert the text and second point to specify angle. I want to push it a step further and add a function to calculate the correct text anchor point which this should be done using the angle (i.e. if pt1X > pt2X & pt1Y>pt2Y then MtextJustify=BottomLeft). I appreciate that when Angle is 0 or 180 the justification in regards to Top & Bottom (Ignoring Left or Right) cannot be calculate due to the angle being zero, which I dont mind. See Lisp code below (defun c:LE-CalExtFFL (/ ffl-ent ffl-obj ffl-text ffl-value new-level pt-list pt user-input) ;;Set Layer (command "_layer" "_m" "-LE-E-External Levels" "") ;; Function to extract numeric value from FFL text (defun extract-ffl-value (text-string / clean-text) ;; Remove first 5 characters from the string (if (> (strlen text-string) 5) (setq clean-text (substr text-string 6)) (setq clean-text text-string) ) ;; Extract the numeric value (if (numberp (read clean-text)) (read clean-text) (progn (princ "\nError: Could not extract numeric value from FFL text.") nil ) ) ) ;; Function to create MText at specified point (defun create-level-mtext (point level-value rot / mtext-obj) ;Calculate Attachment Point based on rotation ;Place Text (setq mtext-obj (entmakex (list (cons 0 "MTEXT") (cons 100 "AcDbEntity") (cons 8 (getvar "CLAYER")) ; Current layer (cons 100 "AcDbMText") (cons 10 point) ; Insertion point (cons 40 0.5) ; Text height (adjust as needed) (cons 41 0.0) ; Reference rectangle width (cons 71 1) ; Attachment point (top left) (cons 72 5) ; Drawing direction (cons 1 (strcat "+" (rtos level-value 2 3))) ; Text content with "+" prefix (cons 50 rot) ; Rotation angle ) ) ) mtext-obj ) ;;Main program starts here------------------------------------------ ;; Prompt user to select FFL MText (princ "\nSelect the MText containing the FFL (Finished Floor Level): ") (setq ffl-ent (car (entsel))) ;; Check if a valid MText was selected (if (and ffl-ent (= (cdr (assoc 0 (entget ffl-ent))) "MTEXT")) (progn ;; Get the MText object and extract text content (setq ffl-obj (entget ffl-ent)) (setq ffl-text (cdr (assoc 1 ffl-obj))) (princ (strcat "\nFFL Text found: " ffl-text)) ;; Extract the FFL numeric value (setq ffl-value (extract-ffl-value ffl-text)) (if ffl-value (progn (setq new-level (- ffl-value 0.15)) ;; Initialize point list (setq pt-list '()) ;; Prompt for points where to place the new MText (princ "\nSelect points where to place the level text (Press Enter to finish): ") ;; Loop to collect points (while (setq pt (getpoint "\nPick point for level text (or press Enter to finish): ")) (setq pt-list (append pt-list (list pt))) (setq rotation (getangle pt "\nSpecify rotation angle for text (or press Enter for 0 degrees): ")) (if (not rotation) (setq rotation 0.0)) (create-level-mtext pt new-level rotation) ) ) (princ "\nCould not extract FFL value from the selected text.") ) ) (princ "\nError: Please select a valid MText object containing FFL information.") ) (princ) ; Clean exit ) CTS-Example Anchor Point.dwg Quote
mhupp Posted Monday at 07:59 PM Posted Monday at 07:59 PM (edited) This would create a text with top left just if the rotation angle is between 0 and 180 else it will be Bottom left. (defun create-level-mtext (pt1 rot / mtext-obj) (if (and rot (> rot 0) (< rot pi)) ;check rotation angle (setq x 1) (Setq x 7) ) (setq mtext-obj (entmakex (list (cons 0 "MTEXT") (cons 100 "AcDbEntity") (cons 8 (getvar "CLAYER")) ; Current layer (cons 100 "AcDbMText") (cons 10 pt1) ; Insertion point (cons 40 0.5) ; Text height (adjust as needed) (cons 41 0.0) ; Reference rectangle width (cons 71 x) ; Attachment point (Top Left) (cons 72 5) ; Drawing direction (cons 1 (strcat "+" (rtos level-value 2 3))) ; Text content with "+" prefix (cons 50 rot) ; Rotation angle ) ) ) mtext-obj ) Edited 17 hours ago by mhupp Quote
BlackBox Posted Monday at 11:03 PM Posted Monday at 11:03 PM 3 hours ago, mhupp said: This would create a text with top left just if the rotation angle is between 0 and 180 else it will be Bottom left. (defun create-level-mtext (pt1 rot / mtext-obj) (if (and rot (> rot 0) (< rot pi) ;check rotation angle (setq x 1) (Setq x 7) ) (setq mtext-obj (entmakex (list (cons 0 "MTEXT") (cons 100 "AcDbEntity") (cons 8 (getvar "CLAYER")) ; Current layer (cons 100 "AcDbMText") (cons 10 pt1) ; Insertion point (cons 40 0.5) ; Text height (adjust as needed) (cons 41 0.0) ; Reference rectangle width (cons 71 x) ; Attachment point (Top Left) (cons 72 5) ; Drawing direction (cons 1 (strcat "+" (rtos level-value 2 3))) ; Text content with "+" prefix (cons 50 rot) ; Rotation angle ) ) ) mtext-obj ) After you account for '; error: too few arguments:'... Might also consider a single < comparer for limiting this to positive X quadrants, a neither 0 or pi check for all quadrants, etc: (if (and rot (< 0 rot pi)) ;check rotation angle (setq x 1) (setq x 7) ) (if (and rot (/= 0 rot) (/= pi rot)) ;check rotation angle (setq x 1) (setq x 7) ) (setq x (if (and rot (/= 0 rot) (/= pi rot)) ;check rotation angle 1 7 ) ) 1 Quote
mhupp Posted 17 hours ago Posted 17 hours ago Don't have cad anymore to test this things and cant remember if you could throw an if statement inside the entmakex function. Quote
BlackBox Posted 17 hours ago Posted 17 hours ago 2 minutes ago, mhupp said: Don't have cad anymore to test this things and cant remember if you could throw an if statement inside the entmakex function. Sorry to hear that; I didn't know. Agree it's better to test if you have the data needed before entmake* functions. If you're wanting to get CAD back, consider joining AUGI as Pro members get a free ADN (Autodesk Developer Network) membership, which would give you any Autodesk product to use for development. https://www.augi.com/adn-membership-offer Cheers 1 Quote
GLAVCVS Posted 12 hours ago Posted 12 hours ago Hi I'm having trouble reconciling my understanding of your question with what I see in the example drawing. The square: doesn't it also play a role in determining the text justification? That is to say: if you select the upper right corner of the square and then specify a horizontal angle to the left, the justification should be bottom right. However, if you do the same thing starting from the lower right corner of the square, the MTEXT justification should be top right. Therefore, the idea seems to be that the MTEXT should always be positioned outside the square. Is this correct? In this case, the MTEXT angle criterion alone is not sufficient; it's also necessary to consider the object to which it refers. If all of this is correct, we would need to write a function that analyzes the geometry of the object the MTEXT refers to and determines the justification, taking the angle into account as well. 1 Quote
CivilTechSource Posted 3 hours ago Author Posted 3 hours ago @GLAVCVS You are absolutely correct. Ideally the user will select the polyline which represents a house and we calculate to place the text outside. However, we do not always get the building outline from the architects as a single polyline and I do not wish to spent time creating that polyline (for now). So I am focusing on at least having the correct Left/Right justification.... Unless I use something similar to LeeMacs Text Alignment Controls https://www.lee-mac.com/curvealignedtext.html . But at the moment this is slightly over my head for now. However, we could solve this issue without taking in consideration of geometry and take a similar approach to how you set the UCS, by selecting 3 points. p1-TextPlacement p2-Text Left & Right Justification based on p1 p3-Text Top & Right Justification based on p1 & p2 Would that work? Quote
GLAVCVS Posted 2 hours ago Posted 2 hours ago (edited) Even if you create MTEXT objects without referencing any other object, they will still have some kind of arbitrary geometry. You could establish a rule that the perimeter points are always entered in a clockwise order This would allow the code to have the necessary criteria to determine what is inside and outside the perimeter. Additionally, the code could dynamically draw a perimeter based on each insertion point specified by the user. As a convention for these temporary perimeters, you could assign them a specific, distinct color. All of this could later allow you to write code for another command that manages these perimeters and their associated MTEXT objects, and then replaces them with the final, definitive version. Edited 2 hours ago by GLAVCVS Quote
Recommended Posts
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.