Jump to content

Recommended Posts

Posted

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

  • Replies 27
  • Created
  • Last Reply

Top Posters In This Topic

  • Lee Mac

    9

  • alanjt

    8

  • Pete_IC

    8

  • SEANT

    2

Posted

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,

Posted

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

Posted

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

Posted

Anyone got any idea how to do this?

Posted

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

Posted

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?

Posted

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

Posted

thanks very much Lee Mac, that's just what I wanted.

Posted

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

Posted

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

Posted
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.:P Excellent way of evaluating the final list BTW.

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

Posted
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 :thumbsup: 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.

Posted
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++?

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

Posted
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.)?

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

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