Jump to content

Testing polyline


paulmcz

Recommended Posts

I am trying to figure out how to test if selected polyline is made out of alternating straight segments and arcs. It also has to be starting and ending with the straight segments. So far, I have a list of all 'assoc 42' values. This list has to start with 0.0, every second member has to be non zero and the last two members in this list also have to be both 0.0. Any idea or hint what the testing mechanism should be?

 

Thanks.

Link to comment
Share on other sites

Is this another homework question? :unsure:

 

I am trying to figure out how to test if selected polyline is made out of alternating straight segments and arcs. It also has to be starting and ending with the straight segments. So far, I have a list of all 'assoc 42' values. This list has to start with 0.0, every second member has to be non zero and the last two members in this list also have to be both 0.0. Any idea or hint what the testing mechanism should be?

 

Hint:

You can test to see if a Pline segment is straight by determining if the midpoint between two adjacent vertices falls on the Pline itself, or not.

Link to comment
Share on other sites

You could use a counter variable (initiated at zero) and test whether the bulge equals zero everytime the counter is even.

Edited by Lee Mac
Link to comment
Share on other sites

You could use a counter variable (initiated at zero) and test whether the bulge equals zero everytime the counter is even.

 

It seems to be a bit more complicated than that. If all bulge values are zero, the test would still pass, where it shouldn't. The pattern of the list of bulge values should always be - 0, non zero, 0, non zero,...... unknown number of times and it has to end with 0, 0.

Link to comment
Share on other sites

It seems to be a bit more complicated than that. If all bulge values are zero, the test would still pass, where it shouldn't. The pattern of the list of bulge values should always be - 0, non zero, 0, non zero,...... unknown number of times and it has to end with 0, 0.

 

Then test for zero bulge when the counter is even, otherwise test for non-zero bulge.

Link to comment
Share on other sites

I have written this so far, where value of "b" is the test but it doesn't work for all possible polyline shapes. Not to mention that it is not very pretty.

(defun c:test (/ x pl g xx d li a tot b)
 (setq	x  (car (entsel "\n Select polyline: "))
pl (entget x)
c  (cdr (assoc 10 pl))
g  (member (assoc 42 pl) pl)
 )
 ;(command "circle" c 1.0)
 (while g
   (setq xx (cdr (assoc 42 g))
  d  (cdr g)
  g  (member (assoc 42 d) d)
  li (append li (list xx))
  a (length li)
   )
 )
 (while li
   (if	(and (car li) (zerop (car li)) (cadr li))
     (setq tot	(+ (car li) (cadr li))
    a	(length li)
     )
     (setq tot 0)
   )
   (if	(= a 2)
     (setq b 0)
     (setq b (length li))
   )
   (if	(zerop tot)
     (setq li nil)
     (setq li (cddr li))
   )

 )
 (princ)
)

Link to comment
Share on other sites

Is this another homework question? :unsure:

 

 

 

Hint:

You can test to see if a Pline segment is straight by determining if the midpoint between two adjacent vertices falls on the Pline itself, or not.

 

Yes, since I do this at home, it then must be a homework. Not a school project but still a homework.

 

How do you find out if the midpoint falls on the polyline itself?

Link to comment
Share on other sites

Ok, how about something like this, feed it with the LWPolyline Entity name:

 

([color=BLUE]defun[/color] _PolyPredicate ( poly [color=BLUE]/[/color] _MAssoc _Predicate bulg )

 ([color=BLUE]defun[/color] _MAssoc ( key lst [color=BLUE]/[/color] pair )
   ([color=BLUE]if[/color] ([color=BLUE]setq[/color] pair ([color=BLUE]assoc[/color] key lst))
     ([color=BLUE]cons[/color] ([color=BLUE]cdr[/color] pair) (_MAssoc key ([color=BLUE]cdr[/color] ([color=BLUE]member[/color] pair lst))))
   )
 )

 ([color=BLUE]defun[/color] _Predicate ( lst i )
   ([color=BLUE]cond[/color]
     ( ([color=BLUE]null[/color] lst)
       ([color=BLUE]=[/color] 1 ([color=BLUE]logand[/color] i 1))
     )
     ( ([color=BLUE]zerop[/color] ([color=BLUE]logand[/color] i 1))
       ([color=BLUE]and[/color] ([color=BLUE]equal[/color] 0.0 ([color=BLUE]car[/color] lst) 1e-14) (_Predicate ([color=BLUE]cdr[/color] lst) ([color=BLUE]1+[/color] i)))
     )
     ( ([color=BLUE]and[/color] ([color=BLUE]not[/color] ([color=BLUE]equal[/color] 0.0 ([color=BLUE]car[/color] lst) 1e-14)) (_Predicate ([color=BLUE]cdr[/color] lst) ([color=BLUE]1+[/color] i))) )
   )
 )

 ([color=BLUE]setq[/color] bulg (_MAssoc 42 ([color=BLUE]entget[/color] poly)))
 
 ([color=BLUE]if[/color] ([color=BLUE]zerop[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 70 ([color=BLUE]entget[/color] poly))))
   ([color=BLUE]setq[/color] bulg ([color=BLUE]reverse[/color] ([color=BLUE]cdr[/color] ([color=BLUE]reverse[/color] bulg))))
   ([color=BLUE]setq[/color] bulg ([color=BLUE]append[/color] bulg ([color=BLUE]list[/color] ([color=BLUE]car[/color] bulg))))
 )
 ([color=BLUE]and[/color] ([color=BLUE]<[/color] 2 ([color=BLUE]length[/color] bulg)) (_Predicate bulg 0))
)

I guessed at the correct result for closed LWPolylines.

 

Quick test function:

 

(defun c:test ( / e )
 (and
   (setq e (car (entsel)))
   (eq "LWPOLYLINE" (cdr (assoc 0 (entget e))))
   (_PolyPredicate e)
 )
)

Link to comment
Share on other sites

Yes, since I do this at home, it then must be a homework. Not a school project but still a homework.

 

How do you find out if the midpoint falls on the polyline itself?

 

Homework questions are welcomed, but consider noting that in the OP when applicable, as you may received better (more educational?) immediate responses.

 

Lee has offered a better course of action for you, in my opinion. However, to answer your question...

 

Presuming that the source polyline were already selected, and the entity name stored to a variable, you could use the calculated midpoint as either a single entity selection (and compare that selection's eName to the previously stored eName), or simply compare the coordinate returned at the midpoint distance (adjusted for actual distance along the Polyline) using vlax-curve-getpointatdist, to that of the calculated midpoint coordinate.

 

Like I said, I feel Lee has offered the simpler solution.

 

Hope this helps!

Link to comment
Share on other sites

Wow, Lee, your code is a way over my head but it works perfectly. It will take me some time to absorb and understand all the steps in it as my lisp knowledge is quite elementary.

 

Thank you very much.

Link to comment
Share on other sites

Homework questions are welcomed, but consider noting that in the OP when applicable, as you may received better (more educational?) immediate responses.

 

Lee has offered a better course of action for you, in my opinion. However, to answer your question...

 

Presuming that the source polyline were already selected, and the entity name stored to a variable, you could use the calculated midpoint as either a single entity selection (and compare that selection's eName to the previously stored eName), or simply compare the coordinate returned at the midpoint distance (adjusted for actual distance along the Polyline) using vlax-curve-getpointatdist, to that of the calculated midpoint coordinate.

 

Like I said, I feel Lee has offered the simpler solution.

 

Hope this helps!

 

Thanks RenderMan.

Link to comment
Share on other sites

Wow, Lee, your code is a way over my head but it works perfectly. It will take me some time to absorb and understand all the steps in it as my lisp knowledge is quite elementary.

 

Thank you very much.

 

Thanks paulmcz, you're welcome.

Link to comment
Share on other sites

Or perhaps going with the vla object:

(vl-load-com)

(defun XOR (v1 v2 /) (and (or v1 v2) (not (and v1 v2))))

(defun c:testpl (/ eo n len last-line)
 (if (and (setq eo (entsel "\nPick polyline: ")) ;Pick entity
          (setq eo (vlax-ename->vla-object (car eo))) ;Convert to vla
          (eq (vla-get-ObjectName eo) "AcDbPolyline") ;Check if polyline
     )
   (if (= (vla-GetBulge eo 0) 0.0) ;Check if 1st vector is a line
     (progn
       (setq n         1 ;Initialize index to 2nd vector
             len       (1- (/ (length (vlax-get eo 'Coordinates)) 2)) ;Get number of vectors
             last-line t ;Initialize last-line to indicate it was a line
       )
       (while (and (< n len) ;Step through entire list of vectors
                   (xor (zerop (rem n 2)) last-line) ;But stop if sequence is broken
              )
         (setq last-line (zerop (vla-GetBulge eo n)) ;Check if current vector is a line
               n         (1+ n);Increment index
         )
       )
       (if (= n len);If index reached end
         (if last-line;If last check was on a line
           (princ "\nPolyline alternates line-arc-line... Starts and ends with lines.")
           ;; Else last check was an arc
           (princ "\nPolyline doesn't end with a straight line.")
         )
         ;; Else didn't reach end, so sequence was broken
         (princ "\nPolyline doesn't alternate line-arc-line...")
       )
     )
     ;; Else 1st vector wasn't a line
     (princ "\nPolyline doesn't start with a straight line.")
   )
   ;; Else the picked object isn't a polyline
   (princ "\nThat's not a polyline.")
 )
 (princ)
)

A bit of imperative code in lisp ... please don't shoot! :shock:

Link to comment
Share on other sites

Thanks irneb. I am only familiar with vlax-curve functions when it comes to 'vla-object'. It is about time to learn all that, I guess.

 

Your code works on all the polylines, except the one at the bottom in the attached drawing. It has one sharp corner and therefore shouldn't qualify.

 

I appreciate the explanation on each step.

 

Thanks.

testpolyline.dwg

Link to comment
Share on other sites

I believe Irne has fallen for the 'trap' you noted in post #4 Paul, an XOR of the test for an even index value and straight line flag variable will still allow straight lines when the index is odd. :wink:

Link to comment
Share on other sites

The 'trap', if any, was unintentional. I was only talking about the bulge values and the last two in collected list (of bulge values) have to be both 0. Not the last two polyline segments.

Link to comment
Share on other sites

The 'trap', if any, was unintentional..

 

I was just referring to the fact that checking whether the bulge value is zero for even indexes doesn't imply it is non-zero for odd indexes, maybe not a 'trap' but certainly something that could be overlooked when working with the logical expressions.

 

It seems to be a bit more complicated than that. If all bulge values are zero, the test would still pass, where it shouldn't.
Link to comment
Share on other sites

Lee, the fact that things can be overlooked, I understand very well from my own experience and testings. Sometimes, I don't see things that are very obvious or elementary, even to me.

 

It is 2AM in London now, isn't it? Do you sleep at all?

Link to comment
Share on other sites

It is 2AM in London now, isn't it? Do you sleep at all?

 

Where's ReMark's avatar when you need him!? LoL (12:50 AM my time)

 

Don't worry... He'll be back. 8)

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