nkeseci 发表于 2022-7-5 16:21:28

排序上的混合顺序点

你好
 
有谁能帮我写一个lisp函数来排序多段线上的点(假设交点)?
 
在我的代码中,我有一个多段线对象和一组交点。我需要连续计算这些点和顶点之间的累积距离。
 
谢谢

Lee Mac 发表于 2022-7-5 16:41:07

以下函数将根据点沿多段线的位置对其进行排序:
 
(defun sortpoints ( ent lst )
   (vl-sort lst
       (function
         (lambda ( a b )
               (<(vlax-curve-getparamatpoint ent a)
                   (vlax-curve-getparamatpoint ent b)
               )
         )
       )
   )
)或者,如果点不一定位于对象上:
 
上述函数应使用相关多段线的实体名称和WCS点列表调用,例如:
 
(sortpoints <entity-name> <point-list>)
 
您还需要确保在使用上述函数之前调用(vl load com)。

nkeseci 发表于 2022-7-5 16:47:41

谢谢你的回答。但是sortpoints函数似乎不起作用。我用样本数据在代码中尝试了这个函数。
样本数据是多段线的顶点。我混合了顶点的顺序,我希望你的函数(sortpoints)对这些点进行排序。但它给了我相同的分数顺序。也许是我的错。
 
以下是采样点(多段线的顶点)
(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.
 
以下是完整代码:
 

(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
)


 
谢谢

Lee Mac 发表于 2022-7-5 16:59:44

由于您的坐标值列表以文字表示,并且仅提供3 d.p.精度,因此vlax curve getparamatpoint函数可能无法识别该点位于给定的多段线实体上;您是否尝试了我建议的第二个函数,该函数使用vlax curve getclosestpointto函数将坐标“捕捉”到多段线?
 
此外,请注意,我已经说过,上述函数需要实体名称参数,而不是VLA对象;vlax曲线-*函数将在这两种类型的参数(ename/vla对象)下正确执行,但是,当在vla对象上提供实体名称时,函数将更快(此外,不需要使用vlax ename->vla对象进行转换)。
 
编辑:仔细检查代码后,在调用我的sortpoints函数后,您没有更新ptList变量的值:
您需要将排序函数返回的值赋给ptList变量:
这一推理适用,因为我们传递的排序函数的值由ptList变量持有,而不是指向变量本身的“指针”(如传递带引号的符号)。

nkeseci 发表于 2022-7-5 17:02:16

是的,我只是犯了一个很简单的错误。我忘了作业:
5
 
但它使用vlax curve getclosestpointto函数给出了预期结果,正如您所解释的:
7
 
非常感谢你

Lee Mac 发表于 2022-7-5 17:17:44

不客气!

rajannautiyal 发表于 2022-7-5 17:28:02

先生
 
我急需这个lisp程序来完成我的紧急工作。我也试过这个程序,但出现如下错误:
 
命令:NK\u FINT
 
选择多段线:
之前:
371118.717 311119.493
371016.444 311267.177
370961.248 310947.465
371083.002 311526.843
371232.353 311705.362
370930.404 311919.585
; 错误:错误的参数类型:lselsetp nil
 
 
这是我谦虚的请求,如果你们有时间,请上传更正了这个程序为我在txt格式。
 
提前谢谢。
顺致敬意,
拉詹·纳提亚尔
页: [1]
查看完整版本: 排序上的混合顺序点