1. ;;;La为图层名
    2. (defun Layer_zdsb (La / sel make_point_list n mn en entype pt1 pt2 pL sel k p1 p2 enlast ensel)
    3. ;;;===============================
    4. ;;;表操作函数
    5. ;;;判断点 p1 是否在点集PL中,是返回T ,不是返回nila为精度
    6. ;;;例 (IsInPointList '(1.0001 1.001 0) '((1 1 0) (2 1 0)) 0.001),返回T
    7. (defun IsInPointList (p1 PL a)
    8. ;(setq n (length PL))
    9. (if (member t (mapcar '(lambda (b) (equal p1 b a)) PL))
    10. t
    11. nil
    12. )
    13. )
    14. ;;;取出图元索引i对应的值
    15. (defun dxf (ent i)
    16. (cdr (assoc i (entget ent)))
    17. )
    18. ;;;取圆弧的起点、终点。中点
    19. (defun arc_3point (a / cenp radius STP ENPmp arcmidpoint)
    20. (setq cenp (cdr (assoc 10 (entget a))))
    21. (setq radius (cdr (assoc 40 (entget a))))
    22. (setq STP (vlax-curve-getPointAtParam A (vlax-curve-getstartparam A)))
    23. (setq ENP (vlax-curve-getPointAtParam A (vlax-curve-getEndParam A)))
    24. (setq arcmidpoint (polar (polar stp (angle stp enp) (/ (distance STP ENP) 2.0))
    25. (angle cenp (polar stp (angle stp enp) (/ (distance STP ENP) 2.0)))
    26. (- radius (distance (polar stp (angle stp enp) (/ (distance STP ENP) 2.0)) cenp))))
    27. (list stp enp arcmidpoint)
    28. )
    29. ;;;根据选择集中的line、arc、circle,生成点集
    30. (defun make_point_list (s / PL)
    31. (setq n 0 PL '() mn (sslength s))
    32. (repeat mn
    33. (setq en (ssname s n)
    34. enType (dxf en 0))
    35. (cond
    36. ((= enType "LINE")
    37. (setq pt1 (dxf en 10)
    38. pt2 (dxf en 11))
    39. (if (not (IsInPointList pt1 pl 0.00001))
    40. (setq pl (cons pt1 pl))
    41. );if
    42. (if (not (IsInPointList pt2 pl 0.00001))
    43. (setq pl (cons pt2 pl))
    44. );if
    45. )
    46. ((= enType "ARC")
    47. (setq pt1 (car (arc_3point en))
    48. pt2 (cadr (arc_3point en))
    49. )
    50. (if (not (IsInPointList pt1 pl 0.00001))
    51. (setq pl (cons pt1 pl))
    52. );if
    53. (if (not (IsInPointList pt2 pl 0.00001))
    54. (setq pl (cons pt2 pl))
    55. );if
    56. )
    57. );cond
    58. (setq n (1+ n))
    59. );repeat
    60. (setq pl pl)
    61. );make_point_list
    62. ;;;此处SEL选择集可自行修改为命令行选择代码
    63. (setq sel (ssget "x" (list '(0 . "line,arc,circle") (cons 8 La))))
    64. ;;(setq sel (ssget (list '(0 . "line,arc,circle") (cons 8 La))))
    65. (if sel
    66. (progn
    67. (setq Plist (make_point_list sel))
    68. (setq enlast (entlast) ensel (ssadd))
    69. (setvar "CLAYER" la)
    70. (command "_.boundary" "a" "b" "n" sel "" "" )
    71. (setq n -1
    72. mn 0
    73. k (length Plist))
    74. (repeat k
    75. (setq p0 (nth (setq n (1+ n)) Plist) mn n)
    76. (repeat (- k n 1)
    77. (setq p1 (nth (setq mn (1+ mn)) Plist))
    78. (setq p2 (midpoint p0 p1))
    79. (command p2)
    80. );repeat
    81. );repeat
    82. (command "")
    83. (while (setq en (entnext enlast))
    84. (setq enlast en)
    85. (ssadd en ensel)
    86. );while
    87. (command "erase" sel "")
    88. (setq ensel ensel)
    89. );progn
    90. nil
    91. );if
    92. )
    93. ;;程序缺点是选择的实体多了,计算速度太慢,请高手讨论,提供共好的算法!
    94. ;;程序加以改进后,完整代码如下:
    95. ;;以下内容需要发帖数高于 10 才可浏览
    96. ;;;选择直线 园弧 园自动生成边界,程序作者:Gu_xl 时间:20102
    97. (defun c:BianJie (/ NewSel sel n mn en entype pt1 pt2 pL sel k p1 p2 enlast ensel)
    98. ;;;选择集合并,返回合并后选择集,参数 选择集 图元都可以
    99. (defun SS_SSjoin (ss1 ss2 / ename ss cnt)
    100. (if ss1
    101. (progn
    102. (if (= (type ss1) 'ENAME)
    103. (progn
    104. (setq
    105. ename ss1
    106. ss1 (ssadd)
    107. )
    108. (ssadd ename ss1)
    109. )
    110. )
    111. )
    112. )
    113. (if ss2
    114. (progn
    115. (if (= (type ss2) 'ENAME)
    116. (progn
    117. (setq
    118. ename ss2
    119. ss2 (ssadd)
    120. )
    121. (ssadd ename ss2)
    122. )
    123. )
    124. )
    125. )
    126. (setq ss (ssadd))
    127. (if (and ss1 ss2)
    128. (progn
    129. (setq ss ss2
    130. cnt 0
    131. )
    132. (repeat (sslength ss1)
    133. (ssadd (ssname ss1 cnt) ss)
    134. (setq cnt (1+ cnt))
    135. )
    136. )
    137. )
    138. (if (and ss1 (not ss2))
    139. (setq ss ss1)
    140. )
    141. (if (and ss2 (not ss1))
    142. (setq ss ss2)
    143. )
    144. (if (> (sslength ss) 0)
    145. (eval ss)
    146. nil
    147. )
    148. )
    149. ;;;========================================================================================
    150. ;;选择集求交点子程序
    151. ;;;========================================================================================
    152. (defun interss
    153. (ss / i ssl aobj1 aobj2 n2 ipts pts pts1 pt el objL objL1)
    154. (setq ssl (sslength ss)
    155. i -1
    156. objL '()
    157. )
    158. ;;;OBJL 对象表 '((obj1) (obj2)...)
    159. (repeat ssl
    160. (setq
    161. objL
    162. (cons (list (vlax-ename->vla-object (ssname ss (setq i (1+ i)))))
    163. objL
    164. )
    165. )
    166. ) ;repeat
    167. (setq i -1)
    168. (repeat ssl
    169. (setq obj1 (nth (setq i (1+ i)) objL))
    170. (setq objL1 (cdr (member obj1 objL))
    171. aobj1 (car obj1)
    172. )
    173. (setq mm (- ssl i 1)
    174. m -1
    175. pts '()
    176. )
    177. (repeat mm
    178. (setq obj2 (nth (setq m (1+ m)) objL1))
    179. (setq aobj2 (car obj2)
    180. pts1 '()
    181. )
    182. (setq ipts (vla-intersectwith
    183. aobj1
    184. aobj2
    185. 0
    186. )
    187. ipts (vlax-variant-value ipts)
    188. )
    189. (if (> (vlax-safearray-get-u-bound ipts 1) 0) ;是否有交点
    190. (progn
    191. (setq ipts
    192. (vlax-safearray->list ipts)
    193. )
    194. (while (> (length ipts) 0)
    195. (setq pt (list (car ipts)
    196. (cadr ipts)
    197. (caddr ipts)
    198. )
    199. )
    200. (cond
    201. ((or (= (vla-get-objectname aobj2) "AcDbLine")
    202. (= (vla-get-objectname aobj2) "AcDbArc")
    203. )
    204. (if (not (or (equal (vlax-curve-getstartpoint aobj2)
    205. pt
    206. 0.0001
    207. )
    208. (equal (vlax-curve-getendpoint aobj2)
    209. pt
    210. 0.0001
    211. )
    212. )
    213. )
    214. (setq pts1 (cons pt pts1))
    215. ;(setq objL (subst (append obj2 (list pt)) obj2 objL))
    216. ) ;if
    217. )
    218. ((= (vla-get-objectname aobj2) "AcDbCircle")
    219. ;(setq objL (subst (append obj2 (list pt)) obj2 objL))
    220. (setq pts1 (cons pt pts1))
    221. )
    222. ) ;cond
    223. (cond
    224. ((or (= (vla-get-objectname aobj1) "AcDbLine")
    225. (= (vla-get-objectname aobj1) "AcDbArc")
    226. )
    227. (if (not (or (equal (vlax-curve-getstartpoint aobj1)
    228. pt
    229. 0.0001
    230. )
    231. (equal (vlax-curve-getendpoint aobj1)
    232. pt
    233. 0.0001
    234. )
    235. )
    236. )
    237. (setq pts (cons pt pts))
    238. ) ;if
    239. )
    240. ((= (vla-get-objectname aobj1) "AcDbCircle")
    241. (setq pts (cons pt pts))
    242. )
    243. ) ;cond
    244. (setq ipts (cdddr ipts))
    245. ) ;while
    246. ) ;progn
    247. ) ;if
    248. (if pts1
    249. (setq objL (subst (append obj2 pts1) obj2 objL))
    250. )
    251. ) ;repeat
    252. (if pts
    253. (setq objL (subst (append obj1 pts) obj1 objL))
    254. ) ;if
    255. ) ;repeat
    256. ;在这里单独去除重合点和点沿曲线排序
    257. (mapcar '(lambda (a)
    258. (if (cdr a)
    259. (list (car a)
    260. (gxl-SortPointOnCurve
    261. (gxl-ListDumpPoint (cdr a) 0.00001)
    262. (car a)
    263. )
    264. )
    265. a
    266. )
    267. )
    268. objL
    269. )
    270. ) ;defun interss1
    271. ;;;========================================================================================
    272. ;;;Line/Arc/Circle实体打断程序 Break_ss
    273. (defun Break_ss (ss / ObjptL obj pts
    274. thisdrawing modelspace ssl
    275. pstart pend LayerName Linetype Color
    276. objLine
    277. )
    278. (if ss
    279. (progn
    280. (setq objptL (interss ss)
    281. thisdrawing (vla-get-activedocument
    282. (vlax-get-acad-object)
    283. )
    284. modelspace (vla-get-ModelSpace thisdrawing)
    285. ssL (length objptL)
    286. i -1
    287. )
    288. ) ;progn
    289. ) ;if
    290. (vla-startundomark thisdrawing)
    291. (setq LastEntity (entlast))
    292. (repeat ssl
    293. (setq objPts (nth (setq i (1+ i)) objptL)
    294. obj (car objPts)
    295. pts (cadr objPts)
    296. )
    297. (cond ((= (vla-get-objectname obj) "AcDbLine")
    298. (setq LayerName (vla-get-layer obj)
    299. Linetype (vla-get-linetype obj)
    300. Color (vla-get-color obj)
    301. )
    302. (setq pstart (vlax-curve-getstartpoint obj)
    303. pend (vlax-curve-getendpoint obj)
    304. pts (append (list pstart) pts)
    305. pts (append pts (list pend))
    306. )
    307. (while
    308. (> (length pts) 1)
    309. (setq objLine (vla-addline
    310. modelspace
    311. (vlax-3d-point (car pts))
    312. (vlax-3d-point (cadr pts))
    313. )
    314. )
    315. ;;;加入选择集
    316. (ssadd (entlast) NewSel)
    317. (vla-put-layer objLine LayerName)
    318. (vla-put-linetype objLine Linetype)
    319. (vla-put-color objLine Color)
    320. (setq pts (cdr pts))
    321. )
    322. (ssdel (vlax-vla-object->ename obj) Sel)
    323. (vla-Delete obj)
    324. )
    325. ((= (vla-get-objectname obj) "AcDbArc")
    326. (BreakArcByPoint (vlax-vla-object->ename obj) pts)
    327. )
    328. ((= (vla-get-objectname obj) "AcDbCircle")
    329. (Cir2ArcByPoint (vlax-vla-object->ename obj) pts)
    330. )
    331. ) ;cond
    332. ) ;repeat
    333. (vla-endundomark thisdrawing)
    334. ) ;defun Break_ss1
    335. ;;;将圆、圆弧打断变为arc 实体表转换 (cir2arc cir strang endang)
    336. ;;;测试: (cir2arc (car(entsel "\n选择要转为半圆弧的圆实体:")) 0 Pi T)
    337. (defun cir2arc (cir strang endang / el x)
    338. (setq el (entget cir)
    339. el (vl-remove-if
    340. '(lambda (x) (or (= -1 (car x)) (= 0 (car x))))
    341. el
    342. )
    343. el (append
    344. (list '(0 . "ARC"))
    345. el
    346. (list '(100 . "AcDbArc") (cons 50 strang) (cons 51 endang))
    347. )
    348. )
    349. (entmake el)
    350. ;;;加入选择集
    351. (ssadd (entlast) NewSel)
    352. )
    353. ;;;沿园上分割点将园打断为圆弧 Cir2ArcByPoint cir ptLst
    354. (defun Cir2ArcByPoint (cir ptLst / cpt r x k kk ang0 ang1 angL)
    355. (setq cpt (dxf cir 10)
    356. r (dxf cir 40)
    357. )
    358. (setq angL (vl-sort (mapcar '(lambda (x) (angle cpt x)) ptLst) '<))
    359. (setq k -1
    360. kk (length angL)
    361. ang0 (last angL)
    362. )
    363. (repeat kk
    364. (setq ang1 (nth (setq k (1+ k)) angL)
    365. )
    366. (cir2arc cir ang0 ang1)
    367. (setq ang0 ang1)
    368. ) ;repeat
    369. (ssdel cir Sel)
    370. (entdel cir)
    371. ) ;defun
    372. ;;;沿园弧上分割点将园打断为圆弧 BreakArcByPoint cir ptLst
    373. (defun BreakArcByPoint
    374. (cir ptLst / cpt r x k kk angstart angEnd ang1 angL)
    375. (setq angstart (dxf cir 50)
    376. angEnd (dxf cir 51)
    377. cpt (dxf cir 10)
    378. )
    379. (setq angL (mapcar '(lambda (x) (angle cpt x)) ptLst))
    380. (setq k -1
    381. kk (length angL)
    382. )
    383. (repeat kk
    384. (setq ang1 (nth (setq k (1+ k)) angL)
    385. )
    386. (cir2arc cir angstart ang1)
    387. (setq angstart ang1)
    388. ) ;repeat
    389. (cir2arc cir angstart angEnd)
    390. (ssdel cir Sel)
    391. (entdel cir)
    392. ) ;defun
    393. ;;;gxl-ListDumpPoint 从给定点列表中移去重复出现的点。
    394. ;;pts:表 fuzz:精度
    395. ;;By Aeo
    396. (defun gxl-ListDumpPoint (ptLst fuzz / pt1 x)
    397. (cond ((= (length ptLst) 1) ptLst)
    398. (t
    399. (setq pt1 (car ptLst))
    400. (cons pt1
    401. (vl-remove-if
    402. '(lambda (x) (equal pt1 x fuzz))
    403. (gxl-ListDumpPoint (cdr ptLst) fuzz)
    404. )
    405. )
    406. )
    407. )
    408. )
    409. ;;;=============================================================================================
    410. ;;;(gxl-SortPointOnCurve points curve) 参数 点集 points 曲线图元 curve 点集沿曲线排序
    411. (defun gxl-SortPointOnCurve (points curve / pl1 xx nn)
    412. (if (= (type curve) 'ENAME)
    413. (setq curve (vlax-ename->vla-object curve))
    414. )
    415. (setq pl1 (mapcar '(lambda (xx /)
    416. (vlax-curve-getparamatpoint
    417. curve
    418. (vlax-curve-getclosestpointto curve xx)
    419. )
    420. )
    421. points
    422. )
    423. )
    424. (mapcar '(lambda (nn) (nth nn points))
    425. (vl-sort-i pl1 '<)
    426. )
    427. )
    428. ;;;===============================
    429. ;;;表操作函数
    430. ;;;判断点 p1 是否在点集PL中,是返回T ,不是返回nila为精度
    431. ;;;例 (IsInPointList '(1.0001 1.001 0) '((1 1 0) (2 1 0)) 0.001),返回T
    432. (defun IsInPointList (p1 PL a)
    433. (if (member t (mapcar '(lambda (b) (equal p1 b a)) PL))
    434. t
    435. nil
    436. )
    437. )
    438. ;;;取出图元索引i对应的值
    439. (defun dxf (ent i)
    440. (cdr (assoc i (entget ent)))
    441. )
    442. ;;;==================================================================
    443. ;;;MidPoint 表操作函数,计算两点的中点
    444. ;;;计算两点的中点
    445. ;;;==================================================================
    446. (defun MidPoint (p1 p2)
    447. (if (> 2 (length p1))
    448. (list (* 0.5 (+ (car p1) (car p2)))
    449. (* 0.5 (+ (cadr p1) (cadr p2)))
    450. (* 0.5 (+ (caddr p1) (caddr p2)))
    451. )
    452. (list (* 0.5 (+ (car p1) (car p2)))
    453. (* 0.5 (+ (cadr p1) (cadr p2)))
    454. )
    455. )
    456. )
    457. ;;;取圆弧的起点、终点。中点
    458. (defun arc_3point (a / cenp radius STP ENPmp arcmidpoint)
    459. (setq cenp (cdr (assoc 10 (entget a))))
    460. (setq radius (cdr (assoc 40 (entget a))))
    461. (setq
    462. STP (vlax-curve-getPointAtParam A (vlax-curve-getstartparam A))
    463. )
    464. (setq ENP (vlax-curve-getPointAtParam A (vlax-curve-getEndParam A)))
    465. (setq arcmidpoint
    466. (polar (polar stp
    467. (angle stp enp)
    468. (/ (distance STP ENP) 2.0)
    469. )
    470. (angle cenp
    471. (polar stp
    472. (angle stp enp)
    473. (/ (distance STP ENP) 2.0)
    474. )
    475. )
    476. (- radius
    477. (distance (polar stp
    478. (angle stp enp)
    479. (/ (distance STP ENP) 2.0)
    480. )
    481. cenp
    482. )
    483. )
    484. )
    485. )
    486. (list stp enp arcmidpoint)
    487. )
    488. ;;;==================================================================
    489. ;;;get_rec_pointlist 获得一组点列表中左下角坐标和右上角坐标范围,[<左下角点> <右上角点> ]
    490. ;;;==================================================================
    491. (defun get_rec_pointlist (Pt_List / n plx ply pmin pmax e1 e2)
    492. (setq pt3 (LIST (apply 'max (mapcar '(lambda (x) (car X)) PT_LIST))
    493. (apply 'max (mapcar '(lambda (x) (caDr X)) PT_LIST))
    494. )
    495. PT1 (LIST (apply 'mIN (mapcar '(lambda (x) (car X)) PT_LIST))
    496. (apply 'mIN (mapcar '(lambda (x) (caDr X)) PT_LIST))
    497. )
    498. )
    499. (list PT1
    500. pt3
    501. )
    502. ) ;defun get_rec_pointlist
    503. ;;;==================================================================
    504. ;;;zoom_window 窗口显示,参数,点对表
    505. ;;;==================================================================
    506. (defun zoom_window (pl)
    507. (setq n (length pl))
    508. (if (= 2 n)
    509. (command "_.Zoom" "W" (car pl) (cadr pl))
    510. )
    511. ) ;defun zoom_window
    512. ;;;==================================================================
    513. ;;;返回直线、弧、园中点左右两侧一定距离的点,(LAC-LR-Point en d) 返回点对表 (左侧点 . 右侧点)
    514. (defun LAC-LR-Point (en d / a1 a2 a3 ang1 ang2)
    515. (cond ((= (dxf en 0) "LINE")
    516. (setq a1 (dxf en 10)
    517. a2 (dxf en 11)
    518. a3 (MidPoint a1 a2)
    519. ang (angle a1 a2)
    520. ang1 (+ ang (* pi 0.5))
    521. ang2 (- ang (* pi 0.5))
    522. a1 (polar a3 ang1 d)
    523. a2 (polar a3 ang2 d)
    524. )
    525. (cons a1 a2)
    526. )
    527. ((= (dxf en 0) "ARC")
    528. (setq a3 (dxf en 10) ;圆心
    529. r (dxf en 40) ;半径
    530. ang (* (+ (dxf en 50) (dxf en 51)) 0.5)
    531. a1 (polar a3 ang (- r d))
    532. a2 (polar a3 ang (+ r d))
    533. )
    534. (cons a1 a2)
    535. )
    536. ((= (dxf en 0) "CIRCLE")
    537. (setq a1 (dxf en 10)
    538. a2 (polar a1 0 (+ d (dxf en 40)))
    539. )
    540. (cons a1 a2)
    541. )
    542. ) ;cond
    543. )
    544. ;;;根据选择集中的line、arc、circle,生成点集
    545. (defun make_point_list (s / PL)
    546. (setq n 0
    547. PL '()
    548. mn (sslength s)
    549. )
    550. (repeat mn
    551. (setq en (ssname s n)
    552. enType (dxf en 0)
    553. )
    554. (cond
    555. ((= enType "LINE")
    556. (setq pt1 (dxf en 10)
    557. pt2 (dxf en 11)
    558. )
    559. (if (not (IsInPointList pt1 pl 0.00001))
    560. (setq pl (cons pt1 pl))
    561. ) ;if
    562. (if (not (IsInPointList pt2 pl 0.00001))
    563. (setq pl (cons pt2 pl))
    564. ) ;if
    565. )
    566. ((= enType "ARC")
    567. (setq pt1 (car (arc_3point en))
    568. pt2 (cadr (arc_3point en))
    569. )
    570. (if (not (IsInPointList pt1 pl 0.00001))
    571. (setq pl (cons pt1 pl))
    572. ) ;if
    573. (if (not (IsInPointList pt2 pl 0.00001))
    574. (setq pl (cons pt2 pl))
    575. ) ;if
    576. )
    577. ) ;cond
    578. (setq n (1+ n))
    579. ) ;repeat
    580. (setq pl pl)
    581. ) ;make_point_list
    582. ;;;=======================================================
    583. ;;;主程序开始
    584. (princ "\n*******选择直线 园弧 园自动生成边界,程序作者:Gu_xl********")
    585. (setq oldos (getvar "osmode"))
    586. (setq oldfill (getvar "fillmode"))
    587. (setvar "osmode" 0)
    588. (setvar "fillmode" 1)
    589. (setvar "cmdecho" 0)
    590. (setq NewSel (ssadd))
    591. (princ "\n选择直线 、园弧、 园:")
    592. (setq sel (ssget (list '(0 . "line,arc,circle"))))
    593. (princ "\n正在整理 数据...........")
    594. ;;;打断代码
    595. (Break_ss Sel)
    596. (setq Sel (SS_SSjoin Sel NewSel))
    597. (if sel
    598. (progn
    599. (setq Plist (make_point_list sel))
    600. (zoom_window (setq recList (get_rec_pointlist Plist)))
    601. ;;;计算点范围Y值的五百分之一
    602. (setq VerticalLimit
    603. (* 0.002 (- (cadadr recList) (cadar recList)))
    604. )
    605. (if (< VerticalLimit 0.2)
    606. (setq VerticalLimit 0.2)
    607. )
    608. (setq enlast (entlast)
    609. ensel (ssadd)
    610. )
    611. ;;;如果enlast为块定义,得到最后子图元
    612. (while (entnext enlast)
    613. (setq enlast (entnext enlast))
    614. )
    615. (setq enlast1 enlast)
    616. (command "_.boundary" "a" "i" "n" "+x" "b" "n" sel "" "")
    617. (setq ki -1
    618. k (sslength Sel)
    619. )
    620. (princ "\n共有 ")
    621. (princ K)
    622. (princ " 边,正在生成边界.........")
    623. (princ K)
    624. (repeat k
    625. (setq en-line (ssname Sel (setq ki (1+ ki)))
    626. LpLst (LAC-LR-Point en-line VerticalLimit) ;直线两边点
    627. )
    628. (command (car LpLst))
    629. (command (cdr LpLst))
    630. ) ;repeat
    631. (command "")
    632. ;;;======================================================
    633. (while (setq en (entnext enlast))
    634. (setq enlast en)
    635. (ssadd en ensel)
    636. ) ;while
    637. (command "erase" sel "")
    638. (setq ensel ensel)
    639. ) ;progn
    640. nil
    641. ) ;if
    642. (setvar "osmode" oldos)
    643. (setvar "fillmode" oldfill)
    644. (princ)
    645. )