Visual LISP, AutoLISP and General Customization

Visual LISP, AutoLISP and General Customization

Reply
Contributor
user_sf
Posts: 20
Registered: ‎06-12-2014
Message 1 of 21 (263 Views)
Accepted Solution

Easy way to find a point on XLINE and LINE

263 Views, 20 Replies
06-12-2014 11:48 AM

Hi,

 

I have two questions for experts

 

1) Is there an easy way in LISP to calculate a mid point of a line and get an X, Y, Z coordinates for this point? I know I can pull end points from the entity data

 

(setq current_line (entsel "\n Select line")

(setq point1 (cdr (assoc 10 (entget (car current_line)))))

(setq point2 (cdr (assoc 11 (entget (car current_line)))))

 

2) I also would like to find X,Y,Z coordinates of a point on an xline located, say, 20 units away from xline origination point.

 

 Your input is highly appreciated


user_sf wrote:

I am still struggling finding a point along XLINE. I think my problem is that I've not dealt with vlax functions and don't know how to go about them. .... 

....

(setq xline_pt1 (cdr (assoc 10 (entget (car x_line)))))
(setq xline_pt2 (cdr (assoc 11 (entget (car x_line)))))

.... 


In explanation of my suggestion from earlier:

 

(vlax-curve-getPointAtParam theXlineEntityName 20)  ... and ... -20)

 

This function gets the Point along the entity at the specified Parameter value from the start point.  What the Parameter values represent varies with entity type, but for Xlines and Lines, one drawing unit of length adds 1 to the Parameter value.  For Xlines, the 0 Parameter is the defining "start" or origin point, the same as the (assoc 10) value in the entity data list.  Distances along it from there can be positive or negative, with the positive direction being toward the second defining point, i.e. the (assoc 11) value in the entity data.

 

Since Parameter values are the same as distances from the origin, the same could be done with a different function:

(vlax-curve-getPointAtDist theXlineEntityName 20)  ... and ... -20)

 

You can give (vlax-curve...) functions either the entity name [in this case, (car x_line), or it can be extracted from an (ssget) selection set or a list of entity names, or, when appropriate, with (entlast)] or the conversion of that into a VLA object with (vlax-ename->vla-object).

 

Don't be thrown by the "curve" in the function names -- "curve" objects in VLA terms are anything with linearity, whether curved or straight: Lines, Arcs, Circles, Polylines of any type, Ellipses, Splines, Rays, Xlines....

 

Another way you could do it without (vlax-curve...) functions:

 

(polar xline_pt1 (angle xline_pt1 xline_pt2) 20)

and either

(polar xline_pt1 (angle xline_pt1 xline_pt2) -20)

or

(polar xline_pt1 (+ (angle xline_pt1 xline_pt2) pi) 20)


user_sf wrote:

.... When I use vlax functions, should I do something else to make those functions available for the program? ....


Put

 

(vl-load-com)

 

in, either within any program that uses such functions, or in acaddoc.lsp so that they are loaded in every drawing you open.

*Expert Elite*
Lee_Mac
Posts: 1,270
Registered: ‎12-29-2009
Message 2 of 21 (256 Views)

Re: Easy way to find a point on XLINE and LINE

06-12-2014 12:11 PM in reply to: user_sf
user_sf wrote:

1) Is there an easy way in LISP to calculate a mid point of a line and get an X, Y, Z coordinates for this point?

 

You can use the following function:

 

(defun mid ( p1 p2 )
    (mapcar '(lambda ( a b ) (/ (+ a b) 2.0)) p1 p2)
)

 

For example:

 

_$ (mid '(1.2 3.4 0.0) '(5.2 1.3 2.8))
(3.2 2.35 1.4)

 

Or, with a LINE:

 

(defun c:test ( / ent enx )
    (if (and (setq ent (car (entsel "\nSelect LINE: ")))
             (= "LINE" (cdr (assoc 0 (setq enx (entget ent)))))
        )
        (entmake (list '(0 . "POINT") (cons 10 (mid (cdr (assoc 10 enx)) (cdr (assoc 11 enx))))))
    )
    (princ)
)

 

user_sf wrote:

2) I also would like to find X,Y,Z coordinates of a point on an xline located, say, 20 units away from xline origination point.

 

Try the following function:

 

(defun xpoint ( enx dis )
    (mapcar '(lambda ( a b ) (+ a (* dis b))) (cdr (assoc 10 enx)) (cdr (assoc 11 enx)))
)

 

Call the above with the DXF data of your XLINE & the distance from the XLINE origin, e.g.:

 

(defun c:test ( / ent enx len )
    (if (and (setq ent (car (entsel "\nSelect XLINE: ")))
             (= "XLINE" (cdr (assoc 0 (setq enx (entget ent)))))
             (setq len (getdist "\nSpecify distance from origin: "))
        )
        (entmake (list '(0 . "POINT") (cons 10 (xpoint enx len))))
    )
    (princ)
)
Lee Mac ProgrammingTwitterExchange App StoreDropbox (500MB free)
Expert Elite
With Mathematics there is the possibility of perfect rigour, so why settle for less?
*Expert Elite*
Kent1Cooper
Posts: 5,871
Registered: ‎09-13-2004
Message 3 of 21 (236 Views)

Re: Easy way to find a point on XLINE and LINE

06-12-2014 12:48 PM in reply to: user_sf

user_sf wrote:

.... 

1) Is there an easy way in LISP to calculate a mid point of a line and get an X, Y, Z coordinates for this point? I know I can pull end points from the entity data

 

(setq current_line (entsel "\n Select line"))

(setq point1 (cdr (assoc 10 (entget (car current_line)))))

(setq point2 (cdr (assoc 11 (entget (car current_line)))))

 

2) I also would like to find X,Y,Z coordinates of a point on an xline located, say, 20 units away from xline origination point.

....


1)  Another way to do it, without the need to extract point1 and point2:

 

(osnap (cadr current_line) "_mid")

 

Or, if you need point1 and point2 for some other reason, so you're getting them anyway:

 

(mapcar '/ (mapcar '+ point1 point2) '(2 2 2))

 

 

2)  Parameter values for Xlines are drawing unit lengths.  These will get those points in the two directions from the origination point:

 

(vlax-curve-getPointAtParam theXlineEntityName 20)

 

(vlax-curve-getPointAtParam theXlineEntityName -20)

 

[after doing (vl-load-com) if necessary]

Kent Cooper
*Expert Elite*
Lee_Mac
Posts: 1,270
Registered: ‎12-29-2009
Message 4 of 21 (219 Views)

Re: Easy way to find a point on XLINE and LINE

06-12-2014 03:19 PM in reply to: Kent1Cooper
Kent1Cooper wrote:

1)  Another way to do it, without the need to extract point1 and point2:

 

(osnap (cadr current_line) "_mid")

 

Be careful with this method - it could return unexpected results when used in crowded areas of a drawing.

Lee Mac ProgrammingTwitterExchange App StoreDropbox (500MB free)
Expert Elite
With Mathematics there is the possibility of perfect rigour, so why settle for less?
Contributor
user_sf
Posts: 20
Registered: ‎06-12-2014
Message 5 of 21 (213 Views)

Re: Easy way to find a point on XLINE and LINE

06-12-2014 04:20 PM in reply to: Lee_Mac
Thank you. It should work. I will research on mapcar and lamdba tonight.
Contributor
user_sf
Posts: 20
Registered: ‎06-12-2014
Message 6 of 21 (212 Views)

Re: Easy way to find a point on XLINE and LINE

06-12-2014 04:23 PM in reply to: Kent1Cooper
I like the second suggested approach for dealing with Q1. Followup to Q2 - Would I be able to use vlax functions in AutoLISP or would I have to do it in Visual? Thank you.
Valued Mentor
stevor
Posts: 891
Registered: ‎12-26-2005
Message 7 of 21 (193 Views)

Re: Easy way to find a point on XLINE and LINE

06-13-2014 06:55 AM in reply to: user_sf
Yes, vlax functions, and others, are available in any full version of Autocad. Autolisp and Vlisp run inside Autocad, no need to be in either of them.
S
Distinguished Mentor
gasty1001
Posts: 582
Registered: ‎04-11-2010
Message 8 of 21 (184 Views)

Re: Easy way to find a point on XLINE and LINE

06-13-2014 08:41 AM in reply to: user_sf

Hi,

 

I prefer to do it with vlax functions:

 

(vl-load-com)

(defun GetMidPoint(ent)
  (vlax-curve-getPointAtParam ent 0.5)
)

(defun GetPointAtDistanceFromOrigin(ent dist)
  (vlax-curve-getPointAtDist ent dist)
) 

 

OBS:

The (vl-load-com) need to be called only once in the session

 

The first function takes ent as argument it should be an ENAME, but it will fail if ent it's not a curve, and may give an erroneous output if ent it's not a line.

 

Curve objects like lines, polylines, etc are parameterized curves, and for lines the start parameter is 0 and the end parameter is 1, and as lines are linear objects, the mid point will be positioned exactly at the value 0.5, this may not apply to others curve objects even with only one segment.

 

The second function is no needed at all, as it's only a rename to clarify that the distance is measured from the origin (dxf code 10)

 

Gaston Nunez

 

 

*Expert Elite*
Kent1Cooper
Posts: 5,871
Registered: ‎09-13-2004
Message 9 of 21 (177 Views)

Re: Easy way to find a point on XLINE and LINE

06-13-2014 05:58 PM in reply to: gasty1001

gasty1001 wrote:

....

 

,,,,
(defun GetMidPoint(ent) (vlax-curve-getPointAtParam ent 0.5) ) ,,,,

 

... for lines the start parameter is 0 and the end parameter is 1, and as lines are linear objects, the mid point will be positioned exactly at the value 0.5, ....

 


That's not the case with Lines.  The Parameter values are drawing units of length.  The end Parameter of a Line will be 1 only if the Line is exactly 1 drawing unit long.  The only thing I can think of off-hand for which that would find the midpoint would be a one-segment Polyline, but it would do so whether that is a line or an arc segment.
Kent Cooper
*Expert Elite*
Kent1Cooper
Posts: 5,871
Registered: ‎09-13-2004
Message 10 of 21 (174 Views)

Re: Easy way to find a point on XLINE and LINE

06-13-2014 06:09 PM in reply to: Lee_Mac

Lee_Mac wrote:
Kent1Cooper wrote:

1)  Another way to do it, without the need to extract point1 and point2:

 

(osnap (cadr current_line) "_mid")

 

Be careful with this method - it could return unexpected results when used in crowded areas of a drawing.


Yes, and if it seems likely that this could be an issue [i.e. that you won't always be able to select your Line in a place clear of other objects within Osnap range], one thing that I have sometimes done is to set the APERTURE System Variable temporarily to the same size as the PICKBOX System Variable.  Presumably one is not going to select an object in a place where other objects are within the pick-box target range, so if the Osnap Aperture is no bigger than that, Object Snap wouldn't find what it's looking for in relation to any object other than the one selected.

Kent Cooper
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.