Line to Point

Line to Point

Anonymous
Not applicable
5,371 Views
11 Replies
Message 1 of 12

Line to Point

Anonymous
Not applicable

Good day everyone, 

Do you know how get line start x & y property and change it to line end x & y property using lsp? By doing so, i should be able to convert a line in to a point. Thanks in advance.

joshuamarzamora_3-1616975996262.png

 

joshuamarzamora_2-1616975940975.png

 

 

0 Likes
Accepted solutions (1)
5,372 Views
11 Replies
Replies (11)
Message 2 of 12

Kent1Cooper
Consultant
Consultant
Accepted solution

In simplest terms, something like:

 

(defun C:L2P (/ edata); = Line {to} Point

  (setq edata (entget (car (entsel "\nLine to make equivalent to point at end: "))))

  (entmod

    (subst

      (cons 10 (cdr (assoc 11 edata))); pair start entry code 10 with end coordinates

      (assoc 10 edata); and replace original start entry with it

      edata ; in the entity data list

    ); subst

  ); entmod

  (princ)

); defun

 

Reverse the 10 & 11 entries to do the same with the result at the start instead of the end.

 

If you don't know which end is which, you could probably use LENGTHEN and the Total option, setting the Total to 0 and picking on the Line closer to the opposite end from where you want the resulting equivalent of a point.  [I'm not on an AutoCAD computer to test -- it might reject 0 as a total length.]

Kent Cooper, AIA
0 Likes
Message 3 of 12

Anonymous
Not applicable

Thanks, works like magic. 

0 Likes
Message 4 of 12

Sea-Haven
Mentor
Mentor

Another simple way of which end.

 

(defun c:test ( / ent pt1 pt2 pt3 d1 d2 temp)
(setq ent (entsel "\nPick line near end req'd "))
(setq pt1 (cadr ent))
(setq pt2 (cdr (assoc 10 (entget (car ent)))))
(setq pt3 (cdr (assoc 11 (entget (car ent)))))
(setq d1 (distance pt1 pt2)
	d2 (distance pt1 pt3)
)
(if (> d1 d2)
    (progn 
    (setq temp pt3)
    (setq pt3 pt2)
    (setq pt2 temp)
    )
)
(command "point" pt2)
(princ)
)

  

0 Likes
Message 5 of 12

Anonymous
Not applicable

what would be the code if i want it to be done in multiple lines at once? like i would just fence it the all lines inside the fence would be changed to a point?

0 Likes
Message 6 of 12

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... multiple lines at once? like i would just fence it the all lines inside the fence would be changed to a point?


Would you care at which end the "point" result lands?  It would be pretty easy if you don't [though it could be at your choice of either the start or the end as in my routine].  But if you do, would you want it to be at the end nearer to where the selection Fence crosses it, or farther from it?

 

[Also, I'm curious -- is there some reason to make them zero-length Lines, rather than put actual POINT objects at an end of each one?]

Kent Cooper, AIA
0 Likes
Message 7 of 12

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:

.... you could probably use LENGTHEN and the Total option, setting the Total to 0 ....  [I'm not on an AutoCAD computer to test -- it might reject 0 as a total length.]


[It does reject zero as a Total length, so that option is a no-go.]

Kent Cooper, AIA
0 Likes
Message 8 of 12

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

... multiple lines at once? like i would just fence it the all lines inside the fence would be changed to a point?


Do you really mean "all lines inside the fence"?  Fence selection selects only things that are intersected by the fence.  If you run a fence around and back to where you started, things inside that shape will not be selected if the fence does not actually cross them.  Do you mean a CP [Crossing-Polygon] selection instead?  That would select things that it crosses and also things inside it that it surrounds but does not cross.

Kent Cooper, AIA
0 Likes
Message 9 of 12

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:

....

[Also, I'm curious -- is there some reason to make them zero-length Lines, rather than put actual POINT objects at an end of each one?]


If an actual POINT object is desired, as in @Sea-Haven 's suggestion, I would do it this way, which avoids a bunch of calculation:

(defun C:L2P (/ aper esel)
  (setq
    aper (getvar 'aperture)
    esel (entsel "\nSelect Line near end for Point replacement: ")
  ); setq
  (setvar 'aperture (getvar 'pickbox))
    ; to ensure not Snapping to some other nearby ENDpoint
  (command "_.point" (osnap (cadr esel) "_end"))
  (setvar 'aperture aper)
  (entdel (car esel))
  (princ)
); defun

[And yes, it should have *error* handling added to ensure the APERTURE System Variable gets reset, or the whole changing of that could be omitted if you would never have a situation with the potential for other ENDpoints within Osnap range of, but closer the the Line's nearest end, to the pick location.]

 

And I included removal of the Line, so that the effect is more like the original changing of it to zero length.

Kent Cooper, AIA
0 Likes
Message 10 of 12

Anonymous
Not applicable

[Also, I'm curious -- is there some reason to make them zero-length Lines, rather than put actual POINT objects at an end of each one?]

 

RE: Originally, I'm just adjusting dimension spaces for ordinated dimension. Then an lisp helped me create multiple ordinated dimensions at once with a defined spacing. The only catch with the lisp is that it only set minimum spacing not maximum. So I just explode the ordinated dimension then remove the text and now I'm here, asking if a line can be changed to point. 

0 Likes
Message 11 of 12

Anonymous
Not applicable

If you want the line to remain remove the delete line. (entdel

 

Second answer is I like Kents end solution if you do a ssget "F" it will draw like a pline over the lines you want to add points to so drag the temp line near the desired end. You end up with a selection of lines. 

 

I tried to use the apperture method but could not get it to work.

(defun C:L2P2 (/ aper esel x ss ahpllst co-ord ent)
(vl-load-com)
(defun AHpllst ( /)
(command "_pline")
(while (= (getvar "cmdactive") 1 )
  (command (Getpoint))
)
(setq co-ord (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget (entlast)))))
(princ)
)

(defun aH:swap ( pt /  )
(setq st (cdr (assoc 10 (entget ent))) end (cdr (assoc 11 (entget ent))))

	(setq d1 (distance st pt))
	(setq d2 (distance end pt))
		(if (> d1 d2)
		(progn 
			(setq temp st)
			(setq st end)
			(setq end temp)
		)
		)
)

(AHpllst)
(setq obj1 (vlax-ename->vla-object (entlast)))

    ; to ensure not Snapping to some other nearby ENDpoint
  (setvar 'pdmode 34)
(setq ss (ssget "F" co-ord '((0 . "LINE"))))

(repeat (setq x (sslength ss))
    (setq ent (ssname ss (setq x (- x 1))))
    (setq obj2 (vlax-ename->vla-object ent ))
    (setq intpt   (vlax-invoke obj2 'intersectWith obj1 acExtendNone))
	(aH:swap intpt)
	(command "_.point" st )
)

(vla-delete obj1)

(princ)

); defun

 

Just drag pline points over the lines near the end of the lines.

 

screenshot377.png

 

0 Likes
Message 12 of 12

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... if you do a ssget "F" it will draw like a pline over the lines you want to add points to so drag the temp line near the desired end. You end up with a selection of lines. 

....

Just drag pline points over the lines near the end of the lines.


You don't actually need to draw a Polyline to do this.  The (ssnamex) function "knows" by what method each object in a selection set was selected, and in the case of pick or Fence selection, where it was selected [the pick point, or the place where the Fence crossed it].  So a Point can be placed using ENDpoint Osnap at that location.

 

If you're willing to be conscious enough to follow the instructions in the prompt [use only individual-pick or Fence selection, including needing to type in the F for the latter], this puts Points at the nearer ends of all objects selected in either of those ways:

(defun C:PAE (/ ss); = Points At Ends
  (prompt "\nTo put Points At Ends of objects, BY FENCE OR PICK SELECTION ONLY near desired ends,")
  (if (setq ss (ssget))
    (foreach entry (ssnamex ss); list of objects and how/where selected
      (if (member (car entry) '(1 4)); selected by pick or Fence
        (command
          "_.point" "_end" (cadr (last entry)); selection location
          "_.erase" (cadr entry) "" ; the object
        ); command
      ); if
    ); foreach
  ); if
  (princ)
); defun

It works with Lines, Arcs, Polylines, Splines, Rays, partial Ellipses, Leaders, even Multilines, but could be limited to LINE objects only, or a limited set of objects types, if desired, with a filter for that in the (ssget) function.

 

If you disobey the instructions and select things with something like a Window, those will be ignored.

 

Remove or comment out the Erase line if you want to keep the Lines/etc.

 

If used on multi-segment Polylines or Leaders, since it uses ENDpoint Osnap, it can sometimes find an internal vertex rather than the overall end.  Maybe that can be accounted for if desired.

 

I find that if I pick the same object twice, near each end, or a Fence crosses it twice like that, or a Fence near one end and a pick near the other, it puts only one Point on it, even without the Erasing.  It appears to be always at the end nearer to the first of the selections of it, but I'm not positive of that.

Kent Cooper, AIA
0 Likes