Pete_IC Posted May 19, 2010 Posted May 19, 2010 Hi, Im trying to find a lisp that will give me the centre/midpoint of a set of polylines. I work with boats and often need to find the total length and the centre of gravity (midpoint) of a set of stiffeners in a hull, at the moment im using a LISP called Tlen to give me the total length of the stiffeners but have to estimate or manually calculate the cog, what I’m looking for is a lisp that will work out the combined midpoint of a number of polylines . I have attached an example of what I would be working with Thanks Pete Stiffeners.dwg Quote
MSasu Posted May 19, 2010 Posted May 19, 2010 Maybe this will help you: (defun c:MidPL( / PlinesSet thePline Dist1st Dist2nd PlineLen PointMid OldOsmode ) (setq OldOsmode (getvar "OSMODE")) (setvar "OSMODE" 0) (prompt "\nSelect polylines to mark middle point:") (if (and (setq PlinesSet (ssget '((0 . "LWPOLYLINE")))) ;select polylines (> (sslength PlinesSet) 0)) (while (> (sslength PlinesSet) 0) (setq thePline (ssname PlinesSet 0)) (setq Dist1st (vlax-curve-getDistAtPoint thePline (vlax-curve-getStartPoint thePline)) Dist2nd (vlax-curve-getDistAtPoint thePline (vlax-curve-getEndPoint thePline)) PlineLen (- Dist2nd Dist1st) PointMid (vlax-curve-getPointAtDist thePline (+ Dist1st (* 0.5 PlineLen)))) (entmake (list (cons '0 "POINT") ;add point entity (cons '10 PointMid))) (setq PlinesSet (ssdel thePline PlinesSet)) ;remove processed polyline ) ) (setvar "OSMODE" OldOsmode) (princ) ) Regards, Quote
alanjt Posted May 19, 2010 Posted May 19, 2010 A little less legwork. (defun c:TEst (/ ss) (vl-load-com) (if (setq ss (ssget '((0 . "ARC,LINE,*POLYLINE")))) ((lambda (i) (while (setq e (ssname ss (setq i (1+ i)))) (entmakex (list '(0 . "POINT") (cons 10 (vlax-curve-GetPointAtDist e (/ (vlax-curve-GetDistAtParam e (vlax-curve-GetEndParam e)) 2.) ) ) ) ) ) ) -1 ) ) (princ) ) Quote
Pete_IC Posted May 19, 2010 Author Posted May 19, 2010 Thanks for both those replies, they will come in handy, but what im looking for is a little different. I don't know if want I want is possible but I don't see why it couldn't be done. Is there a way I can get the average distance of those points in one single number, I assume if I set a new USC at the start of the stiffeners then I should be able to get a X coordinate for the average mid point of those lines. I have attached the lisp I use to get the total length, if I could get something like this that could give me the average x or x and y locations for the mid point for the all the lines combined that would be fantastic. I have also attached a basic drawing to show the location I need to find. any more help would be very appreciated thanks Pete. tlen.lsp MidPoint.dwg Quote
Lee Mac Posted May 23, 2010 Posted May 23, 2010 Try this: (defun c:AveMid ( / ss ) ;; © Lee Mac ~ 24.05.10 (vl-load-com) (if (setq ss (ssget '((0 . "ARC,*POLYLINE,LINE")))) ( (lambda ( i / ent mLst l ) (while (setq ent (ssname ss (setq i (1+ i)))) (setq mLst (cons (vlax-curve-getPointatParam ent (/ (+ (vlax-curve-getEndParam ent) (vlax-curve-getStartParam ent)) 2.) ) mLst ) ) ) (setq l (length mLst)) ( (lambda ( p ) (entmakex (list (cons 0 "POINT") (cons 10 p) ) ) ) (mapcar (function /) (apply (function mapcar) (cons (function +) mLst ) ) (list l l l) ) ) ) -1 ) ) (princ) ) Quote
Pete_IC Posted May 23, 2010 Author Posted May 23, 2010 Thanks for the reply Lee Mac, when i use AveMid this is what im getting Command: avemid Select objects: 1 found Select objects: ; error: no function definition: VLAX-CURVE-GETENDPARAM any ideas? Quote
Lee Mac Posted May 23, 2010 Posted May 23, 2010 Thats just the Visual LISP functions not being loaded - code updated If ever you get that kind of thing again, just add (vl-load-com) to the top of the code. Most of us guys have (vl-load-com) called in an ACADDOC.lsp, so we don't notice if its missing Quote
Pete_IC Posted May 24, 2010 Author Posted May 24, 2010 thanks very much Lee Mac, that's just what I wanted. Quote
alanjt Posted May 24, 2010 Posted May 24, 2010 Nothing wrong with yours Lee. I was just curious about a different approach. Solely academic. (defun c:AvMid (/ ss lst) ;; Alan J. Thompson, 05.24.10 (if (setq ss (ssget '((0 . "ARC,LINE,*POLYLINE")))) ((lambda (i) (while (setq e (ssname ss (setq i (1+ i)))) (setq lst (cons (vlax-curve-getPointatParam e (/ (+ (vlax-curve-getEndParam e) (vlax-curve-getStartParam e) ) 2. ) ) lst ) ) ) (entmakex (list '(0 . "POINT") (cons 10 (mapcar (function (lambda (f) (/ (apply (function +) (mapcar (function f) lst)) (length lst) ) ) ) (list car cadr caddr) ) ) ) ) ) -1 ) ) (princ) ) Quote
Lee Mac Posted May 24, 2010 Posted May 24, 2010 Its good to post variations - gets the brain working... But bear in mind that your code is extremely inefficient - it has to churn through the selection set three times, then churn through the resultant list each time also... Quote
alanjt Posted May 24, 2010 Posted May 24, 2010 Its good to post variations - gets the brain working... But bear in mind that your code is extremely inefficient - it has to churn through the selection set three times, then churn through the resultant list each time also... Ugh, you're exactly right. I placed the stepping through the selection set portion within mapcar statement purely by accident. However, you are correct. Now that I look at it, the portion where it averages the points, it does step through the final list an un-required number of times. Guess that will teach me to code first thing in the morning. Excellent way of evaluating the final list BTW. Quote
alanjt Posted May 24, 2010 Posted May 24, 2010 Thanks mate So, your mapcar... (list l l l) is the equivalent to: (mapcar (function (lambda (x) (/ x l))) (apply (function mapcar) (cons (function +) mLst ) ) ) This piece of code is the shear brilliance. I'm throughly impressed. (apply (function mapcar) (cons (function +) mLst ) ) I've done something similar, but never to apply mapcar to it. A+ I would make one suggestion (very minor at that). I would have float'd my list length. (setq l (float (length mLst))) just to avoid dividing a real by an integer. Quote
Lee Mac Posted May 24, 2010 Posted May 24, 2010 So, your mapcar... (list l l l) is the equivalent to: (mapcar (function (lambda (x) (/ x l))) (apply (function mapcar) (cons (function +) mLst ) ) ) Exactly - I just thought it look neater the way I wrote it This piece of code is the shear brilliance. I'm throughly impressed. (apply (function mapcar) (cons (function +) mLst ) ) I've done something similar, but never to apply mapcar to it. A+ Thanks Alan There's only a few situations that it fits, I remember using that construct here also. I would make one suggestion (very minor at that). I would have float'd my list length. (setq l (float (length mLst))) just to avoid dividing a real by an integer. Nice catch - I wouldn't have thought of that - although I would think that the points returned by vlax-curve* are Doubles, it would perhaps mildly improve performance avoiding the the data type conversion ('type promotion' I believe - or at least it is in C++) when performing the division. Quote
alanjt Posted May 24, 2010 Posted May 24, 2010 Exactly - I just thought it look neater the way I wrote it Just confirming. Nice catch - I wouldn't have thought of that - although I would think that the points returned by vlax-curve* are Doubles, it would perhaps mildly improve performance avoiding the the data type conversion ('type promotion' I believe - or at least it is in C++) when performing the division. I've done the same thing before. I only noticed/thought about it when I was stepping through your code. Are you still working with learning C++? Quote
Lee Mac Posted May 24, 2010 Posted May 24, 2010 Are you still working with learning C++? Only console programs - getting used to the loops/conditionals/pointers etc.. I haven't looked at trying to apply it to AutoCAD in any way as yet, but I would say that I know the basics pretty well. Quote
alanjt Posted May 24, 2010 Posted May 24, 2010 Only console programs - getting used to the loops/conditionals/pointers etc.. I haven't looked at trying to apply it to AutoCAD in any way as yet, but I would say that I know the basics pretty well. Interesting. What are you using for knowledge base (book, etc.)? Quote
Lee Mac Posted May 24, 2010 Posted May 24, 2010 Interesting.What are you using for knowledge base (book, etc.)? Mainly a Book (by Herbert Schildt), and a few header references online - but its slow going, as I'm slightly paranoid about messing my system up, and so will only test something when I know it is completely correct (when dealing with arrays/pointers anyway).. Quote
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.