Author Topic: How can I know if the shapes are the same?  (Read 9024 times)

0 Members and 1 Guest are viewing this topic.

litss

  • Guest
How can I know if the shapes are the same?
« on: February 16, 2009, 09:08:13 AM »
I wish I could find a way to group shapes(closed pline) that are the same. But it is hard for me. Any one have a good idea? Thx!

Attached is a fig. If I select all the shapes by "ssget", I want a way to find out the "1" and "2", which are the same shapes.



CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: How can I know if the shapes are the same?
« Reply #1 on: February 16, 2009, 10:13:57 AM »
There are lots of common items that can be compared but absolute conformation may be complex.

This is what I would check.
Both are LWPolylines
Both are closed or open
They have the same length & area
They have the same number of segments
May not need this one but check that the segment lengths are the same

That should be a good test.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

ronjonp

  • Needs a day job
  • Posts: 7527
Re: How can I know if the shapes are the same?
« Reply #2 on: February 16, 2009, 10:29:34 AM »
There are lots of common items that can be compared but absolute conformation may be complex.

This is what I would check.
Both are LWPolylines
Both are closed or open
They have the same length & area
They have the same number of segments
May not need this one but check that the segment lengths are the same

That should be a good test.

That's scary...this is what I was starting to write. :-D

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: How can I know if the shapes are the same?
« Reply #3 on: February 16, 2009, 10:59:42 AM »
You are just being LOGICAL.  :lmao:
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

litss

  • Guest
Re: How can I know if the shapes are the same?
« Reply #4 on: February 16, 2009, 11:15:59 AM »
Quote
Both are LWPolylines
Both are closed or open
They have the same length & area
They have the same number of segments
May not need this one but check that the segment lengths are the same

It's for sure: Both are LWPolylines & Both are closed
And I can do comparison of length & area. But it's not enough. There are hundreds of plines in my draft, length & area are all close to each other.
:( the problem is how to check each segment length? starting from which leg of the plines?  it might be a huge comparison. quite hard for me...

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: How can I know if the shapes are the same?
« Reply #5 on: February 16, 2009, 11:51:22 AM »
Look into these functions. They will get you what you need.
Code: [Select]
(vlax-curve-getarea curve-obj)
(vlax-curve-getclosestpointto curve-obj givenPnt [extend])
(vlax-curve-getclosestpointtoprojection curve-obj givenPnt normal [extend])
(vlax-curve-getdistatparam curve-obj param)
(vlax-curve-getdistatpoint curve-obj point)
(vlax-curve-getendparam curve-obj)
(vlax-curve-getendpoint curve-obj)
(vlax-curve-getfirstderiv curve-obj param)
(vlax-curve-getparamatdist curve-obj dist)
(vlax-curve-getparamatpoint curve-obj point)
(vlax-curve-getpointatdist curve-obj dist)
(vlax-curve-getpointatparam curve-obj param)
(vlax-curve-getsecondderiv curve-obj param)
(vlax-curve-getstartparam curve-obj)
(vlax-curve-getstartpoint curve-obj)
(vlax-curve-isClosed ent) ; true if Closed
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Spike Wilbury

  • Guest

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: How can I know if the shapes are the same?
« Reply #7 on: February 16, 2009, 04:56:39 PM »
That is a very good link. Thanks 8-)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Spike Wilbury

  • Guest
Re: How can I know if the shapes are the same?
« Reply #8 on: February 16, 2009, 05:09:24 PM »
That is a very good link. Thanks 8-)

Yes... Alan,

That's one of my old url kept for quite a while.... :)




ps> using a default name - me

SomeCallMeDave

  • Guest
Re: How can I know if the shapes are the same?
« Reply #9 on: February 16, 2009, 05:15:05 PM »
I haven't done a rigorous proof (have done no proof at all really), but it would seem to me that the sum of the distances from the centroid to each vertex would be a unique value for each shape and would be independent of the rotation of the shape.

And it would be a quick calculation:
  for each shape:
          calc the centroid
          build a vertex list (just an (assoc 10) list since the OP said all shapes are LwPoly)
          then sum the distances ->     (apply '+ (mapcar '(lambda (x) (distance x centroid)) vertlist))

Build a list containing each value, find the matches, use the index of the list to pull the entities from the selection set.

Almost writes itself  :)


         
         

ronjonp

  • Needs a day job
  • Posts: 7527
Re: How can I know if the shapes are the same?
« Reply #10 on: February 16, 2009, 05:33:53 PM »
Give this a try....seems to work OK for me  :-)  **will not work if you reverse the vertexes  fixed.

Code: [Select]
(defun c:similar_polylines (/ d lst n n2 obj out ss)
  (setq n -1)
  (if (setq ss (ssget '((0 . "LWPOLYLINE"))))
    (progn (repeat (sslength ss)
             (setq obj (vlax-ename->vla-object (ssname ss (setq n (1+ n))))
                   n2  0.0
                   d   nil
             )
             ;;get distances between vertexes  **accuracy is 5 decimal places
             (repeat (fix (vlax-curve-getendparam obj))
               (setq d (cons (rtos (distance (vlax-curve-getpointatparam obj n2)
                                             (vlax-curve-getpointatparam obj (setq n2 (1+ n2)))
                                   )
                                   2
                                   5
                             )
                             d
                       )
               )
             )
             ;;put all the information into the list to check
             (setq lst (cons (list obj
                                   (rtos (vla-get-area obj) 2 5)
                                   (vla-get-closed obj)
                                   (rtos (vla-get-length obj) 2 5)
                                   (vlax-curve-getendparam obj)
                                   (vl-sort d '>)
                             )
                             lst
                       )
             )
           )
           ;;iterate the list checking for more than one occurence of the first element properties
           (foreach pl lst
             (if (> (length (vl-remove-if-not '(lambda (x) (equal x (cdr pl)))
                                              (mapcar 'cdr lst)
                            )
                    )
                    1
                 )
               (setq out (cons (car pl) out))
             )
           )
    )
  )
  ;;(foreach x out (vla-put-color x 3))
  ;;quick check
  out
)
(c:similar_polylines)


« Last Edit: February 16, 2009, 06:17:57 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

litss

  • Guest
Re: How can I know if the shapes are the same?
« Reply #11 on: February 17, 2009, 01:48:38 AM »
Thx all of u guys! helped me a lot..

to:  David Blackmon
I like ur way "the sum of the distances from the centroid". I'll try it tonight :)

to: ronjonp
ur routine runs perfectly. And I made some modification so that it could group each kind of shapes as a list. Hope you don't mind. I am poor at programing, so it might not look as clean as urs :). here's it:

Code: [Select]
(defun c:similar_polylines (/ d lst n n2 obj out ss)
  (setq n -1)
  (if (setq ss (ssget '((0 . "LWPOLYLINE"))))
    (progn
      (repeat (sslength ss)
        (setq obj (vlax-ename->vla-object (ssname ss (setq n (1+ n))))
              n2 0.0
              d nil
        )             ;;get distances between vertexes  **accuracy is 5 decimal places
        (repeat (fix (vlax-curve-getendparam obj))
          (setq d (cons (rtos (distance (vlax-curve-getpointatparam obj n2)
                                        (vlax-curve-getpointatparam obj (setq n2 (1+ n2)))
                              ) 2 5
                        ) d
                  )
          )
        )             ;;put all the information into the list to check
        (setq lst (cons (list obj (rtos (vla-get-area obj) 2 5) (vla-get-closed obj) (rtos
                                                                                           (vla-get-length obj)
                                                                                           2 5
                                                                                     )
                              (vlax-curve-getendparam obj) (vl-sort d '>)
                        ) lst
                  )
        )
      )           ;;iterate the list checking for more than one occurence of the first element properties
   ;;;------------------modified------------------------------------------------
      (setq out '())
      (while (> (length lst) 0)
        (setq pl (car lst))
        (setq lst0 (vl-remove-if-not '(lambda (x)
                                        (equal (cdr x) (cdr pl))
                                      ) lst
                   )
        )
        (setq out (cons lst0 out))
        (setq n 0)
        (repeat (length lst0)
          (setq pl (nth n lst0))
          (setq lst (vl-remove-if '(lambda (x)
                                     (equal (cdr x) (cdr pl))
                                   ) lst
                    )
          )
          (setq n (1+ n))
        );repeat
      );while
    )
  )
  (setq n 3)
  (foreach x out
    (setq n (1+ n))
    (foreach y x
      (vla-put-color (car y) n)
    )
  )  ;;quick check
  ;;;------------------modified------------------------------------------------
)
(c:similar_polylines)

ronjonp

  • Needs a day job
  • Posts: 7527
Re: How can I know if the shapes are the same?
« Reply #12 on: February 17, 2009, 10:18:12 AM »
Glad it worked for you :)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

ronjonp

  • Needs a day job
  • Posts: 7527
Re: How can I know if the shapes are the same?
« Reply #13 on: February 17, 2009, 10:41:11 AM »
Here is how I would group the objects as sublists.
Code: [Select]
(defun c:similar_polylines (/ d lst n n2 obj out ss sub)
  (setq n -1)
  (if (setq ss (ssget '((0 . "LWPOLYLINE"))))
    (progn (repeat (sslength ss)
             (setq obj (vlax-ename->vla-object (ssname ss (setq n (1+ n))))
                   n2  0.0
                   d   nil
             )
             ;;get distances between vertexes  **accuracy is 5 decimal places
             (repeat (fix (vlax-curve-getendparam obj))
               (setq
                 d (cons (rtos (distance (vlax-curve-getpointatparam obj n2)
                                         (vlax-curve-getpointatparam obj (setq n2 (1+ n2)))
                               )
                               2
                               5
                         )
                         d
                   )
               )
             )
             ;;put all the information into the list to check
             (setq lst (cons (list obj
                                   (rtos (vla-get-area obj) 2 5)
                                   (vla-get-closed obj)
                                   (rtos (vla-get-length obj) 2 5)
                                   (vlax-curve-getendparam obj)
                                   (vl-sort d '>)
                             )
                             lst
                       )
             )
           )
           ;;iterate the list checking for more than one occurence of the first element properties
           (foreach pl lst
             (if (> (length
                      (setq sub (vl-remove-if-not '(lambda (x) (equal (cdr x) (cdr pl)))
                                                  lst
                                )
                      )
                    )
                    1
                 )
               (progn (setq out (cons (mapcar 'car sub) out))
                      (setq lst (vl-remove-if '(lambda (x) (member x sub)) lst))
               )
             )
           )
    )
  )
  (setq n 0)
  (foreach pl out
    (setq n (1+ n))
    (mapcar '(lambda (x) (vla-put-color x n)) pl)
  )
  out
)
(c:similar_polylines)

Here is one using David's centroid\vertex distance method...same results as the one above  :-)

Code: [Select]
(defun c:similar_polylines (/ e lst m n out pts ss sub sum x)
  (setq n -1)
  (if (setq ss (ssget '((0 . "LWPOLYLINE"))))
    (progn (repeat (sslength ss)
             (setq e (ssname ss (setq n (1+ n))))
             (setq pts (mapcar 'cdr
                               (vl-remove-if-not '(lambda (x) (= 10 (car x))) (entget e))
                       )
                   m   (list (/ (apply '+ (mapcar 'car pts)) (length pts))
                             (/ (apply '+ (mapcar 'cadr pts)) (length pts))
                       )
                   ;;same 5 decimal precision
                   sum (apply '+
                              (mapcar 'atof
                                      (mapcar '(lambda (x) (rtos (distance m x) 2 5)) pts)
                              )
                       )
                   lst (cons (list e sum) lst)
             )
           )
           (foreach pl lst
             (if (> (length
                      (setq sub (vl-remove-if-not '(lambda (x) (equal (cdr x) (cdr pl)))
                                                  lst
                                )
                      )
                    )
                    1
                 )
               (progn (setq out (cons (mapcar 'car sub) out))
                      (setq lst (vl-remove-if '(lambda (x) (member x sub)) lst))
               )
             )
           )
    )
  )
  (setq n 0)
  (foreach pl out
    (setq n (1+ n))
    (mapcar '(lambda (x) (vla-put-color (vlax-ename->vla-object x) n))
            pl
    )
  )
  out
)
(c:similar_polylines)
« Last Edit: February 17, 2009, 11:44:52 AM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

SomeCallMeDave

  • Guest
Re: How can I know if the shapes are the same?
« Reply #14 on: February 17, 2009, 01:51:11 PM »
Very nice Ron.

I like your method of calculating the centroid.  Much more concise than mine.