[原创][LISP]根据允许偏离距离DIST_MIN,处理LWPOLYLINE的凸度数据(弧段)
本帖最后由 作者 于 2004-1-11 2:25:26 编辑程序代码内容
;;;根据允许偏离距离DIST_MIN,处理LWPOLYLINE的凸度数据(弧段)。
;;;由凸度计算出弧段直径,再计算以允许偏离距离DIST_MIN为弓高的弧段弦长度LENGTH_XIAN_MAX
;;;再由弧长LENGTH_XIAN和最大弦LENGTH_XIAN_MAX计算要插入顶点数NUM_HU,然后插入顶点
;;;90项点数
;;;42弧段弓弦比=(/ 弓高 (/ 弦长 2.0))
(DEFUN lwpolyline_remove42 (ss1 dist_min
/ curve-obj
data_new diameter
dist_min dxfold_10
dxfold_42 ename
length_gonglength_hu
length_hu_max
length_start length_xian
num1 num_hu
point_add_num
ss1 tmp
)
;;检查参数
(IF (NOT ss1)
(SETQ ss1 (SSADD))
)
(IF (OR (/= 'pickset (TYPE ss1)) (AND (/= 'real (TYPE dist_min)) (/= 'int (TYPE dist_min))))
(*error* "参数类型错。")
)
(PRINC (STRCAT "\n\t0\t处理含有凸度的LWPOLYLINE,共< " (ITOA (SSLENGTH ss1)) " >。"))
(SETQ num1 0)
(REPEAT (SSLENGTH ss1)
(SETQ ename (SSNAME ss1 num1)
curve-obj (VLAX-ENAME->VLA-OBJECT ename)
num1 (1+ num1)
data_new (LIST) ;更新后的数据
dxfold_10 nil ;上一个顶点坐标
point_add_num 0 ;插入的顶点数
)
(PRINC (STRCAT "\r\t" (ITOA num1)))
(FOREACH data_one (ENTGET ename)
(COND ((= 10 (CAR data_one))
(IF (AND dxfold_10 (/= dxfold_42 0.0)) ;如果是弧片断
(PROGN ;;42弧段弓弦比=(/ 弓高 (/ 弦长 2.0))
;;直径=(/ (+ (* 弦长 弦长 0.25) (* 弓高 弓高) 弓高))
(SETQ length_xian (DISTANCE (CDR data_one) dxfold_10) ;弦长
length_gong (ABS (* dxfold_42 length_xian 0.5)) ;弓高
diameter (/ (+ (* length_xian length_xian 0.25) (* length_gong length_gong)) length_gong)
;直径
)
;;反算最大弦长LENGTH_XIAN_MAX
;;弦长=(SQRT (* (- (* 直径 弓高) (* 弓高 弓高)) 4))
;;计算出分段数目NUM_HU
(SETQ length_hu_max (SQRT (ABS (* (- (* diameter dist_min) (* dist_min dist_min)) 4)))
length_start(VLAX-CURVE-GETDISTATPOINT curve-obj dxfold_10)
length_hu (ABS (- (VLAX-CURVE-GETDISTATPOINT curve-obj (CDR data_one)) length_start))
)
(IF (< length_hu_max dist_min)
(SETQ num_hu 0)
(SETQ num_hu (FIX (/ length_hu length_hu_max))
length_hu_max (/ length_hu (1+ num_hu))
)
)
;;插入NUM_HU个顶点
(REPEAT num_hu
(SETQ length_start(+ length_start length_hu_max)
point_add_num (1+ point_add_num)
)
(IF (SETQ tmp (VLAX-CURVE-GETPOINTATDIST curve-obj length_start))
(SETQ data_new (APPEND data_new (LIST (CONS 10 (MAPCAR '* '(1 1) tmp)))))
)
)
)
)
(SETQ dxfold_10 (CDR data_one))
)
((= 42 (CAR data_one))
(SETQ dxfold_42 (CDR data_one)
data_one'(42 . 0.0)
)
)
)
(SETQ data_new (APPEND data_new (LIST data_one)))
)
;;更新顶点数
(SETQ data_new (SUBST (CONS 90 (+ point_add_num (CDR (ASSOC '90 data_new)))) (ASSOC '90 data_new) data_new))
(IF (NOT (ENTMOD data_new))
(*error* "不能更新实体数据。")
)
)
(PRINC)
)
;;;测试
(DEFUN c:test ()
;;根据允许偏离距离DIST_MIN,处理LWPOLYLINE的凸度数据
(WHILE (SETQ tmp (SSGET "X" '((0 . "LWPOLYLINE") (-4 . "/=") (42 . 0.0))))
(lwpolyline_remove42 tmp 0.05)
)
(PRINC)
)
(PRINC) 人家简化还来不及,你却要加点。不知道你用在什么方面? 输出为外部文件,转换成不支持ARC的系统。
我是为了输出成e00文件进行处理的。 本帖最后由 作者 于 2004-1-10 17:40:46 编辑
;;;gg-->原来的凸度
(setq ang (* 4 (atan (abs gg))) ;;;-->这弧线的包含角
;;;dist_min -->你给的允许偏离距离:新凸度
(setq ang_new(* 4 (atan (abs dist_min))) ;;;-->新角度
那么新弧线长为:
(setq new_hu_len(* old_hu_len(/ ang_new ang))) ;;;old_hu_len求应该很方便,就是你的"length_hu"
现在关键是你的dist_min 是根据什么来的.
能不能讲讲 我是用来把大比例尺地形图的线输出成E00文件的。方案中有限差,最大不能超过图中距离0.1毫米,DWG数据用的是实地坐标,比例尺.1:1000。就是说不可以超出0.1。实际上为了保险起见,我把它调到0.05了。
页:
[1]