TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: cmwade77 on November 25, 2014, 01:51:03 PM

Title: Comparing List of Points
Post by: cmwade77 on November 25, 2014, 01:51:03 PM
Ok, I have a list of points from two different polyline objects. I need to compare to see if the list points are identical, but I need to account for the fact that the order of the points may be different. Any ideas on how to accomplish this?
Title: Re: Comparing List of Points
Post by: Tharwat on November 25, 2014, 02:03:27 PM
Try this .
lst-1 represents the first list as well the second one .

Code - Auto/Visual Lisp: [Select]
  1. (vl-every '(lambda (q p) (equal q p 1e-8)) lst-1 lst-2)
  2.  
Title: Re: Comparing List of Points
Post by: cmwade77 on November 25, 2014, 02:13:39 PM
Perhaps I am doing something wrong, here is what I have:
Code: [Select]
(setq PtA (vlax-safearray->list (vlax-variant-value retCoordA))
PtB (vlax-safearray->list (vlax-variant-value retCoordB))
)
(if (vl-every '(lambda (q p) (equal q p 1e-8)) PtA PtB)
     (alert "Objects are the same")
     (alert "Objects are different")
)
Even when the objects are the same, it returns that they are different.
Title: Re: Comparing List of Points
Post by: ribarm on November 25, 2014, 02:21:11 PM
Code - Auto/Visual Lisp: [Select]
  1. (vl-every '(lambda ( x ) (eq x T)) (mapcar '(lambda ( x ) (vl-some '(lambda ( y ) (equal x y 1e-5)) lst-1)) lst-2))
  2.  

The same as Tharwat explained lst-1 and lst-2 are point lists...
Title: Re: Comparing List of Points
Post by: Tharwat on November 25, 2014, 02:21:58 PM
Post the two lists PtA and PtB to have a close look .
Title: Re: Comparing List of Points
Post by: cmwade77 on November 25, 2014, 02:58:01 PM
Ok, here are the list of points:
PtA - (9.34785 4.79562 9.34785 5.55109 10.2356 5.55109 10.2356 4.79562)
PtB - (9.34785 5.55109 9.34785 4.79562 10.2356 5.55109 10.2356 4.79562)
Title: Re: Comparing List of Points
Post by: ribarm on November 25, 2014, 03:08:01 PM
Code: [Select]
Command: (setq lst-1 '(9.34785 4.79562 9.34785 5.55109 10.2356 5.55109 10.2356
4.79562))
(9.34785 4.79562 9.34785 5.55109 10.2356 5.55109 10.2356 4.79562)

Command: (setq lst-2 '(9.34785 5.55109 9.34785 4.79562 10.2356 5.55109 10.2356
4.79562))
(9.34785 5.55109 9.34785 4.79562 10.2356 5.55109 10.2356 4.79562)

Command: (vl-every '(lambda ( x ) (eq x T)) (mapcar '(lambda ( x ) (vl-some
'(lambda ( y ) (equal x y 1e-5)) lst-1)) lst-2))
T

Command: (vl-every '(lambda (q p) (equal q p 1e-8)) lst-1 lst-2)
nil

My and Tharwat's codes...
HTH
Title: Re: Comparing List of Points
Post by: Lee Mac on November 25, 2014, 05:59:59 PM
Code - Auto/Visual Lisp: [Select]
  1. (vl-every '(lambda ( x ) (eq x T)) (mapcar '(lambda ( x ) (vl-some '(lambda ( y ) (equal x y 1e-5)) lst-1)) lst-2))
  2.  
The same as Tharwat explained lst-1 and lst-2 are point lists...

This can be reduced to:
Code - Auto/Visual Lisp: [Select]
  1. (vl-every '(lambda ( x ) (vl-some '(lambda ( y ) (equal x y 1e-8)) PtB)) PtA)
Title: Re: Comparing List of Points
Post by: Lee Mac on November 25, 2014, 06:03:11 PM
Or recursively,
Code - Auto/Visual Lisp: [Select]
  1. (defun f ( l1 l2 )
  2.     (or (null l1) (and (g (car l1) l2) (f (cdr l1) l2)))
  3. )
  4. (defun g ( x l )
  5.     (and l (or (equal x (car l) 1e-8) (g x (cdr l))))
  6. )
Code - Auto/Visual Lisp: [Select]
  1. (f PtA PtB)
Title: Re: Comparing List of Points
Post by: roy_043 on November 26, 2014, 05:15:58 AM
... to see if the list points are identical...
Do you want to check if the polylines overlap? If so, the order of the points is still important. Also the OCS and the elevation should be taken into account.
Title: Re: Comparing List of Points
Post by: Patrick_35 on November 26, 2014, 06:07:33 AM
Hi

To compare two list without vl-every
Code: [Select]
(setq lst-1 '(9.34785 4.79562 9.34785 5.55109 10.2356 5.55109 10.2356 4.79562))
(setq lst-2 '(9.34786 4.79563 9.34786 5.55110 10.2357 5.55110 10.2357 4.79563))

(equal lst-1 lst-2 1e-4) --> T
(equal lst-1 lst-2 1e-5) --> nil

@+
Title: Re: Comparing List of Points
Post by: Kerry on November 26, 2014, 07:11:43 AM
Hi

To compare two list without vl-every

< ... >


(equal lst-1 lst-2 1e-4) --> T
(equal lst-1 lst-2 1e-5) --> nil

:-)
Title: Re: Comparing List of Points
Post by: cmwade77 on November 26, 2014, 11:27:34 AM
Hi

To compare two list without vl-every

< ... >


(equal lst-1 lst-2 1e-4) --> T
(equal lst-1 lst-2 1e-5) --> nil

:-)
This only seems to work if the order is identical.
Title: Re: Comparing List of Points
Post by: Kerry on November 26, 2014, 05:31:06 PM
< .. >
This only seems to work if the order is identical.

Yes,
I tried to visualise the use for comparing point lists where the point order does not matter.
.... wasn't successful.
Care to share the purpose of the test ?
Title: Re: Comparing List of Points
Post by: roy_043 on November 27, 2014, 03:22:43 AM
... to see if the list points are identical...
Do you want to check if the polylines overlap? If so, the order of the points is still important. Also the OCS and the elevation should be taken into account.
Title: Re: Comparing List of Points
Post by: Patrick_35 on November 27, 2014, 05:49:48 AM
Hi

To compare two list without vl-every

< ... >


(equal lst-1 lst-2 1e-4) --> T
(equal lst-1 lst-2 1e-5) --> nil

:-)
This only seems to work if the order is identical.
Yes, the goal is to see if the two lists are identical
Now, if the order does not matter, we can do
Code: [Select]
(equal (vl-sort lst-1 '<) (vl-sort lst-2 '<) 1e-4)
@+
Title: Re: Comparing List of Points
Post by: Lee Mac on November 27, 2014, 12:13:05 PM
Now, if the order does not matter, we can do
Code: [Select]
(equal (vl-sort lst-1 '<) (vl-sort lst-2 '<) 1e-4)
@+

Be careful with vl-sort:
Code: [Select]
_$ (setq lst-1 '(1 2 3 4 4 5) lst-2 '(1 2 2 3 4 5))
(1 2 2 3 4 5)
_$ (equal (vl-sort lst-1 '<) (vl-sort lst-2 '<) 1e-4)
T
Title: Re: Comparing List of Points
Post by: ribarm on November 27, 2014, 12:47:40 PM
Now, if the order does not matter, we can do
Code: [Select]
(equal (vl-sort lst-1 '<) (vl-sort lst-2 '<) 1e-4)
@+

Be careful with vl-sort:
Code: [Select]
_$ (setq lst-1 '(1 2 3 4 4 5) lst-2 '(1 2 2 3 4 5))
(1 2 2 3 4 5)
_$ (equal (vl-sort lst-1 '<) (vl-sort lst-2 '<) 1e-4)
T

1+

Maybe...
Code: [Select]
(defun f ( lst-1 lst-2 )
  (if (and (listp (car lst-1)) (listp (car lst-2)))
    (equal
      (mapcar 'nth
        (vl-sort-i lst-1 '(lambda ( a b ) (< (distance '(0.0 0.0 0.0) a) (distance '(0.0 0.0 0.0) b))))
        (mapcar '(lambda ( x ) lst-1) lst-1)
      )
      (mapcar 'nth
        (vl-sort-i lst-2 '(lambda ( a b ) (< (distance '(0.0 0.0 0.0) a) (distance '(0.0 0.0 0.0) b))))
        (mapcar '(lambda ( x ) lst-2) lst-2)
      )
      1e-4
    )
    (equal
      (mapcar 'nth
        (vl-sort-i lst-1 '<)
        (mapcar '(lambda ( x ) lst-1) lst-1)
      )
      (mapcar 'nth
        (vl-sort-i lst-2 '<)
        (mapcar '(lambda ( x ) lst-2) lst-2)
      )
      1e-4
    )
  )
)
Title: Re: Comparing List of Points
Post by: roy_043 on November 27, 2014, 01:23:31 PM
I am stating the obvious here: Sorting a flat list of reals representing alternating X and Y coordinates of 2D points makes little sense.
Title: Re: Comparing List of Points
Post by: Lee Mac on November 27, 2014, 02:09:05 PM
I am stating the obvious here: Sorting a flat list of reals representing alternating X and Y coordinates of 2D points makes little sense.

Agreed, but then neither does comparing arbitrary X & Y values between the two lists - if I've understood what the OP is looking to achieve, I would have expected an ordered comparison up to permutation, e.g. something like:

Code - Auto/Visual Lisp: [Select]
  1. (defun compare ( a b )
  2.     (defun recurse ( a b c )
  3.         (and a (or (equal (append a c) b 1e-8) (recurse (cddr a) b (append c (list (car a) (cadr a))))))
  4.     )
  5.     (recurse a b nil)
  6. )
Code - Auto/Visual Lisp: [Select]
  1. _$ (compare '(1 2 3 4 5 6 7 8 9 0) '(5 6 7 8 9 0 1 2 3 4))
  2. T
Title: Re: Comparing List of Points
Post by: Patrick_35 on November 27, 2014, 03:02:30 PM
Now, if the order does not matter, we can do
Code: [Select]
(equal (vl-sort lst-1 '<) (vl-sort lst-2 '<) 1e-4)
@+

Be careful with vl-sort:
Code: [Select]
_$ (setq lst-1 '(1 2 3 4 4 5) lst-2 '(1 2 2 3 4 5))
(1 2 2 3 4 5)
_$ (equal (vl-sort lst-1 '<) (vl-sort lst-2 '<) 1e-4)
T
Oh yes, you are right, I had not seen that vl-sort truncates the result with integer
(vl-sort '(1 2 3 4 4 5) '<) --> (1 2 3 4 5)
(vl-sort '(1 2 2 3 4 5) '<) --> (1 2 3 4 5)
and (equal '(1 2 3 4 5) '(1 2 3 4 5)) return T

but (equal (vl-sort '(1.0 2.0 3.0 4.0 4.0 5.0) '<) (vl-sort '(1.0 2.0 2.0 3.0 4.0 5.0) '<)) work
and (equal (vl-sort '(1.0 2.0 3.0 4.0 4.0 5.0) '<) (vl-sort '(1.0 2.0 2.0 3.0 4.0 5.0) '<) 1e-4) work too

@+
Title: Re: Comparing List of Points
Post by: Marc'Antonio Alessi on November 27, 2014, 03:50:52 PM
Oh yes, you are right, I had not seen that vl-sort truncates the result with integer
Only with integers:
Code: [Select]
(vl-sort  '(3 2 1 3 1 2 2 2 1.0 1.0 1.0 1.0) '<)
(1 1.0 1.0 1.0 1.0 2 3)

(vl-sort  '("a" "A" "a") '<)
("A" "a" "a")

(vl-sort  '("a" "A" "a" "A") '<)
("A" "A" "a" "a")
Title: Re: Comparing List of Points
Post by: roy_043 on November 27, 2014, 04:38:25 PM
Iterative approach:
Code - Auto/Visual Lisp: [Select]
  1. (defun Roy_Compare (lstA lstB / num revLstB)
  2.   (if (= (setq num (length lstA)) (length lstB))
  3.     (progn
  4.       (while
  5.         (and
  6.           (> num 0)
  7.           (not (equal lstA lstB 1e-8))
  8.         )
  9.         (setq num (- num 2))
  10.         (setq lstA (append (cddr lstA) (list (car lstA) (cadr lstA))))
  11.       )
  12.       (/= num 0)
  13.     )
  14.   )
  15. )

Code - Auto/Visual Lisp: [Select]
  1. (Roy_Compare '(1 2 3 4 5 6 7 8 9 0) '(5 6 7 8 9 0 1 2 3 4))

Of course there is still the issue of polylines that overlap but are reversed.
Title: Re: Comparing List of Points
Post by: cmwade77 on December 01, 2014, 11:20:03 AM
< .. >
This only seems to work if the order is identical.

Yes,
I tried to visualise the use for comparing point lists where the point order does not matter.
.... wasn't successful.
Care to share the purpose of the test ?
Yes, I am using the boundary command to generate plines and as a result there are some instances where a duplicate polyline gets created but with a different order for the points. This causes the overkill command to fail to identify that they are identical and delete the duplicate. Basically, the polylines need to be identical, but the order that the points were drawn in do not need to be identical.