明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 6017|回复: 45

[讨论] 精确快速求spline线的最小点及最大点

  [复制链接]
发表于 2014-7-16 20:21 | 显示全部楼层 |阅读模式
本帖最后由 lgx9612 于 2014-7-27 13:56 编辑

      之前确因有一贴妙作,发贴不过10贴的不给看,故在不了解版规的情况下发了不少图片充数,确有炫耀和广告之嫌.在此实在是不好意思,虽写出几个小程序但本人笨拙,写的代码量很多,就不一一展示了.对本人来说计算最小点,最大点虽教程到处都可找到,但spline线对我来说是小有困难,费了我很大的心思.下面就spline线的最小点及最大点给出如下代码,请大家批评指正.
  1. (;计算最小点,最大点主程式,spline线
  2. ;ss_minbox_lgx是选集
  3. ;.......................略
  4. (setq nx_lgx (sslength  ss_minbox_lgx))
  5. (repeat nx_lgx
  6. (setq partname_lgx  (ssname ss_minbox_lgx (setq nx_lgx (1- nx_lgx))))
  7. (setq typepart_lgx (cdr (assoc 0 (entget partname_lgx))))
  8. (if (/= typepart_lgx "SPLINE")
  9. (progn
  10. ;不是spline线的计算
  11. )
  12. (calspline_lgx partname_lgx)
  13. )  
  14. )
  15. )
  16. (defun calspline_lgx(partname_lgx)
  17. (setq pl-temp_min_point nil)
  18. (setq pl-temp_max_point nil)
  19. (setq p_lgx nil)
  20. (setq lowest nil)
  21. (setq bbb (entget partname_lgx))
  22. (while (/= (assoc 10  bbb) nil)
  23. (setq p1_lgx (assoc 10  bbb))
  24. (setq p_lgx (cons (cdr p1_lgx) p_lgx))
  25. (setq bbb (vl-remove p1_lgx bbb))
  26. )
  27. (setq pl-temp_min_point (apply 'mapcar (cons 'min p_lgx)))
  28. (setq pl-temp_max_point (apply 'mapcar (cons 'max p_lgx)))
  29. (setq pl-temp_min_point (list (- (car pl-temp_min_point) 3)(- (cadr pl-temp_min_point) 3)))
  30. (setq pl-temp_max_point (list (+ (car pl-temp_max_point) 3)(+ (cadr pl-temp_max_point) 3)))
  31. (setq vla-object(vlax-ename->vla-object partname_lgx))
  32. (progn
  33. (setq pl_min_point pl-temp_min_point)
  34. (setq pl_max_point pl-temp_max_point)
  35. (setq zzl (/ (- (car pl_max_point)(car pl_min_point)) 10))
  36. (setq  givenPnt (list (car pl_min_point)(cadr pl_max_point)))
  37. (setq type_lgx "y")
  38. (calculate_lgx )
  39. (setq y2 topnt)
  40. )
  41. (progn
  42. (setq pl_min_point pl-temp_min_point)
  43. (setq pl_max_point (list (car pl-temp_max_point)(cadr pl-temp_min_point)))
  44. (setq zzl (/ (- (car pl_max_point)(car pl_min_point)) 10))
  45. (setq  givenPnt (list (car pl_min_point)(cadr pl_max_point)))
  46. (setq type_lgx "y" )
  47. (calculate_lgx)
  48. (setq y1 topnt)
  49. )
  50. (progn
  51. (setq pl_min_point pl-temp_min_point)
  52. (setq pl_max_point (list (car pl-temp_min_point)(cadr pl-temp_max_point)))
  53. (setq zzl (/ (- (cadr pl_max_point)(cadr pl_min_point)) 10))
  54. (setq  givenPnt pl_min_point)
  55. (setq type_lgx "x" )
  56. (calculate_lgx )
  57. (setq x1 topnt)
  58. )
  59. (progn
  60. (setq pl_min_point (list (car pl-temp_max_point)(cadr pl-temp_min_point)))
  61. (setq pl_max_point pl-temp_max_point)
  62. (setq zzl (/ (- (cadr pl_max_point)(cadr pl_min_point)) 10))
  63. (setq  givenPnt pl_min_point)
  64. (setq type_lgx "x" )
  65. (calculate_lgx )
  66. (setq x2 topnt)
  67. )
  68. (setq llpoint (list (car x1) (cadr y1)))
  69. (setq urpoint (list (car x2) (cadr y2)))
  70. )
  71. (defun calculate_lgx()
  72. (setq lowest nil)  
  73. (while (>= zzl 0.02)
  74. (repeat 11
  75. (setq topnt (vlax-curve-getClosestPointTo vla-object givenPnt ))
  76. ;;;(command "line" givenPnt topnt "")
  77. (if (or (>= lowest (distance  givenPnt topnt)) (= lowest nil))
  78. (progn
  79. (setq lowest (distance  givenPnt topnt))
  80. (setq lowestpoint givenPnt)
  81. )
  82. )
  83. (if (= type_lgx "y")
  84. (setq  givenPnt (list (+ (car givenPnt) zzl)(cadr pl_max_point)))
  85. (setq  givenPnt (list (car pl_min_point)(+ (cadr givenPnt) zzl)))
  86. )
  87. )
  88. (if (= type_lgx "y")  
  89. (setq  givenPnt (list (- (car lowestpoint) zzl) (cadr pl_max_point)))
  90. (setq  givenPnt (list (car pl_min_point)  (- (cadr lowestpoint) zzl)))  
  91. )  
  92. (setq zzl (/ zzl 5))
  93. )
  94. (setq topnt (vlax-curve-getClosestPointTo vla-object lowestpoint ));;;givenPnt改为 lowestpoint
  95. (setq lowest nil)  
  96. )
发表于 2014-9-9 10:25 | 显示全部楼层
本帖最后由 lucas_3333 于 2016-12-3 14:40 编辑
Gu_xl 发表于 2014-7-17 14:18

发表于 2014-7-16 20:25 | 显示全部楼层
什么叫做最小点和最大点啊,有哪方面的应用呢?科普一下吧
发表于 2014-7-16 20:28 来自手机 | 显示全部楼层
什么是最小点?x最小还丫最小。没看明白
 楼主| 发表于 2014-7-16 20:30 | 显示全部楼层
不好意思!是最小包容盒子的最小点和最大点.
发表于 2014-7-16 20:40 | 显示全部楼层
楼主,你是哪里人啊,写"程式"的人好少哦
发表于 2014-7-16 20:41 来自手机 | 显示全部楼层
lgx9612 发表于 2014-7-16 20:30
不好意思!是最小包容盒子的最小点和最大点.

你用了whi|e,是不是逼近法。G版写的那个更简洁
 楼主| 发表于 2014-7-16 20:45 | 显示全部楼层
本帖最后由 lgx9612 于 2014-7-27 13:59 编辑

(;计算spline线最小包容盒子的左下角点和右上角点
;ss_minbox_lgx是选集
;.....................省略
(setq nx_lgx (sslength  ss_minbox_lgx))
(repeat nx_lgx
(setq partname_lgx  (ssname ss_minbox_lgx (setq nx_lgx (1- nx_lgx))))
(setq typepart_lgx (cdr (assoc 0 (entget partname_lgx))));;;加上这行,这行少写了
(if (/= typepart_lgx "SPLINE")
(progn
;不是spline线的计算
)
(calspline_lgx partname_lgx)
)  
)
)
(defun calspline_lgx(partname_lgx)
(setq pl-temp_min_point nil)
(setq pl-temp_max_point nil)
(setq p_lgx nil)
(setq lowest nil)
(setq bbb (entget partname_lgx))
(while (/= (assoc 10  bbb) nil)
(setq p1_lgx (assoc 10  bbb))
(setq p_lgx (cons (cdr p1_lgx) p_lgx))
(setq bbb (vl-remove p1_lgx bbb))
)
(setq pl-temp_min_point (apply 'mapcar (cons 'min p_lgx)))
(setq pl-temp_max_point (apply 'mapcar (cons 'max p_lgx)))
(setq pl-temp_min_point (list (- (car pl-temp_min_point) 3)(- (cadr pl-temp_min_point) 3)))
(setq pl-temp_max_point (list (+ (car pl-temp_max_point) 3)(+ (cadr pl-temp_max_point) 3)))
(setq vla-object(vlax-ename->vla-object partname_lgx))
(progn
(setq pl_min_point pl-temp_min_point)
(setq pl_max_point pl-temp_max_point)
(setq zzl (/ (- (car pl_max_point)(car pl_min_point)) 10))
(setq  givenPnt (list (car pl_min_point)(cadr pl_max_point)))
(setq type_lgx "y")
(calculate_lgx )
(setq y2 topnt)
)
(progn
(setq pl_min_point pl-temp_min_point)
(setq pl_max_point (list (car pl-temp_max_point)(cadr pl-temp_min_point)))
(setq zzl (/ (- (car pl_max_point)(car pl_min_point)) 10))
(setq  givenPnt (list (car pl_min_point)(cadr pl_max_point)))
(setq type_lgx "y" )
(calculate_lgx)
(setq y1 topnt)
)
(progn
(setq pl_min_point pl-temp_min_point)
(setq pl_max_point (list (car pl-temp_min_point)(cadr pl-temp_max_point)))
(setq zzl (/ (- (cadr pl_max_point)(cadr pl_min_point)) 10))
(setq  givenPnt pl_min_point)
(setq type_lgx "x" )
(calculate_lgx )
(setq x1 topnt)
)
(progn
(setq pl_min_point (list (car pl-temp_max_point)(cadr pl-temp_min_point)))
(setq pl_max_point pl-temp_max_point)
(setq zzl (/ (- (cadr pl_max_point)(cadr pl_min_point)) 10))
(setq  givenPnt pl_min_point)
(setq type_lgx "x" )
(calculate_lgx )
(setq x2 topnt)
)
(setq llpoint (list (car x1) (cadr y1)))
(setq urpoint (list (car x2) (cadr y2)))
)
(defun calculate_lgx()
(setq lowest nil)  
(while (>= zzl 0.02)
(repeat 11
(setq topnt (vlax-curve-getClosestPointTo vla-object givenPnt ))
;;;(command "line" givenPnt topnt "")
(if (or (>= lowest (distance  givenPnt topnt)) (= lowest nil))
(progn
(setq lowest (distance  givenPnt topnt))
(setq lowestpoint givenPnt)
)
)
(if (= type_lgx "y")
(setq  givenPnt (list (+ (car givenPnt) zzl)(cadr pl_max_point)))
(setq  givenPnt (list (car pl_min_point)(+ (cadr givenPnt) zzl)))
)
)
(if (= type_lgx "y")  
(setq  givenPnt (list (- (car lowestpoint) zzl) (cadr pl_max_point)))
(setq  givenPnt (list (car pl_min_point)  (- (cadr lowestpoint) zzl)))  
)  
(setq zzl (/ zzl 5))
)
(setq topnt (vlax-curve-getClosestPointTo vla-object lowestpoint ))
(setq lowest nil)  
)
发表于 2014-7-16 20:47 | 显示全部楼层
能介绍下思路吗?
 楼主| 发表于 2014-7-16 21:17 | 显示全部楼层
风树 发表于 2014-7-16 20:47
能介绍下思路吗?

      通过曲线自身的参数求出能够框住曲线的外框来,再用外框边上取点求出距离曲线最近点,四边用同样的方法分别求出最大x,y最小x,y即可.
发表于 2014-7-16 21:33 | 显示全部楼层
lgx9612 发表于 2014-7-16 21:17
通过曲线自身的参数求出能够框住曲线的外框来,再用外框边上取点求出距离曲线最近点,四边用同样的方 ...

很好,
另外的这个方法也许可行:
原曲线端点+极值点排序后确定y方向上的最大最小值,
原曲线旋转90度后用同样的方式确定原来x方向上的最大最小值

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-4-20 06:18 , Processed in 5.769517 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表