paulmcz Posted July 12, 2011 Share Posted July 12, 2011 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. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted July 12, 2011 Share Posted July 12, 2011 Is this another homework question? 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. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 12, 2011 Share Posted July 12, 2011 (edited) You could use a counter variable (initiated at zero) and test whether the bulge equals zero everytime the counter is even. Edited July 12, 2011 by Lee Mac Quote Link to comment Share on other sites More sharing options...
paulmcz Posted July 12, 2011 Author Share Posted July 12, 2011 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. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 12, 2011 Share Posted July 12, 2011 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. Quote Link to comment Share on other sites More sharing options...
paulmcz Posted July 12, 2011 Author Share Posted July 12, 2011 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) ) Quote Link to comment Share on other sites More sharing options...
paulmcz Posted July 12, 2011 Author Share Posted July 12, 2011 Is this another homework question? 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? Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 12, 2011 Share Posted July 12, 2011 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) ) ) Quote Link to comment Share on other sites More sharing options...
BlackBox Posted July 12, 2011 Share Posted July 12, 2011 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! Quote Link to comment Share on other sites More sharing options...
paulmcz Posted July 12, 2011 Author Share Posted July 12, 2011 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. Quote Link to comment Share on other sites More sharing options...
paulmcz Posted July 12, 2011 Author Share Posted July 12, 2011 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. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted July 12, 2011 Share Posted July 12, 2011 Thanks RenderMan. You're very welcome , sorry I wasn't more helpful... maybe next time? LoL Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 12, 2011 Share Posted July 12, 2011 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. Quote Link to comment Share on other sites More sharing options...
irneb Posted July 12, 2011 Share Posted July 12, 2011 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! Quote Link to comment Share on other sites More sharing options...
paulmcz Posted July 12, 2011 Author Share Posted July 12, 2011 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 Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 12, 2011 Share Posted July 12, 2011 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: Quote Link to comment Share on other sites More sharing options...
paulmcz Posted July 12, 2011 Author Share Posted July 12, 2011 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. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 13, 2011 Share Posted July 13, 2011 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. Quote Link to comment Share on other sites More sharing options...
paulmcz Posted July 13, 2011 Author Share Posted July 13, 2011 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? Quote Link to comment Share on other sites More sharing options...
BlackBox Posted July 13, 2011 Share Posted July 13, 2011 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.