nkeseci Posted December 28, 2012 Posted December 28, 2012 Hi, Can anyone help me to write a lisp function to sort the points (assume the intersection points) on a polyline? With my code, I have a polyline object and a set of intersection points on it. I need to calculate the cumulative distance between those points and vertex points consecutively. Thanks, Quote
Lee Mac Posted December 28, 2012 Posted December 28, 2012 The following function will sort the points based on their position along the polyline: (defun sortpoints ( ent lst ) (vl-sort lst (function (lambda ( a b ) (< (vlax-curve-getparamatpoint ent a) (vlax-curve-getparamatpoint ent b) ) ) ) ) ) Or, if the points do not necessarily lie on the object: (defun sortpoints ( ent lst ) (vl-sort lst (function (lambda ( a b ) (< (vlax-curve-getparamatpoint ent (vlax-curve-getclosestpointto ent a)) (vlax-curve-getparamatpoint ent (vlax-curve-getclosestpointto ent b)) ) ) ) ) ) The above functions should be called with the entity name of the polyline in question, and the list of WCS points, e.g.: (sortpoints <entity-name> <point-list>) You will also need to ensure (vl-load-com) is called before using the above functions. Quote
nkeseci Posted January 7, 2013 Author Posted January 7, 2013 Thank you for your answer. But the sortpoints function seems to not working. I tried the function in my code with sample data. Sample data are vertex points of polyline. I mixed the order of vertex points and I expect your function (sortpoints) sorts those points. But it gave me the same order of points. Maybe it could be my fault. Here is the sample points (vertices of a polyline) (370961.248 310947.465) ;1 (371118.717 311119.493) ;2 (371016.444 311267.177) ;3 (371083.002 311526.843) ;4 (371232.353 311705.362) ;5 (370930.404 311919.585) ;6 Here is the entire code: (vl-load-com) ;* ;* NK_FINT : Find intersection points ;* (intersections points of selected polyline with lines) ;* (defun C:nk_fint (/ plObj line_ss int_ss intP inc ent verts ptList) (setq plObj (vlax-ename->vla-object (car (entsel "\nSelect Polyline: "))); = Polyline OBJect line_ss (ssget "_X" '((0 . "LINE"))); = Line Selection Set int_ss (ssadd); = things that intersect -- start empty inc -1 ); setq (setq ptList '( ;(370961.248 310947.465) ;1 (371118.717 311119.493) ;2 (371016.444 311267.177) ;3 (370961.248 310947.465) ;1 (371083.002 311526.843) ;4 (371232.353 311705.362) ;5 (370930.404 311919.585) ;6 ) ) (princ "\n\Before: \n") (writepoints ptList) ;for testing purpose (repeat (sslength line_ss) (setq ent (ssname line_ss (setq inc (1+ inc)))); = line ENTity (if (setq intP ; intersection point (vlax-invoke plObj 'intersectWith (vlax-ename->vla-object ent) acExtendNone); vlax-invoke ); setq (progn (setq verts (getverts plObj intP)) (princ "\nVerts:\n") (writepoints verts) ;for testing purpose (ssadd ent int_ss) ) ; progn ); if ); repeat (sortpoints plObj ptList) (princ "\n\nAfter: \n") (writepoints ptList) ;for testing purpose (princ) ); defun ;* ;* WRITEPOINTS: write points (test-purpose) ;* (defun writepoints ( plst / x1 y1 ptmp) (while (setq ptmp (car plst)) (princ (rtos (car ptmp) 2 3))(princ " ")(princ (rtos (cadr ptmp) 2 3))(princ "\n") (setq plst (cdr plst)) ) (princ) ) ;* ;* SORTPOINTS: sorts given points along with selected polyline ;* (defun sortpoints ( ent lst ) (vl-sort lst (function (lambda ( a b ) (< (vlax-curve-getparamatpoint ent a) (vlax-curve-getparamatpoint ent b) ) ) ) ) ) ;* ;* GETVERTS: Gives vertex points of selected Polyline. ;* (defun getverts (pObj iPt / PtOnObj DistPick DistV1 PtV1 VNum distFlag DistV2 PtV2) (setq PtOnObj (vlax-curve-getClosestPointTo pObj iPt)) (setq DistPick (vlax-curve-getDistatPoint pObj PtOnObj)) (setq DistV1 0.0) (setq PtV1 (vlax-curve-getPointatparam pObj 0));;Pl start point (setq VNum 1.0) (setq distFlag T) (while distFlag (setq DistV2 (vlax-curve-getDistatParam pObj Vnum)) (setq PtV2 (vlax-curve-getPointatParam pObj Vnum)) (if (> DistV2 DistPick) (setq DistFlag nil) (setq Vnum (+ 1 Vnum) PtV1 PtV2) ) ) (list PtV1 PtV2);;returns list of 2 vertices bounding pick point ) Thanks, Quote
Lee Mac Posted January 7, 2013 Posted January 7, 2013 Since your list of coordinate values are expressed as literals and only given to 3 d.p. precision, there is the possibility that the vlax-curve-getparamatpoint function may not recognise that the point lies on the given polyline entity; did you try my second suggested function which uses the vlax-curve-getclosestpointto function to 'snap' the coordinates to the polyline? Also, note that I have stated that the above functions require an entity-name argument, not a VLA-Object; the vlax-curve-* functions will perform correctly with both types of argument (ename / vla-object), however, the functions will be faster when supplied with an entity-name over a VLA-Object (furthermore, there is no need for the conversion usig vlax-ename->vla-object). EDIT: On closer inspection of your code, you are not updating the value of the ptList variable following the call to my sortpoints function: (sortpoints plObj ptList) You will need to assign the ptList variable the value returned by the sorting function: (setq ptList (sortpoints plObj ptList)) This reasoning applies since we are passing the sorting function with the value held by the ptList variable, not a 'pointer' to the variable itself (as you might by passing a quoted symbol). Quote
nkeseci Posted January 7, 2013 Author Posted January 7, 2013 Yes, I was just doing a very simple error. I forgot the assignment: (setq ptList (sortpoints plObj ptList)) But it gave the expected result with vlax-curve-getclosestpointto function, as you explained: (defun sortpoints ( ent lst ) (vl-sort lst (function (lambda ( a b ) (< (vlax-curve-getparamatpoint ent (vlax-curve-getclosestpointto ent a)) (vlax-curve-getparamatpoint ent (vlax-curve-getclosestpointto ent b)) ) ) ) ) ) Thank you very much Quote
rajannautiyal Posted May 18, 2017 Posted May 18, 2017 Sir, I need this lisp program for my urgent work badly. I had also tried this program but this showing error as below: Command: NK_FINT Select Polyline: Before: 371118.717 311119.493 371016.444 311267.177 370961.248 310947.465 371083.002 311526.843 371232.353 311705.362 370930.404 311919.585 ; error: bad argument type: lselsetp nil This is my humble request to you guys if you have some time please upload corrected this program for me in txt format. Thanks in advance. Best regards, Rajan Nautiyal Quote
Recommended Posts
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.