Author Topic: Unique List of Points  (Read 3175 times)

0 Members and 1 Guest are viewing this topic.

mailmaverick

  • Bull Frog
  • Posts: 495
Unique List of Points
« on: March 28, 2014, 06:38:08 AM »
I have a list containing various points in form of ( (x1 y1 z1) (x2 y2 z2) (x3 y3 z3).......)

Certain points in the list are same. I want to get unique list of points.

How to do that ?

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: Unique List of Points
« Reply #1 on: March 28, 2014, 06:58:07 AM »
Hi,

Try this:
Code - Auto/Visual Lisp: [Select]
  1. (defun gc:distinct (l)
  2.   (if l
  3.     (cons (car l) (gc:distinct (vl-remove (car l) l)))
  4.   )
  5. )

(gc:distinct thePointList)
Speaking English as a French Frog

mailmaverick

  • Bull Frog
  • Posts: 495
Re: Unique List of Points
« Reply #2 on: March 28, 2014, 07:07:31 AM »
Excellent !!!!!

Now can we add some fuzz factor into this ?

I mean all points shall be considered duplicate if their distance is less than 0.00001 m and any one of them shall be kept in the final list.




irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Unique List of Points
« Reply #3 on: March 28, 2014, 07:24:38 AM »
Not very efficient:
Code - Auto/Visual Lisp: [Select]
  1. (defun lst:unique (lst fuzz / result)
  2.   (while lst
  3.     (if (not (vl-some '(lambda (item) (equal item (car lst) fuzz)) result))
  4.       (setq result (cons (car lst) result)))
  5.     (setq lst (cdr lst)))
  6.   (reverse result))
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: Unique List of Points
« Reply #4 on: March 28, 2014, 08:01:35 AM »
Code - Auto/Visual Lisp: [Select]
  1. (defun gc:distinctFuzz (lst fuzz)
  2.   (if lst
  3.     (cons (car lst)
  4.           (gc:distinct
  5.             (vl-remove-if '(lambda (x) (equal x (car lst) fuzz)) lst)
  6.           )
  7.     )
  8.   )
  9. )

(gc:distinctFuzz thePointList 0.00001)
Speaking English as a French Frog

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Unique List of Points
« Reply #5 on: March 28, 2014, 08:18:49 AM »
Code - Auto/Visual Lisp: [Select]
  1. (defun gc:distinctFuzz (lst fuzz)
  2.   (if lst
  3.     (cons (car lst)
  4.           (gc:distinctFuzz
  5.             (vl-remove-if '(lambda (x) (equal x (car lst) fuzz)) lst)
  6.             fuzz
  7.           )
  8.     )
  9.   )
  10. )
FIFY :-D
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: Unique List of Points
« Reply #6 on: March 28, 2014, 08:30:54 AM »
Thanks Irne.
Speaking English as a French Frog

mailmaverick

  • Bull Frog
  • Posts: 495
Re: Unique List of Points
« Reply #7 on: March 28, 2014, 12:10:29 PM »
Thanks to all. Problem solved.

Lee Mac

  • Seagull
  • Posts: 12924
  • London, England
Re: Unique List of Points
« Reply #8 on: March 29, 2014, 02:07:52 PM »

mailmaverick

  • Bull Frog
  • Posts: 495
Re: Unique List of Points
« Reply #9 on: March 31, 2014, 03:55:43 AM »
I have a list (called LISTA) containing various points in form of ( (x1 y1 z1) (x2 y2 z2) (x3 y3 z3).......).

I want following functionalities :-

1.) How to get a new list (LISTB) of those points which are present in list only once. Note that this is not unique function as posted earlier in this post. All those points in the list LISTA whose distance is less than fuzz value must be considered as one point.

2.) How to get a new list (LISTC) of those points which are present in list only twice along with fuzz factor.

3.) How to compare that a point (P) in form of (xn yn zn) is present in (member of) list LISTA along with fuzz factor ?

Thanks.

Certain points in the list are same. I want to get unique list of points.

How to do that ?

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Unique List of Points
« Reply #10 on: March 31, 2014, 08:53:17 AM »
Have you tried the codes in this thread and Lee's page (which describes what they do)? They all literally take one list, then extract those values so the new list contains unique values.

What you're after is a way to get only the values which do not have duplicates. A very similar approach would work here:

Using the recursive method:
  • Start with the 1st item in the list - stop if the list is empty.
  • Check if it is inside the rest of the list (use the vl-some method as per my iterative approach).
  • If not (i.e. unique), then cons it into the result of calling the same function using the rest of the list.
  • Else (if duplicate found) only call the same function on the rest of the list.
Using the iterative approach:
  • Start with the 1st item in the list.
  • Check if it is inside the rest of the list (use the vl-some method as per my iterative approach).
  • If not (i.e. unique), then cons it into the result.
  • No else portion.
  • Change the list to only contain the rest of the list and repeat the loop.
  • After loop, return the result variable reversed to get the values in the original order.
Doing it for the duplicate counter is a bit more complicated. You'd need another list which counts how many times a particular value was found in the list. Then extract only those with the count the same number as specified.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Unique List of Points
« Reply #11 on: March 31, 2014, 09:07:48 AM »
Doing it for the duplicate counter is a bit more complicated. You'd need another list which counts how many times a particular value was found in the list. Then extract only those with the count the same number as specified.
For this I'd suggest getting a fuzzy version of assoc.

Iterative version
Code - Auto/Visual Lisp: [Select]
  1. (defun assoc-fuzz (key lst fuzz / found)
  2.   (while (and (setq found (car lst)) (not (equal key (car found) fuzz)))
  3.     (setq lst (cdr lst)))
  4.   found)
Recursive version:
Code - Auto/Visual Lisp: [Select]
  1. (defun assoc-fuzz (key lst fuzz)
  2.   (cond ((equal key (caar lst) fuzz) (car lst))
  3.         (lst (assoc-fuzz key (cdr lst) fuzz))))
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Unique List of Points
« Reply #12 on: March 31, 2014, 09:24:23 AM »
E.g. a general purpose one:
Code - Auto/Visual Lisp: [Select]
  1. (defun group-duplicates-fuzz (lst fuzz / result found)
  2.   (foreach item lst
  3.     (if (setq found (assoc-fuzz item result))
  4.       (setq result (subst (cons item found) found result))
  5.       (setq result (cons (list item) result))))
  6.   result)
  7.  
  8. (defun find-duplicates-fuzz (lst fuzz count)
  9.   (vl-remove-if-not '(lambda (item) (= (length item) count))
  10.     (group-duplicates-fuzz lst fuzz)))
Say you want all points which are duplicated once (i.e. 2 copies of in the list) with a fuzz-factor of 0.5:
Code - Auto/Visual Lisp: [Select]
  1. (find-duplicates-fuzz lst 0.5 2)
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

fixo

  • Guest
Re: Unique List of Points
« Reply #13 on: March 31, 2014, 10:13:17 AM »
Possible suitable such function to retrieve unique and identical pairs:
Code: [Select]
(defun uique_pairs  (lst fuzz / data result)
  (while (car lst)
    (if (and (setq pair (vl-remove-if-not
  '(lambda (x) (equal x (car lst) fuzz))
  lst))
     (>= (length pair)2))
      (setq result (append result (list (list (car pair) (cadr pair))))))
    (setq lst (vl-member-if '(lambda (a) (not (member a pair))) lst)))
  (reverse
    (while (setq pair (car result))
      (setq result (vl-remove pair result)
            data (cons pair data))))
  data
  )
;;usage (setq pairs (uique_pairs lst1 0.0001))