Author Topic: Comparing List of Points  (Read 7143 times)

0 Members and 1 Guest are viewing this topic.

cmwade77

  • Swamp Rat
  • Posts: 1443
Comparing List of Points
« 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?

Tharwat

  • Swamp Rat
  • Posts: 710
  • Hypersensitive
Re: Comparing List of Points
« Reply #1 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.  

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Comparing List of Points
« Reply #2 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.

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Comparing List of Points
« Reply #3 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...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Tharwat

  • Swamp Rat
  • Posts: 710
  • Hypersensitive
Re: Comparing List of Points
« Reply #4 on: November 25, 2014, 02:21:58 PM »
Post the two lists PtA and PtB to have a close look .

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Comparing List of Points
« Reply #5 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)

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Comparing List of Points
« Reply #6 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
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Comparing List of Points
« Reply #7 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)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Comparing List of Points
« Reply #8 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)

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Comparing List of Points
« Reply #9 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.

Patrick_35

  • Guest
Re: Comparing List of Points
« Reply #10 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

@+

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Comparing List of Points
« Reply #11 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

:-)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Comparing List of Points
« Reply #12 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.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Comparing List of Points
« Reply #13 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 ?
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Comparing List of Points
« Reply #14 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.

Patrick_35

  • Guest
Re: Comparing List of Points
« Reply #15 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)
@+

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Comparing List of Points
« Reply #16 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

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Comparing List of Points
« Reply #17 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
    )
  )
)
« Last Edit: November 27, 2014, 01:07:11 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Comparing List of Points
« Reply #18 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.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Comparing List of Points
« Reply #19 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

Patrick_35

  • Guest
Re: Comparing List of Points
« Reply #20 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

@+

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1453
  • Marco
Re: Comparing List of Points
« Reply #21 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")

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Comparing List of Points
« Reply #22 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.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Comparing List of Points
« Reply #23 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.