Jump to content
chayong91

Sorting Selection Set base on X axis

Recommended Posts

chayong91

Hi Sirs,

 

I'm just new on using autolisp and still learning so please help me on the dilemma i'm facing.

 

Basically i want to sort a selection set of polyline (rectangle) under the layer of "REF" basing on it's X axis. I copied bits of info around the net but i can't get it work the way i want it to.

 

Here is where i copied some of it.

http://forums.augi.com/showthread.php?137837-Sort-Selectionset-by-X-coord

 

(setq plt_set (ssget '((8 . "REF")))) ;select layer "REF"
 (setq count 1
count1 (sslength plt_set)
ss6 (ssadd)
ss4 (list (ssname plt_set (1- count)))
)

 (while (<= (1+ count) count1)        ;SORT LIST BY X COORD LOW TO HIGH
   (setq ss3 (list (ssname plt_set count)))
   (setq ss4 (append ss4 ss3))
   (setq count (1+ count))
 ) ;_ end of while
 
 (vl-sort ss4
 (function
   (lambda (a b) (> ;; or maybe > depending on the order you want
		   (cadr (assoc 10 (entget a)))
		   (cadr (assoc 10 (entget b)))
		   )
     )
   )
 )
 (foreach ss5 (reverse ss4)
   (setq ss6 (ssadd ss5 ss6))
   )

 

It is still sorting by the sequence of when it was created.

 

Hoping for your kind help Cad Masters.

 

Thank you,

Ryan

Share this post


Link to post
Share on other sites
Jef!

Hi Chayong91, and welcome to cadtutor.

 

 

I think the lack of replies is due to the fact that you didn't mention what your goal was. If you want to go in a said direction, I might provide you a car, but if there is a river and no bridge, you won't get to your destination that way. Different goals are inevitably achieved by different paths or approaches. I will try to get you some hints and clues hoping they will be helpful, because I liked the fact that you gave it a try. Here's some things to bare in mind for your project. The example you started from was to sort texts by their x values. Let's look at one.

 

(entget(car(entsel)))

If in command line you type (entsel), you are prompted to select an object. That will return something like ( (2.67556 -0.164706 0.0)), which is a list containing the entity name (often reffered as Ename) of the object you selected, followed by the coordinate you picked. If you would like to see what defines that entity, you need to use the entget function. The entget function needs to be supplied with an Ename. There was one contained in the list returned by (entsel), but we still need to isolate it. For that, we will use the car function. Car returns the first item of a list.

Command: (list 1 2 3)

(1 2 3)

Command: (car (list 1 2 3))

1

Command: (car(entsel))

Select object:

If (car(entsel)) returns an Ename, you can use it to supply an Ename to the entget function, hence the (entget(car(entsel)))

Now let's take a look at that text, "hello" which is left justified at the coordinate 2,0,0.

Command: (entget(car(entsel)))

Select object: ((-1 . ) (0 . "TEXT") (330 . ) (5 . "84311") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "ref") (100 . "AcDbText") (10 2.0 0.0 0.0) (40 . 0.286542) (1 . "HELLO") (50 . 0.0) (41 . 1.0) (51 . 0.0) (7 . "ARIAL") (71 . 0) (72 . 0) (11 0.0 0.0 0.0) (210 0.0 0.0 1.0) (100 . "AcDbText") (73 . 0))

As you can see, it's position is shown here in the dxf code 10. Great! Now let's draw a rectangle from 0,0 to 1,1 and do the same.

RECTANG

Specify first corner point or [Chamfer/Elevation/Fillet/Thickness/Width]: 0,0

Specify other corner point or [Area/Dimensions/Rotation]: 1,1

Command: (entget(car(entsel)))

Select object: ((-1 . ) (0 . "LWPOLYLINE") (330 . ) (5 . "84312") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "ref") (100 . "AcDbPolyline") (90 . 4) (70 . 1) (43 . 0.0) (38 . 0.0) (39 . 0.0) (10 0.0 0.0) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 1.0 0.0) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 1.0 1.0) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 0.0 1.0) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (210 0.0 0.0 1.0))

Now the first problems arise: we have 4 dxf code 10 coordinates, corresponding to the 4 vertex coordinates. By using the assoc function, we can retrieve the portion of the dxf code we need, but if you have multiple assoc, it will only return the first one found.
Command: (assoc 10 (entget(car(entsel))))

Select object: (10 0.0 0.0)

Another issue that arise is that depending on the coordinates chosen when creating the rectangle, the vertex order will vary. ie: if instead of making a rectangle from 0,0 to 1,1 we make a rectangle from 1,1 to 0,0 (which will graphically be the same), here is what is returned if we look at the coordinates of the first vertex

Command: REC RECTANG

Specify first corner point or [Chamfer/Elevation/Fillet/Thickness/Width]: 1,1

Specify other corner point or [Area/Dimensions/Rotation]: 0,0

Command: (assoc 10 (entget(car(entsel))))

Select object: (10 1.0 1.0)

 

Basically, we would have to take into consideration all of the vertex, not only the first one encountered... and that inevitably leads to a question: How do we deal with them? If we have 2 rectangles, rectangle A from 0,0 to 100,100, and rectangle B that goes from 1,1 to 2,2 which would be the first to be listed? Rectangle A which has the leftmost vextex, or Rectangle B which has the leftmost center? The same kind of question can arise if you have lets say 2 squares, both with 1 unit sides, both centered on 0,0 if 1 is rotated 45 degres around its center. And if 2 are identical and superposed one over the other, would we randomly order these 2, or would there be another sorting factor chiming in?

 

Another thing that has to be taken into consideration. With that previous rectangle, lets do a 3d rotate of 15 degrees, with an axis from 0,1 to 0,0.

Command: 3R ROTATE3D

Current positive angle: ANGDIR=counterclockwise ANGBASE=0.00

Select objects: 1 found

Specify first point on axis or define axis by

[Object/Last/View/Xaxis/Yaxis/Zaxis/2points]: 0,1

Specify second point on axis: 0,0

Specify rotation angle or [Reference]: 15

If we ID the upper right point, it stands at that coordinate

Command: ID Specify point: X = 0.97 Y = 1.00 Z = 0.26

Lets see what is in the dxf code of that rectangle now

Command: (entget(car(entsel)))

Select object: ((-1 . ) (0 . "LWPOLYLINE") (330 . ) (5 . "84313") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "ref") (100 . "AcDbPolyline") (90 . 4) (70 . 1) (43 . 0.0) (38 . 0.0) (39 . 0.0) (10 -1.0 1.0) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 -1.0 0.0) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 0.0 0.0) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 0.0 1.0) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (210 -0.258819 0.0 0.965926))

As you can see, the vertex coordinate isn't listed in the rectangle dxf code. The reason is that the coordinates listed in a LWPOLYLINE (polyline) are not in WCS, but actually in OCS, or Object Coordinate System. Dealing with OCS is not something that I would suggest as a first LISP lesson, as it is something that can get pretty complex. Is it likelly that you would try to sort coordinates of rectangles not drawn on a plan parallel to WCS? Maybe not. Still I cannot take for granted that you wont either. Will you?

 

Beside not knowing how to deal with these obstacles along the way, we don't know what you are trying to accomplish. The example you have started from returns a selection set made of resorted items from another selection set. Something tells me that the seek result is not just returning a reordered selection set. You still have to deal with that returned selection set.

 

Lisp programming is fun and can be rewarding. I hope you're here to learn with us :)

Cheers

Share this post


Link to post
Share on other sites
BIGAL

Using Vlisp its easy to get the co-ords of plines. But what are you trying to sort all the pline vertices into some sort of order or just one ?

Share this post


Link to post
Share on other sites
Dadgad

Welcome to CADTutor chayong91. :)

 

This sounds to me like a good job for Data Extraction, it would take some effort to set it up, but all of the functionality is there, if you look for it.

It would then create a table listing the information you are after, sorted by the X value in either ascending or descending order.

You could then save that data extraction, for subsequent use, sort of like a template.

Share this post


Link to post
Share on other sites
Jef!

I think I scared him :D

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...