关于多段线的有趣有挑战性的问题
如下图所示,右边的多段线图形是从左边那个图形复制出去的,求左边的图形要往右复制多长距离,复制后得到的右边的图形与左边的图形只有一个交点。(且右边的图形再往右移动的话就再也不会与左边的图形有交点。)从左图顶点为起点,沿复制移动的方向画一直线pla,pla与左图有两个交点,求出两交点坐标,两坐标距离即是所求。 自动排关注中>>>>>>>>> 由于多段线形状的不确定性,我觉得问题如果用搜索法来解较直观。首先,根据多段线的尺寸选择搜索步长,然后把多段线复制后一步步往右移动,直到它们俩只有一个交点或不相交为止。 先求BOX,将PL向右复制,步长为BOX底边。然后求出原PL的X最大点和复制PL的X最小点,用这两个点分别向右和左作射线,剩下的就是比较和验证几个交点了。 观察了一下,我认为可以搜索一个图形其同一水平线的X最小值和最大值之差,差的最大值就是该图形该复制的距离。。。这个想法未使用数学方法证实,不知是否正确 楼上的,按楼主的意思右边的图应该继续往右移,而按我的“理论”,你所示的并非X之差最大处,所以这个图并没有特殊之处
用肉眼观察,这个图形的“一个交点”应该在右边那个钩的顶点。。。 对于某些特殊的情况如简单的box,这个问题就没有解。 不谈图元重叠的情况,我觉得“这个值”应该是一些向外凸的点决定的,比较这些点在图形内x方向上的距离,大者即是。 又想了一下,<A name=2852><FONT color=#000066><B>meflying</B></FONT></A>的分析是对的.但是用cad编程实现起来还没想到什么好办法. 我非常同意四楼的观点,因为我也是这么考虑的。我要写一个程序验证一下。 ;This routine works for plines contain no arcs only. I have modified
;mccad’s routine GETINTERPOINT here. Thanks.
(defun C:GETD (/ obj vertice i ax-vertice max-width width intpts XlineObj objcopy)<BR> (vl-load-com)<BR> (setq AcadObject (vlax-get-acad-object)<BR> AcadDocument (vla-get-ActiveDocument AcadObject)<BR> mSpace (vla-get-ModelSpace AcadDocument))<BR> (setq obj (vlax-ename->vla-object (car (entsel "\nSelect a pline: "))))<BR> (if (= (vlax-curve-isClosed obj) nil)<BR> (vla-put-closed obj :vlax-true))<BR> (setq vertice (vlax-safearray->list<BR> (vlax-variant-value (vla-get-coordinates obj))))<BR> (setq ax-vertice '() i 0)<BR> (repeat (/ (length vertice) 2)<BR> (setq ax-vertice (append ax-vertice<BR> (list (vlax-3d-point (nth i vertice) (nth (1+ i) vertice)))))<BR> (setq i (+ i 2))<BR> );repeat<BR> (setq max-width 0)<BR> (foreach vertex ax-vertice<BR> (setq xlineobj (vla-addXline mSpace vertex<BR> (vla-PolarPoint (vla-get-utility AcadDocument) vertex 0 1)))<BR> (setq intpts (GetInterPoint obj xlineobj))<BR> (vla-erase xlineobj) <BR> (if (> (length intpts) 1)<BR> (setq width (abs (- (car (vl-sort (mapcar 'car intpts) '<))<BR> (car (vl-sort (mapcar 'car intpts) '>)))))<BR> );end_if<BR> (if (> width max-width)<BR> (setq max-width width))<BR> );foreach<BR> (setq objcopy (vla-copy obj))<BR> (vla-move objcopy (vlax-3d-point '(0 0 0)) (vlax-3d-point (list max-width 0 0)))<BR> (princ (strcat "\nDistance to move: " (rtos max-width)))<BR> (princ)<BR>)<BR>;;;;<BR>(defun GetInterPoint (ax_ent_1 ax_ent_2 / intpoints i)<BR> (setq intpoints (vla-intersectwith ax_ent_1 ax_ent_2 acextendnone))<BR> (setq intpoints (vlax-variant-value intpoints))<BR> (if (> (vlax-safearray-get-u-bound intpoints 1) 0)<BR> (progn<BR> (setq intpoints (vlax-safearray->list intpoints))<BR> (setq i 0)<BR> (setq ptlist '())<BR> (repeat (/ (length intpoints) 3)<BR> (setq ptlist (append ptlist (list (list (nth i intpoints)<BR> (nth (1+ i) intpoints)<BR> (nth (+ i 2) intpoints)))))<BR> (setq i (+ i 3))<BR> );repeat<BR> ptlist<BR> );progn<BR> nil<BR> );end_if<BR>)