Author Topic: Put every nth block in a selection set from a long row of blocks  (Read 3280 times)

0 Members and 1 Guest are viewing this topic.

jaydee

  • Guest
Put every nth block in a selection set from a long row of blocks
« on: September 18, 2011, 04:42:39 AM »
Hi.
This post gave me idea to intitial this post
http://www.theswamp.org/index.php?topic=39480.0

Tunnel lighting (thousands of lights in one direction)
What i would like is to select all the blocks in the row but only ie. Put every fourth light or every fifth light (user define) into a selection set

Please help me to rebuilt the list, i just simplfy a list of all selected blocks basepoints
list 1
Code: [Select]
'(
(1 0 0)(2 0 0)(3 0 0)(4 0 0)(5 0 0)(6 0 0)(7 0 0)(8 0 0)(9 0 0)(10 0 0)(11 0 0)(12 0 0)
(13 0 0)(14 0 0)(15 0 0)(16 0 0)(17 0 0)(18 0 0)(19 0 0)(20 0 0)(21 0 0)(22 0 0)(23 0 0)(24 0 0)
)
User specify the nth item. ie every 4th in the list and the result
list 2 =
Code: [Select]
'(
(4 0 0)(8 0 0)((12 0 0)(16 0 0)(20 0 0)(24 0 0)
)
and here is what i come up with, the thing i think is missing i a list of every nth item.
Code: [Select]
;;;This function is from Tony T
(defun find-nearest-x (pt plist fuzz / x y dist ylist res)
 (setq x (car pt) y (car pt))
 (setq dist (abs (apply '- (minmax (mapcar 'car plist)))))
   (foreach point plist
     (if (and (equal (car point) x fuzz)
            (> dist (abs (- (car point) x)))
         )
     (setq dist (abs (- (car point) x))
              res point
     )
   )
)
res
)

(defun minmax (numlist)
(mapf '(min max) numlist)
)

(defun mapf (funcs lst)
(mapcar '(lambda (f) (apply f lst)) funcs)
)
Code: [Select]
(defun c:Test  (/ myset fuzz fuzzang getline enlist linelength lineang sset ssentity index name ent p1 p2 sslinang dist)

(setq myset (ssadd))
(setq fuzz  (* 0.01 (getvar "dimscale")))

(setq sset (ssget))

(setq Index 0)
  (while (< Index (sslength sset))
    (setq Lst (cons (cdr (assoc 10 (entget (ssname sset Index)))) Lst)
             Index (1+ Index)
    )
  )
(setq Lst (reverse Lst))
;;;(setq z Lst)


(setq XListOrder (vl-sort Lst '(lambda (p1 p2) (< (car p1) (car p2)))))

  (setq index 0)
   (while (< index (sslength sset))
    (setq name (ssname sset index))
    (setq ent (entget name))
    (setq p1 (cdr (assoc 10 ent)))

     (if (find-nearest-x p1 lst fuzz)
      (setq myset (ssadd name myset))
     )
     (setq index (1+ index))
    )
    (sssetfirst nil myset)

(princ)
)
« Last Edit: September 18, 2011, 07:13:55 PM by jaydee »

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Put every nth block in a selection set from a long row of blocks
« Reply #1 on: September 18, 2011, 07:54:40 AM »
If the list is presorted, maybe:

Code: [Select]
(defun nth-lst (lst / n i output)

  (initget 7)
  (setq n (getint "\nAtom To Strip:   "))

  (setq i 1)
  (foreach a lst
    (if (zerop (rem i n))
        (setq output (cons (nth (1- i) lst) output)))
    (setq i (1+ i)))

  (reverse output))

-David
R12 Dos - A2K

Lee Mac

  • Seagull
  • Posts: 12924
  • London, England
Re: Put every nth block in a selection set from a long row of blocks
« Reply #2 on: September 18, 2011, 11:25:41 AM »
Or:

Code: [Select]
(defun Every-Nth-Item ( n l / i )
    (setq i 0)
    (vl-remove-if-not '(lambda ( x ) (zerop (rem (setq i (1+ i)) n))) l)
)

IMO, 'n' should be zero-based though.

jaydee

  • Guest
Re: Put every nth block in a selection set from a long row of blocks
« Reply #3 on: September 18, 2011, 07:16:01 PM »
Thankyou David and Lee

Both work great.
Not sure when im going to do another tunnel job so i could utilise this routine.

Cheers

pBe

  • Bull Frog
  • Posts: 402
Re: Put every nth block in a selection set from a long row of blocks
« Reply #4 on: September 19, 2011, 02:04:46 AM »
Or:

Code: [Select]
(defun Every-Nth-Item ( n l / i )
    (setq i 0)
    (vl-remove-if-not '(lambda ( x ) (zerop (rem (setq i (1+ i)) n))) l)
)

IMO, 'n' should be zero-based though.


I wrote the code almost identical to Lee's

Code: [Select]
(defun Every (n lst / cnt)
(setq cnt 0)
(vl-remove-if-not '(lambda (l)
                         (if (= (rem (setq cnt (1+ cnt)) n) 0) l))
                             lst)
  )

Guess that means i'm better now since the i started coding again a year and so ago.

Thank you all from the bottom of my heart.
 :-)

jaydee

  • Guest
Re: Put every nth block in a selection set from a long row of blocks
« Reply #5 on: September 19, 2011, 08:01:30 AM »
Hi.
The code i used from Tony T seem a bit over complicated for this purpose.
Could some please show me a simpler solution of
comparing if a point is in the list. Also is a fuzz factor require when comparing points??

Code: [Select]
(if (12 0 0) ;;; is in the list below
'((4 0 0)(8 0 0)((12 0 0)(16 0 0)(20 0 0)(24 0 0))
)
==> T

Is this the right solution, it seems to be working
Code: [Select]
(defun IsPoint-inList (pt pointlist)
 (vl-some
  '(lambda (p)
    (equal pt p 0.001)
   )
   pointlist
 )
)

Thankyou
« Last Edit: September 19, 2011, 08:26:21 AM by jaydee »

Ketxu

  • Newt
  • Posts: 109
Re: Put every nth block in a selection set from a long row of blocks
« Reply #6 on: September 19, 2011, 10:59:58 PM »
Maybe you should put 0.001 (fuzz) as an argument ?

pBe

  • Bull Frog
  • Posts: 402
Re: Put every nth block in a selection set from a long row of blocks
« Reply #7 on: September 19, 2011, 11:41:54 PM »
Hi.
The code i used from Tony T seem a bit over complicated for this purpose.
Could some please show me a simpler solution of
comparing if a point is in the list. Also is a fuzz factor require when comparing points??

Code: [Select]
(if (12 0 0) ;;; is in the list below
'((4 0 0)(8 0 0)((12 0 0)(16 0 0)(20 0 0)(24 0 0))
)
==> T

One way.
Code: [Select]
(defun Mmbr  (itm lst / a F)
  (while
    (setq a (car lst))
     (if (or (equal itm lst)
     (member itm a))
       (setq lst nil
     F T)
       (setq lst (cdr lst))
       )
     )
  (if (null F)
    lst
    T))

(Mmbr '(12 0 0) '((4 0 0)(8 0 0)((12 0 0)(16 0 0)(20 0 0)(24 0 0))))
T

Sometimes I  cheat when faced with nested list  :wink:

Code: [Select]
(defun Cheat  (itm lst)
  (if (vl-string-search
(vl-princ-to-string itm)
(vl-princ-to-string lst))
    T
    nil))




jaydee

  • Guest
Re: Put every nth block in a selection set from a long row of blocks
« Reply #8 on: September 20, 2011, 01:46:04 AM »
Thankyou Pbe for the code and Ketxu for advice

Ketxu

  • Newt
  • Posts: 109
Re: Put every nth block in a selection set from a long row of blocks
« Reply #9 on: September 20, 2011, 03:07:59 AM »
Sometimes I  cheat when faced with nested list  :wink:
Code: [Select]
(defun Cheat  (itm lst)
  (if (vl-string-search
(vl-princ-to-string itm)
(vl-princ-to-string lst))
    T
    nil))
Nice cheat pBe ^^
Code: [Select]
(defun Cheat  (itm lst)
  (and (vl-string-search
(vl-princ-to-string itm)
(vl-princ-to-string lst))))

pBe

  • Bull Frog
  • Posts: 402
Re: Put every nth block in a selection set from a long row of blocks
« Reply #10 on: September 20, 2011, 03:35:37 AM »
Thank you Ketxu, there are times you can get away with it,  but not ALL the time  :laugh:

jaydee

  • Guest
Re: Put every nth block in a selection set from a long row of blocks
« Reply #11 on: September 20, 2011, 08:57:31 PM »
Thankyou for your input.
Here is a complete routine that select the nth block in a long linear of blocks
Code: [Select]
(defun c:TEST  (/ myset fuzz response Lst LstNth ListOrder sset index name ent p1 p2 ListOrder n)

(setq mySet nil)
(setq Lst nil)
(setq fuzz (* 0.001 (getvar "dimscale")))
(setq myset (ssadd))

(if (null default)
 (setq default "L")
)

(setq response nil)
 (while (not (ok_response_test response))
  (setq response
(strcase
(getstring
  (strcat
   "\nSorting from  [L]eft,  [R]ight,  [T]op,  [B]tm   <" default ">: "
  )
)
)
  )
  (if (ok_response_test response)
   (if (equal response "")
    (setq response default)
    (setq default response)
   )
   (prompt "\n**Your Entry was Invalid, Please Re-enter...")
  )
 )

(if (/= (type #n) 'STR)(setq #n "3"))

(initget 6)
(if (setq n (getint (strcat "\nEnter the Selection Interval, ie  3  for Every Third Item:   <"#n ">: ")))
  (setq #n (itoa n))
  (setq n (atoi #n))
)

(prompt "\nSelect All Block Along the Layout")
(setq sset (ssget '((0 . "INSERT"))))

(setq Index 0)
  (while (< Index (sslength sset))
    (setq Lst (cons (cdr (assoc 10 (entget (ssname sset Index)))) Lst)
             Index (1+ Index)
    )
  )

(cond
  ((= response "L") (setq ListOrder (vl-sort Lst '(lambda (p1 p2) (< (car p1) (car p2)))))
(setq LstNth (Every-Nth-Item n ListOrder))
  );;;x sort
  ((= response "R") (setq ListOrder (vl-sort Lst '(lambda (p1 p2) (< (car p1) (car p2)))))
(setq LstNth (Every-Nth-Item n (reverse ListOrder)))
  );;;-x sort
  ((= response "T") (setq ListOrder (vl-sort Lst '(lambda (p1 p2) (< (cadr p1) (cadr p2)))))
(setq LstNth (Every-Nth-Item n (reverse ListOrder)))
  );;;y sort
  ((= response "B") (setq ListOrder (vl-sort Lst '(lambda (p1 p2) (< (cadr p1) (cadr p2)))))
(setq LstNth (Every-Nth-Item n ListOrder))
  );;;-y sort
)

  (setq index 0)
   (while (< index (sslength sset))
    (setq name (ssname sset index))
    (setq ent (entget name))
    (setq p1 (cdr (assoc 10 ent)))

      (if (IsPtInList p1 LstNth fuzz)
       (setq myset (ssadd name myset))
      )

     (setq index (1+ index))
    )
    (sssetfirst nil myset)

(princ))

;;;============================================

(defun ok_response_test (response)
 (if (or (= response "L")
          (= response "R")
          (= response "T")
          (= response "B")
          (= response "")
     )
  t
  nil
 )
)

;;;============================================

(defun IsPtInList (pt pointlist fuzz)
(vl-some
  '(lambda (p)
    (equal pt p fuzz)
   )
   pointlist
)
)

;;;============================================

(defun Every-Nth-Item ( n ListOrder / i )
    (setq i 0)
    (vl-remove-if-not '(lambda ( x ) (zerop (rem (setq i (1+ i)) n))) ListOrder)
)

Lee Mac

  • Seagull
  • Posts: 12924
  • London, England
Re: Put every nth block in a selection set from a long row of blocks
« Reply #12 on: September 21, 2011, 06:49:48 AM »
Look into the getkword and initget functions  :wink:

jaydee

  • Guest
Re: Put every nth block in a selection set from a long row of blocks
« Reply #13 on: September 21, 2011, 10:16:01 PM »
Look into the getkword and initget functions  :wink:


I see. Thankyou Lee

Lee Mac

  • Seagull
  • Posts: 12924
  • London, England
Re: Put every nth block in a selection set from a long row of blocks
« Reply #14 on: September 22, 2011, 07:20:31 AM »
Look into the getkword and initget functions  :wink:

I see. Thankyou Lee

You're welcome, this may also help in that respect  :-)