Jump to content

Determine a specific Z value in 3D lines


teknomatika

Recommended Posts

A necessity and a challenge:

He needed a routine that you can select a line with different values of Z and along its length to determine a specific value for Z in the example, the value 10. The marking should be done with a point and its annotation value Z.

Mentioned as an example a line, but the ideal is that this check may occur simultaneously in a set of lines.

where_coord.jpg

Link to comment
Share on other sites

In Pseudo Code:

 

  • Get Line Entity
  • Get Start/End Points
  • Calculate Z-Difference between Points
  • Calculate 2D Distance between Points (now you have the gradient)
  • Calculate the distance of the point with specified Z value using the fact that z=gd (g=gradient, d=2D distance).

Link to comment
Share on other sites

Lee Mac, It is a good guideline.

My knowledge is basic. Do not know if I can.

Describing it another way, what I want is to get an effect of contour, in a survey work. You specify a particular Z coordinate, and the routine must be able to look at each line. At the same time you have to mark that point on each line by introducing a point entity and its notation Z coordinate text.

Link to comment
Share on other sites

Here is a very verbose example of the route I was indicating - I have used long variable names and step-by-step variable assignments so that you can see the method I have used.

 

(defun PointOnLine

 ( line zvalue / 2ddist 2dpoint 2dpoint1 2dpoint2 dist gradient linedata point1 point2 vector )

 (setq linedata (entget line)
       point1   (cdr (assoc 10 linedata))
       point2   (cdr (assoc 11 linedata))
       2Dpoint1 (list (car point1) (cadr point1) 0.)
       2Dpoint2 (list (car point2) (cadr point2) 0.)
       2Ddist   (distance 2Dpoint1 2Dpoint2)
 )
 (if (equal 2Ddist 0.0 1e-
   (list (car 2Dpoint1) (cadr 2Dpoint1) zvalue)
   (if (not (equal (setq gradient (/ (- (caddr point2) (caddr point1)) 2Ddist)) 0.0 1e-)
     (progn
       (setq vector  (mapcar '(lambda ( x1 x2) (/ (- x1 x2) 2Ddist)) 2Dpoint2 2Dpoint1)
             dist    (/ (- zvalue (caddr point1)) gradient)
             2Dpoint (mapcar '+ 2Dpoint1 (mapcar '* vector (list dist dist dist)))
       )
       (list (car 2Dpoint) (cadr 2Dpoint) zvalue)
     )
   )
 )
)

Here is an example test function:

(defun c:test ( / e p z )
 (if
   (and
     (setq e (car (entsel "\nSelect Line: ")))
     (eq "LINE" (cdr (assoc 0 (entget e))))
     (setq z (getreal "\nSpecify Z-Value: "))
     (setq p (PointonLine e z))
   )
   (entmakex (list (cons 0 "POINT") (cons 10 p)))
 )
 (princ)
)

Link to comment
Share on other sites

Lee's code is much more succinct, but here's what came to mind for me (yet another ActiveX example - LoL):

 

(defun c:FOO ( / *error* oldNomutt ss elev acDoc startElev endElev lp hp flag len space)
 (vl-load-com)

 (defun *error*  (msg)
   (and oldNomutt (setvar 'nomutt oldNomutt))
   (vla-endundomark acDoc)
   (cond ((not msg))                                                   ; Normal exit
         ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
         ((princ (strcat "\n** Error: " msg " ** "))))                 ; Fatal error, display it
   (princ))

 (prompt "\nSelect 3D polylines to mark elevation: ")
 (and (setq oldNomutt (getvar 'nomutt)) (setvar 'nomutt 1))
 (if (and (setq ss (ssget "_:L" '((0 . "POLYLINE"))))
          (setvar 'nomutt oldNomutt)
          (setq elev (getreal "\nEnter elevation: ")))
   (progn
     (vla-startundomark
       (setq acDoc (vla-get-activedocument (vlax-get-acad-object))))
     (vlax-for x  (setq ss (vla-get-activeselectionset acDoc))
       (setq startElev (last (vlax-curve-getstartpoint x)))
       (setq endElev (last (vlax-curve-getendpoint x)))
       (cond ((< startElev endElev)
              (setq lp startElev)
              (setq hp endElev)
              (setq flag T))
             ((> startElev endElev)
              (setq lp endElev)
              (setq hp startElev))
             ((= startElev endElev)
              (prompt "\n** Flat polylines not accepted ** ")
              (redraw (vlax-vla-object->ename x) 3)
              (quit)))
       (setq len (vla-get-length x))
       (vla-put-color
         (vla-addpoint
           (cond (space)
                 ((setq space (vla-get-modelspace acDoc))))
           (vlax-3d-point
             (cond (flag
                    (vlax-curve-getpointatdist
                      x
                      (/ (- elev lp)
                         (/ (abs (- hp lp)) len))))
                   ((vlax-curve-getpointatdist
                      x
                      (- len
                         (/ (- elev lp)
                            (/ (abs (- hp lp)) len))))))))
         acred))
     (vla-endundomark acDoc)
     (vla-delete ss))
   (cond (ss (prompt "\n** Invalid input: No elevation ** "))
         ((prompt "\n** No 3D polylines selected ** "))))
 (princ))

Edited by BlackBox
Reversed prompt / nomutt call
Link to comment
Share on other sites

LeeMac:

Excellent. That's right. It only remains to integrate the annotation text of the quota value Z.

In addition, it might be possible to accept the same procedure for polylines and 3D polylines.

 

RenderMan:

Your version does not work. Surely because to fail is something that currently do not understand.

Link to comment
Share on other sites

RenderMan:

Your version does not work.

 

It works just fine on my end when I select 3D Polylines. :? LoL

 

(Pircture shown at PDMODE = 3)

foo_label.3d.polylines.png

Link to comment
Share on other sites

RenderMan:

Your version does not work. Surely because to fail is something that currently do not understand.

 

Maybe because RenderMan considered the Line as Polyline !! :unsure:

Link to comment
Share on other sites

Maybe because RenderMan considered the Line as Polyline !! :unsure:

 

That is correct... Both Lines, and LWPolylines have no slope.

 

Without a 3D Polyline, how does one have a difference in elevation between Start and End points?

 

... Unless the elevations are purely annotation? In which case I've completely misunderstood the OP. :unsure: LoL

Link to comment
Share on other sites

In which case I've completely misunderstood the OP. :unsure: LoL

 

I think from the title of the thread 3D lines and from the Z value which both of these things indicate to elevation works although it is recommend to work

with 3D poly in Elevations and not lines , which normally that gave you the idea of the OP request without reading the whole thread to the end (just a guess) .

 

You considered the right thing to be 3d poly and you went to it with your routine which I also agree with it and not lines due to drafting reasons ,

things like poly entity is easy to deal with in elevations since it is one element and you can handle it in programming much more easier than lines in elevations specifically .

 

Hope I got close to the point . :)

 

One question dear RenderMan .

 

Why you are using the following method with cond function while the name of the varable is localized and it will always logically be nil ?

 

(cond ([b]space[/b]) ;; <- will always be nil since it localized 
                 ((setq space (vla-get-modelspace acDoc)))
           )

regards.

Link to comment
Share on other sites

One question dear RenderMan .

 

Why you are using the following method with cond function while the name of the varable is localized and it will always logically be nil ?

 

Good question, Tharwat. This is a great concept to learn for iterating. :)

 

Copy this code to your VLIDE, where ( is a breakpoint:

 

(vl-load-com)
(setq acDoc (vla-get-activedocument (vlax-get-acad-object)))
[b][color=#ff0000]([/color][/b]cond [color=#000000](space)[/color]
   ((setq space (vla-get-modelspace acDoc)))
   )

 

(^^ Code assumes space = nil ^^)

 

... Now, when the code stops at the breakpoint, step through the code using F8.

 

Be mindful to note the difference in behavior of the first iteration, as compared to subsequent iterations.

 

What do you notice, and how could this behavior be useful when, for example one steps through a selection set, or vla-collection (i.e., foreach, vlax-for, respectively)?

Link to comment
Share on other sites

It only remains to integrate the annotation text of the quota value Z.

In addition, it might be possible to accept the same procedure for polylines and 3D polylines.

 

That part I leave for you :wink:

 

Without a 3D Polyline, how does one have a difference in elevation between Start and End points?

 

A Line with endpoints with different z-values?

 

(entmakex '((0 . "LINE") (10 10.0 20.0 30.0) (11 15.0 35.0 50.0)))

Link to comment
Share on other sites

Silly me, I'm working with 3D too much these days (features, contours, etc.) that I completely overlooked a line with Z's. Especially so, when we only use lines for construction \ design layout (i.e., temporary), and not for saved project data.

 

That's quite an oversight on my part. LoL I need a drink.

 

RenderMan

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...