View Full Version : distance and offset along a polyline
ccowgill
2006-05-25, 11:32 AM
I am trying to create a routine that will allow the user to select a polyline, and its start point, then have the lisp routine automate creating text that specifies the distance from the beginning of the polyline and the offset from the polyline of a point that contains an attribute. This part of the routine is the step prior to my other post on replacing text in a drawing, it is the step that will create the text.
If at all possible I would like to have the "X" coordinate of the text insert to be = to the distance from the start point, with a specific "y" coordinate and if the text will overlap, specify a minimum distance apart for the next text object.
The main points that I need help with is getting the information, and then actually creating the text object. I am not sure how to create something from nothing, the only thing up to this point that I have ever been able to do is edit something that already exists.
any help is greatly appreciated.
Hammer.John.J
2006-05-25, 11:47 AM
sounds like you are trying to do something like LDT does with alignments and station labels?
ccowgill
2006-05-25, 11:50 AM
that is exactly what I am trying to do, except I am using vanilla AutoCAD, we dont have LDT and as far as I know my office has no plans to leave Eagle Point. we have a program that does this already, but it doesn't work the way I would like it to. and it is written very poorly so I dont want to use any of it, I figured it would be easier to start from scratch.
Hammer.John.J
2006-05-25, 12:39 PM
sounds like you could do a modified measure command that will use the spacing you define to measure at, the distance and incrementally add that to every block suscinctly
ccowgill
2006-05-25, 12:44 PM
no, that wouldn't work, the points are already in the drawing and not specific distances from the start of the polyline, measure would be more for a set distance apart, as for the placement of the text, I will know the y coordinate, for x I would just use a logic test to determine if they are too close together
(if (< (- x1 x2) (* 0.5 Textheight))
(setq x2 (+ (* 0.5 Textheight) x1))
)
Hammer.John.J
2006-05-26, 11:48 AM
sounds like after all the few posts i've read from ya that you need civil 3d or ldt because it does all of this stuff you are doing through customization.
eagle point is ok for landscaping but thats about the only use i found for it.
ccowgill
2006-05-26, 12:16 PM
well, my company has no plans to switch, I would prefer that they would, so I have to deal with what I have. The program can be written, I just need to know how to collect the data I need, and create a text object.
well, my company has no plans to switch, I would prefer that they would, so I have to deal with what I have. The program can be written, I just need to know how to collect the data I need, and create a text object.
Here's a couple of posts for creating the text object. One is for MTEXT and the other for TEXT.
RE: Create MTEXT with Lisp
RE: Help with an "entmake" routine
Now all we need to do is collect the data. ;)
ccowgill
2006-05-26, 01:25 PM
I think the one for single text will work, I just need to adjust it for what I want, It is a good starting off point, hopefully someone will help out with the collection of the data part today, so I can try to get a working program by Tuesday, or at least more questions
CAB2k
2006-05-26, 02:28 PM
Chris,
Do you have pseudo code?
Do you have some code worked out?
Show us what you have so far.
In the learning stages you should, in my opinion, use this method.
Create pseudo code and add ;; for each line.
Then add the code segments to accomplish that task.
As you develop the routine the code will evolve & may change location.
That's ok, it's part of the process. Most of my first lisp were cut & paste of code I borrowed from other routines.
That's ok too, it's a way to use a working piece of code to get you started.
Turn your general request into pseudo code
I am trying to create a routine that will allow the user to select a
polyline, and its start point, then have the lisp routine automate creating text
that specifies the distance from the beginning of the polyline and the offset
from the polyline of a point that contains an attribute. This part of the
routine is the step prior to my other post on replacing text in a drawing, it is
the step that will create the text.
Select a polyline
Pick end point of ployline
Get distance from select point to pick point
Then be more specific about your goal
Select ONLY polyline
Pick end point of THE SELECTED ployline
Get distance ALONG THE POLYLINE from select point to pick point
These are important details that will clarify the goal of the routine.
I assume they are implied but we all have a different perspective of the problem.
(defun c:MyRoutine ()
;; Select ONLY polyline
;; Note, need to trap ENTER
(prompt "\nSelect a polyline.")
(setq ss (ssget "+.:E:S" '((0 . "LWPOLYLINE,POLYLINE"))))
(setq ename (ssname ss 0)))
;; Pick end point of THE SELECTED ployline
;; Note, need to trap ENTER and missed endpoint of matching pline
(setq pt (getpoint "\nPick the endpoint of the polyline."))
;; Get distance ALONG THE POLYLINE from select point to pick point
;; Note, use vlax-curve-getDistAtPoint but to use it we need to determine
;; if the picked point is the END or START of the pline
(princ)
)
Your turn. :)
ccowgill
2006-05-26, 02:45 PM
I am glad that some one else feels that is the important way to begin things, I am only going to post the part that is relative to this thread, you guys have already helped me out on other parts, and I already have parts that I knew how to write done.
;;;;;;;;;;;;;;;;;;;;;;;;;select polyline
(setq centerline (ssget ":S" '(( 0 . "*polyline"))))
;;;;;;;;;;;;;;;;;;;;;;;;;select beginning
(setq beginningpt (getpoint "nSelect Start Point"))
;;;;;;;;;;;;;;;;;;;;;;;;;select start station
(setq startsta (getint "nEnter Start Station"))
;;;;;;;;;;;;;;;;;;;;;;;;;select points
;;select blocks on only particular layers with particular names (use insert point)
;;;;;;;;;;;;;;;;;;;;;;;;;get station of point
;;;;;;;;;;;;;;;;;;;;;;;;;get offset of point
;;;;;;;;;;;;;;;;;place text starting at 0+00 on both sides at 0,0 with proper scale distances;;;
;;(VbaAddText "text" (list x y z) 4 4)
;;By John W Anstaett 10/13/05
;;This function add a text object to modelspace
;; myText = the text to use
;; myPoint = list of the point
;; myHight = the text hight
;; myJustification = the Alignment
;;Alignment
;;acAlignment enum; read-write
;;acAlignmentLeft = 0
;;acAlignmentCenter = 1
;;acAlignmentRight = 2
;;acAlignmentAligned = 3
;;acAlignmentMiddle = 4
;;acAlignmentFit = 5
;;acAlignmentTopLeft = 6
;;acAlignmentTopCenter = 7
;;acAlignmentTopRight = 8
;;acAlignmentMiddleLeft = 9
;;acAlignmentMiddleCenter = 10
;;acAlignmentMiddleRight = 11
;;acAlignmentBottomLeft = 12
;;acAlignmentBottomCenter = 13
;;acAlignmentBottomRight = 14
;; the function return the textobj as a vbaobject
;; so you can use make other change to the object
;;Exp:
;;(vla-put-layer myreturn "layername")
;;(vla-put-width myreturn 0.5)
;;(vla-put-textstyle myreturn "newstyle")
(vl-load-com)
;;This function loads the extended AutoLISP functions provided
;;with Visual LISP. The Visual LISP extensions implement ActiveX
;;and AutoCAD reactor support through AutoLISP, and also provide
;;ActiveX utility and data conversion functions, dictionary handling
;;functions, and curve measurement functions.
;;If the extensions are already loaded, vl-load-com does nothing
(defun VbaAddText (myText myPoint myHight MyJustification / acadObject acadDocument myss myas myc vlss)
(setq acadObject (vlax-get-acad-object));get Autocad object
(setq acadDocument (vla-get-ActiveDocument acadObject));get the Activedocument object
(setq acadModelSpace (VLA-GET-MODELSPACE acadDocument));get the modelspace block
(setq mytextObj (vla-addtext acadModelSpace mytext (vlax-3d-point myPoint) myhight));add text
(vla-put-Alignment mytextObj myJustification);set text Justification
(setq mytextObj myTextobj);retrun the text object
)
CAB2k
2006-05-26, 04:04 PM
Oh, good, you have a start on the project.
I'll help you with the distance part and perhaps someone else will fill in.
I have to get some work done today too. :)
;; no error checking at this time
(defun c:myroutine ()
;; Select ONLY polyline
;; Note, need to trap ENTER
(prompt "\nSelect a polyline.")
(setq ss (ssget "+.:E:S" '((0 . "LWPOLYLINE,POLYLINE"))))
(setq ename (ssnamex ss 0) ; look this function up in the help
selpt (last (last (car ename))) ; the pick point
ename (cadar ename) ; the entity name
)
;; Pick end point of THE SELECTED ployline
;; Note, need to trap ENTER and missed endpoint of matching pline
(setq pt (getpoint "\nPick the endpoint of the polyline."))
;; Get distance ALONG THE POLYLINE from select point to pick point
;; Note, use vlax-curve-getDistAtPoint but to use it we need to determine
;; if the picked point is the END or START of the pline
;; get the actual point on the pline for the select point
;; this assures that the point is ON the pline not next to it
(setq selpt (vlax-curve-getclosestpointto ename selpt))
;; get the actual point on the pline fot the picked point
;; and get the distance
(if (< (distance pt (vlax-curve-getstartpoint ename))
(distance pt (vlax-curve-getendpoint ename))
)
;; pt is START of pline
(setq pkpt (vlax-curve-getendpoint ename)
dist (vlax-curve-getdistatpoint ename selpt)
)
;; pt is END of pline
(setq pkpt (vlax-curve-getstartpoint ename)
;; (- <total length> <dist to selpt>)
dist (- (vlax-curve-getdistatpoint ename (vlax-curve-getEndPoint ename))
(vlax-curve-getdistatpoint ename selpt))
)
)
(princ)
)
ccowgill
2006-05-30, 11:45 AM
CAB, I'm sorry, I must not be understanding what your code actually does. it is probably simple, but I am not that familiar with vlax commands. I have posted the whole code that has to do with this part of my program, including all the modifications I made this weekend. Your code might be out of place as to how you intended it. on my parts of the program, I only have parts that I knew how to write, the station and offset areas still need the basic functions to determine the station and offset, I just coded how to convert the station to the text that I need displayed.
;;;;;;;;;;;;;;;;;;;;;;;;select polyline AND BEGINNING
;; no error checking at this time
(defun c:PLINESELECT ()
;; Select ONLY polyline
;; Note, need to trap ENTER
(prompt "nSelect a polyline.")
(setq ss (ssget "+.:E:S" '((0 . "*POLYLINE"))))
(setq ename (ssnamex ss 0) ; look this function up in the help
selpt (last (last (car ename))) ; the pick point
ename (cadar ename) ; the entity name
)
;; Pick end point of THE SELECTED ployline
;; Note, need to trap ENTER and missed endpoint of matching pline
(setq pt (getpoint "nPick the endpoint of the polyline."))
;; Get distance ALONG THE POLYLINE from select point to pick point
;; Note, use vlax-curve-getDistAtPoint but to use it we need to determine
;; if the picked point is the END or START of the pline
;; get the actual point on the pline for the select point
;; this assures that the point is ON the pline not next to it
(setq selpt (vlax-curve-getclosestpointto ename selpt))
;; get the actual point on the pline fot the picked point
;; and get the distance
(if (< (distance pt (vlax-curve-getstartpoint ename))
(distance pt (vlax-curve-getendpoint ename))
)
;; pt is START of pline
(setq pkpt (vlax-curve-getendpoint ename)
dist (vlax-curve-getdistatpoint ename selpt)
)
;; pt is END of pline
(setq pkpt (vlax-curve-getstartpoint ename)
;; (- <total length> <dist to selpt>)
dist (- (vlax-curve-getdistatpoint
ename
(vlax-curve-getEndPoint ename)
)
(vlax-curve-getdistatpoint ename selpt)
)
)
)
(princ)
)
(C:PLINESELECT)
;;;;;;;;;;;;;;;;;;;;;;;;;select start station
(setq startsta (getint "nEnter Start Stationn"))
;;;;;;;;;;;;;;;;;;;;;;;;;select points
;;select blocks on only particular layers with particular names (use insert point)
(setq pointlist
(ssget
"_X"
(LIST
'(-4 . "<AND")
(CONS 410 (GETVAR "ctab"))
'(-4 . "<OR")
'(0 . "insert")
'(8
.
"BNDPT,BNDPTS,FEATURE,FEATIURE,GDRL,EXIST TELE,TREELINE,UTILELEC,UTILSTORM,UTILCOMM,UTILSAN,UTILGAS,TREELINE,BLDGPT"
)
'(-4 . "OR>")
'(-4 . "AND>")
);END LIST
);END SSGET
);END SETQ
;;;;;;;;;;;;;;;;;;;;;;;;;get station of point
(while (setq staoff (ssname ss 0))
(setq whole (/ sta 100)
remainder (* (rem sta 100) 100)
station (strcat whole "+" remainder))
;;;;;;;;;;;;;;;;;;;;;;;;;get offset of point
;;;;;;;;;;;;;;;;;place text starting at 0+00 on both sides at 0,0 with proper scale distances;;;
(vl-load-com)
;(defun C:OffsetText ()
(setq acadObject (vlax-get-acad-object)) ;get Autocad object
(setq acadDocument (vla-get-ActiveDocument acadObject))
;get the Activedocument object
(setq acadModelSpace (VLA-GET-MODELSPACE acadDocument))
;get the modelspace block
(if (< (- sta sta1) (* 1.5 text_height))
(setq sta (+ sta1 (* 1.5 text_height)))
(setq sta1 sta)
);end if
(setq ofsl (* 22.5235 aoscale)
ofsr (* 7.35 aoscale)
);end setq
(if (< (atoi offset) 0)
(setq Insertpoint (list (sta,ofsl, "0")))
(setq Insertpoint (list (sta,ofsr, "0")))
);end if
(setq textObj (vla-addtext
acadModelSpace
(strcat station description offset)
(vlax-3d-point Insertpoint)
text_height
);end vla-addtext
);end setq
(if (< (atoi offset) 0)
(vla-put-Alignment textObj 11) ;set text Justification
(vla-put-Alignment textObj 9) ;set text Justification
) ;end if
;(setq mytextObj myTextobj);retrun the text object
) ;end while
CAB2k
2006-05-30, 12:13 PM
Do you mind if we go back to the beginning?
Start with pseudo code.
This I extracted from you previous post. Can you expand on each line item with more detail as to what
you want to accomplish. I know it's a lot of writing but it will put me on the same page with you
in terms of your goal & will help calcify your intended action at each point.
;;;;;;;;;;;;;;;;;;;;;;;;;select polyline
;;;;;;;;;;;;;;;;;;;;;;;;;select beginning
;;;;;;;;;;;;;;;;;;;;;;;;;select start station
;;;;;;;;;;;;;;;;;;;;;;;;;select points
;;select blocks on only particular layers with particular names (use insert point)
;;;;;;;;;;;;;;;;;;;;;;;;;get station of point
;;;;;;;;;;;;;;;;;;;;;;;;;get offset of point
;;;;;;;;;;;;;;;;;place text starting at 0+00 on both sides at 0,0 with proper scale distances
ccowgill
2006-05-30, 12:24 PM
;;;;;;;;;;;;;;;;;;;;;;;;;select polyline
;;select the centerline of the project (it will probablly be a 2d polyline, *polyline will work)
;;;;;;;;;;;;;;;;;;;;;;;;;select beginning
;;select the beginning point of the polyline (start point may not be necassary)
;;;;;;;;;;;;;;;;;;;;;;;;;select start station
;;some projects dont nessasarily start at 0+00, some might start at 100+00, this part should account for that)
(setq startsta (getint "\nEnter Start Station\n"))
;;;;;;;;;;;;;;;;;;;;;;;;;select points
;;select blocks on only particular layers with particular names (use insert point)
(setq pointlist
(ssget
"_X"
(LIST
'(-4 . "<AND")
(CONS 410 (GETVAR "ctab"))
'(-4 . "<OR")
'(0 . "insert")
'(8
.
"BNDPT,BNDPTS,FEATURE,FEATIURE,GDRL,EXIST TELE,TREELINE,UTILELEC,UTILSTORM,UTILCOMM,UTILSAN,UTILGAS,TREELINE,BLDGPT"
)
'(-4 . "OR>")
'(-4 . "AND>")
);END LIST
);END SSGET
);END SETQ
;;;;;;;;;;;;;;;;;;;;;;;;;get offset of point
;;find the perpindicular distance from the selected point to the centerline
;;;;;;;;;;;;;;;;;;;;;;;;;get station of point
;;find the distance along the centerline to the perpindicular point in the last step
(while (setq staoff (ssname ss 0))
(setq whole (/ sta 100)
remainder (* (rem sta 100) 100)
station (strcat whole "+" remainder));this part of the code converts the distance to the text that will be used below
;;;;;;;;;;;;;;;;;place text starting at 0+00 on both sides at 0,0 with proper scale distances
;;using the station value, place text beginning as though 0 is 0+00
(vl-load-com)
;(defun C:OffsetText ()
(setq acadObject (vlax-get-acad-object)) ;get Autocad object
(setq acadDocument (vla-get-ActiveDocument acadObject))
;get the Activedocument object
(setq acadModelSpace (VLA-GET-MODELSPACE acadDocument))
;get the modelspace block
(if (< (- sta sta1) (* 1.5 text_height))
(setq sta (+ sta1 (* 1.5 text_height)))
(setq sta1 sta)
);end if
(setq ofsl (* 22.5235 aoscale)
ofsr (* 7.35 aoscale)
);end setq
(if (< (atoi offset) 0)
(setq Insertpoint (list (sta,ofsl, "0")))
(setq Insertpoint (list (sta,ofsr, "0")))
);end if
(setq textObj (vla-addtext
acadModelSpace
(strcat station description offset);offset will be calculated above in the offset portion, description needs to be extracted from the appropriate attribute of the selected block
(vlax-3d-point Insertpoint)
text_height
);end vla-addtext
);end setq
(if (< (atoi offset) 0)
(vla-put-Alignment textObj 11) ;set text Justification
(vla-put-Alignment textObj 9) ;set text Justification
) ;end if
;(setq mytextObj myTextobj);retrun the text object
) ;end while
the while loop is to get this thing to loop until all points in the selection set have been annotated originally I had station first, but it might be easier to calc the offset first, then use that information to get the station, it might not be the proper way to loop the program, any better ideas are definitely welcome.
CAB2k
2006-05-30, 12:48 PM
Off on an errand, will look when I get back.
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.