Jump to content

3d poly lisp


flopo

Recommended Posts

Hello everybody,

I'm working with 3d polylines and I need a lisp to do this: to draw lines from some points perpendiculat to a 3d polyline. There are a lot of points, 3d points - I mean points in space, with Z different from 0. From each point to draw a perpendicular on 3d polyline, but on that part of poly that is closer to my point. Is it possible? Thanks!

Link to comment
Share on other sites

This is an example, but unfortunately I don't have a drawing with 3d polyline, only with 2d polyline.The original 3d ply has been flatten :( Is a pipe, and anyhow, differences on Z axis are small...

polyline.dwg

Link to comment
Share on other sites

Try this:

 

(defun c:perp (/ i ss ent pt p1 p2)
 (vl-load-com)

 (princ "\n>> Select Points >>")
 (if (setq i -1 ss (ssget '((0 . "POINT"))))
   
   (if (and (setq ent (car (entsel "\nSelect Curve: ")))
            (wcmatch (cdr (assoc 0 (entget ent))) "*LINE,CIRCLE,ELLIPSE,ARC"))

       (while (setq pt (ssname ss (setq i (1+ i))))
         (setq p2 (vlax-curve-getClosestPointto ent (setq p1 (cdr (assoc 10 (entget pt))))))
         (entmake (list (cons 0 "LINE") (cons 10 p1) (cons 11 p2))))))
 
 (princ))

Link to comment
Share on other sites

Try this:

 

(defun c:perp (/ i ss ent pt p1 p2)
 (vl-load-com)

 (princ "\n>> Select Points >>")
 (if (setq i -1 ss (ssget '((0 . "POINT"))))
   
   (if (and (setq ent (car (entsel "\nSelect Curve: ")))
            (wcmatch (cdr (assoc 0 (entget ent))) "*LINE,CIRCLE,ELLIPSE,ARC"))

       (while (setq pt (ssname ss (setq i (1+ i))))
         (setq p2 (vlax-curve-getClosestPointto ent (setq p1 (cdr (assoc 10 (entget pt))))))
         (entmake (list (cons 0 "LINE") (cons 10 p1) (cons 11 p2))))))
 
 (princ))

 

Hey, I use something quite similar to that. :)

;;; Draw line perpendicular from selected curve
;;; Required Subroutines: AT:Entsel
;;; Alan J. Thompson, 09.29.09
(defun c:LPer (/ *error* #Ent #Obj #Point)
 (setq *error* (lambda (x) (and #Obj (vl-catch-all-apply 'vla-highlight (list #Obj :vlax-false)))))
 (and
   (setq #Ent (AT:Entsel nil "\nSelect curve: " '((0 . "*POLYLINE,ARC,LINE,CIRCLE,ELLIPSE")) nil))
   (setq #Obj (vlax-ename->vla-object (car #Ent)))
   (not (vla-highlight #Obj :vlax-true))
   (while (setq #Point (getpoint "\nSpecify point for line: "))
     (entmake (list '(0 . "LINE")
                    (cons 10 (vlax-curve-getclosestpointto (car #Ent) (trans #Point 1 0) T))
                    (cons 11 (trans #Point 1 0))
              ) ;_ list
     ) ;_ entmake
   ) ;_ while
 ) ;_ and
 (*error* nil)
 (princ)
) ;_ defun

 

The only problem is, with 3DPolylines, the vertex elevation will screw up deriving the closest point. It will often snap to the end point or something. It's really quite annoying. That's why, when trying to get a point on a 3DPolyline, you have to use (osnap (cadr ent) "_near") instead of (vlax-curve-getclosestpointto (car ent) (cadr ent)). :(

Link to comment
Share on other sites

A quick test seemed to work OK, but I'm not disagreeing with you as I have limited experience indeed in the world of 3D... :wink:

It draws them to the line, they just aren't perpendicular in a top view (which, in my experience, is what you want). However, the requesting party may be asking for just what you did. It's tricky when dealing with the 3D world. I'm civil and things are 3D, but not in the fashion that some people work in 3D. I still live in a TOP view world.

 

perp.gif

Link to comment
Share on other sites

Point taken, how about this then?

 

(defun c:perp (/ i ss ent pt p1 p2)
 (vl-load-com)

 (princ "\n>> Select Points >>")
 (if (setq i -1 ss (ssget '((0 . "POINT"))))
   
   (if (and (setq ent (car (entsel "\nSelect Curve: ")))
            (wcmatch (cdr (assoc 0 (entget ent))) "*LINE,CIRCLE,ELLIPSE,ARC"))

       (while (setq pt (ssname ss (setq i (1+ i))))
         (setq p2 (vlax-curve-getClosestPointtoprojection ent
                    (setq p1 (cdr (assoc 10 (entget pt)))) '(0 0 1)))
         (entmake (list (cons 0 "LINE") (cons 10 p1) (cons 11 p2))))))
 
 (princ))

Link to comment
Share on other sites

Point taken, how about this then?

 

(defun c:perp (/ i ss ent pt p1 p2)
 (vl-load-com)

 (princ "\n>> Select Points >>")
 (if (setq i -1 ss (ssget '((0 . "POINT"))))
   
   (if (and (setq ent (car (entsel "\nSelect Curve: ")))
            (wcmatch (cdr (assoc 0 (entget ent))) "*LINE,CIRCLE,ELLIPSE,ARC"))

       (while (setq pt (ssname ss (setq i (1+ i))))
         (setq p2 (vlax-curve-getClosestPointtoprojection ent
                    (setq p1 (cdr (assoc 10 (entget pt)))) '(0 0 1)))
         (entmake (list (cons 0 "LINE") (cons 10 p1) (cons 11 p2))))))
 
 (princ))

 

 

Nicely done Lee! :)

 

I've updated mine as well.

 

;;; Draw line perpendicular from selected curve
;;; Required Subroutines: AT:Entsel
;;; Alan J. Thompson, 09.29.09
(defun c:LPer (/ *error* #Ent #Obj #Point)
 (setq *error* (lambda (x) (and #Obj (vl-catch-all-apply 'vla-highlight (list #Obj :vlax-false)))))
 (and
   (setq #Ent (AT:Entsel nil "\nSelect curve: " '((0 . "*POLYLINE,ARC,LINE,CIRCLE,ELLIPSE")) nil))
   (setq #Obj (vlax-ename->vla-object (car #Ent)))
   (not (vla-highlight #Obj :vlax-true))
   (while (setq #Point (getpoint "\nSpecify point for line: "))
     (entmake (list '(0 . "LINE")
                    (cons 10 (vlax-curve-getclosestpointtoprojection (car #Ent) (trans #Point 1 0) '(0 0 1)))
                    (cons 11 (trans #Point 1 0))
              ) ;_ list
     ) ;_ entmake
   ) ;_ while
 ) ;_ and
 (*error* nil)
 (princ)
) ;_ defun

Link to comment
Share on other sites

Hello everybody,

after drawing perpendicular lines from points to a 3dpoly, I have to measure the distance between consecutive intersection 3dpoly - perpendicular line. A lisp to do this will help me a lot... See the attachment - drawing. Thanks!

3dpoly-dist.dwg

Link to comment
Share on other sites

Try this: (Lee's Routine Modified)

(defun c:perp (/ i ss ent pt p1 p2)
 (vl-load-com)
 (command "_undo" "_begin")
 (princ "\n>> Select Points >>")
 (if (setq i  -1
           ss (ssget '((0 . "POINT"))) )
   (if (and (setq ent (car (entsel "\nSelect Curve: ")))
            (wcmatch (cdr (assoc 0 (entget ent))) "*LINE,CIRCLE,ELLIPSE,ARC"))
     (while (setq pt (ssname ss (setq i (1+ i))))
       (setq
         p2 (vlax-curve-getClosestPointto ent (setq p1 (cdr (assoc 10 (entget pt)))))
       )
       (if (entmake (list '(0 . "LINE") '(8 . "perp") (cons 10 p1) (cons 11 p2)))
         (entmake
           (list '(0 . "MTEXT")
                 '(100 . "AcDbEntity")
                 '(100 . "AcDbMText")
                 '(8 . "point")
                 (cons 10 p1)
                 '(40 . 0.6)
                 '(41 . 6.03584)
                 '(71 . 1)
                 '(72 . 5)
                 (cons 1 (vl-princ-to-string (distance p1 p2)))
                 '(7 . "Standard")
                             ;'(210 0.0 0.0 1.0)
                 '(42 . 1.6)
                 '(43 . 0.6)
                 '(50 . 0.0)
                 '(73 . 1)
                 '(44 . 1.0)
           )
         )
       )
     )
   )
 )
 (command "_undo" "_end")

 (princ)
)

Link to comment
Share on other sites

Oops, Thanks Wizman.:shock:

(defun c:perp (/ i ss ent pt p1 p2 ptList LASTPT)
 (vl-load-com)
 (command "_undo" "_begin")
 (princ "\n>> Select Points >>")
 (if (setq i  -1
           ss (ssget '((0 . "POINT"))) )
   (if (and (setq ent (car (entsel "\nSelect Curve: ")))
            (wcmatch (cdr (assoc 0 (entget ent))) "*LINE,CIRCLE,ELLIPSE,ARC"))
     (while (setq pt (ssname ss (setq i (1+ i))))
       (setq p2 (vlax-curve-getClosestPointto ent (setq p1 (cdr (assoc 10 (entget pt))))))
       (setq ptList (cons p2 ptList))
       (entmake (list '(0 . "LINE") '(8 . "perp") (cons 10 p1) (cons 11 p2)))
     )
   )
 )

 (if ptList
   (progn
     (setq Startpt (vlax-curve-getstartpoint ent)
           Lastpt Startpt)
     ;;  sort by distance
     (setq ptList (vl-sort ptList '(lambda (e1 e2)
                                     (< (vlax-curve-getdistatpoint ent e1)
                                        (vlax-curve-getdistatpoint ent e2)))))
   (foreach pt ptList
     (if (> (distance pt Startpt) 0.001)
         (entmake
           (list '(0 . "MTEXT")
                 '(100 . "AcDbEntity")
                 '(100 . "AcDbMText")
                 '(8 . "point")
                 (cons 10 (polar pt (angle pt Lastpt)(/ (distance pt Lastpt) 2.)))
                 '(40 . 0.6)
                 '(41 . 0.0)
                 '(71 . 
                 '(72 . 5)
                 (cons 1 (rtos (distance pt Lastpt) 2 2))
                 '(7 . "Standard")
                             ;'(210 0.0 0.0 1.0)
                 '(50 . 0.0)
                 '(73 . 1)
                 '(44 . 1.0)

           )
         )
       )
      (setq LastPt pt)
     )
   )
 )
 
 (command "_undo" "_end")

 (princ)
)

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...