明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2698|回复: 4

理解按位编码的好处,及编码后如何拆分因子,理解系统变量决定的状态(源码)

  [复制链接]
发表于 2012-5-22 22:47:27 | 显示全部楼层 |阅读模式
本帖最后由 sfzyr 于 2012-5-23 11:53 编辑

1.引子:

AutoCAD中,有很多这样的变量,一个变量其不同的变量值,代表着不同的意思,且多数是按位编码的,以"osmode"为例子,系统帮助文件解释如下:

OSMODE 系统变量     
类型:整数
保存位置:注册表
初始值: 4133
使用下列位码设置“对象捕捉”的运行模式:
0 NON(无)
1 END(端点)
2 MID(中点)
4 CEN(圆心)
8 NOD(节点)
16 QUA(象限点)
32 INT(交点)
64 INS(插入点)
128 PER(垂足)
256 TAN(切点)
512 NEA(最近点)
1024 QUI(快速)
2048 APP(外观交点)
4096 EXT(尺寸线)
8192 PAR(平行)
要指定多个对象捕捉方式,请输入各个位码值之和。例如,输入 3 指定“端点”(位码 1) 和“中点”(位码 2) 对象捕捉。输入 16383 指定全部对象捕捉方式。
使用状态行的“对象捕捉”按钮关闭对象捕捉模式,除了返回 OSMODE 的普通值,还将返回位码 16384 (0x4000)。这个附加值有助于开发人员编写 AutoCAD 应用程序并将此模式与“绘图设置”对话框关闭的对象捕捉模式区别开来。设置此位码值将关闭对象捕捉。在该位码值关闭时将 OSMODE 设置为其他值可以打开对象捕捉。


如只打开“端点,中点” ,则osmode = 1 + 2 =3
(setq osm(getvar "osmode")) 得到"osmode"值,就知道了那几个捕捉开了,其实这种编码就好先开关,解释如下:
第n位
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1

二进制
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1

对应的十进制
32768
16384此位码值将关闭对象捕捉
8192 PAR(平行)
4096 EXT(尺寸线)
2048 APP(外观交点)
1024 QUI(快速)
512 NEA(最近点)
256 TAN(切点)
128 PER(垂足)
64 INS(插入点)
32 INT(交点)
16 QUA(象限点)
8 NOD(节点)
4 CEN(圆心)
2 MID(中点)
1 END(端点)
0 NON(无)

故:14位全开,十进制= (1+ 2 + 4 + …… + 4096 + 8192 )= 16383:输入 16383 指定全部对象捕捉方式
      16384:关闭对象捕捉(绘图区按钮)
所以:(setq osm(getvar "osmode")) 得到"osmode"值,osmode = 16385,虽然端点打开,但是(16385 = 16384 + 1 ),而16384 绘图区 “ 对象捕捉按钮” 为关闭状态。
所以:判断某捕捉是否打开,并有效 ,判断某位置的“位码”是否为1 即可,用logand 函数
logand 2 (getvar "osmode") )=2 则中点开,且判断(logand 16384 (getvar “osmode”))是否= 16384即可
;;;;;=================================================================
2解码:

有人问


通过(getvar "osmode")返回值确认某种捕捉方式已打开,
如返回值为11,如何通过程序知道这11由1+2+8组成

caoyin 版在http://bbs.mjtd.com/forum.php?mod=viewthread&tid=93694已经给了一种算法,我在给出另外几种算法,抛砖引玉。

  1. ;; [功能] 按位编码分解
  2. ;; [参数] maxi----整型数。因子的最大范围
  3. ;;        cost----整型数。要分解的值
  4. ;; [返回] 包含按位编码的整型数列表
  5. ;; [测试] (lt:factor 171)->(1 2 8 32 128)
  6. ;;;sfzyr,logand分解
  7. (defun sf:factor (cost / fact lst maxi)
  8.   (setq maxi 1)
  9.   (while (< maxi cost)
  10.     (if (/= (setq fact (logand maxi cost)) 0)
  11.       (setq lst (cons fact lst))
  12.     )
  13.     (setq maxi (* maxi 2))
  14.   )
  15.   (reverse lst)
  16. )
  17. ;;;sfzyr,rem分解:计算机基础中的十进制二进制转换算法,“除 2 取 余”
  18. (defun sf:factor2 (cost / fact lst maxi)
  19.   (setq maxi 1)
  20.   (while (> cost 0)
  21.     (setq fact (* maxi (rem cost 2))
  22.    cost (/ cost 2)
  23.    maxi (* maxi 2)
  24.    lst  (vl-remove 0 (cons fact lst))
  25.     )
  26.   )
  27.   (reverse lst)
  28. )


3:其实位码拆分,就是“十进制”转“二进制” 的过程,有下面的计算机基础,你就可以编写出很多这个问题的解法了
  二进制的1101转化成十进制

  1101(2)=1*2^0+0*2^1+1*2^2+1*2^3=1+0+4+8=13

  转化成十进制要从右到左用二进制的每个数去乘以2的相应次方

  不过次方要从0开始

  相反 用十进制的数除以2 每除一下将余数就记在旁边

  最后按余数从下向上排列就可得到1101

  十进制转二进制:

  用2辗转相除至结果为1

  将余数和最后的1从下向上倒序写 就是结果

  例如302

  302/2 = 151 余0

  151/2 = 75 余1

  75/2 = 37 余1

  37/2 = 18 余1

  18/2 = 9 余0

  9/2 = 4 余1

  4/2 = 2 余0

  2/2 = 1 余0

  1/2 = 0 余1

  故二进制为100101110

以上,希望对logand 函数的用法更加清楚,对 一个系统变量,对应多个值 ,表示不同状态有所理解。
同时,自己也可以创建这样的变量,编码实现不同值对应不同状态。

抛砖引玉,高手不要拍砖。

评分

参与人数 2明经币 +3 金钱 +24 收起 理由
革天明 + 1 很给力!
caoyin + 2 + 24

查看全部评分

发表于 2012-5-22 23:08:05 | 显示全部楼层
补充下:
5楼logand、logor的用法举例
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=56976

点评

感谢C版指引!!!  发表于 2012-5-23 12:34
发表于 2012-5-23 06:20:26 来自手机 | 显示全部楼层
谢谢,学习了。
发表于 2012-5-23 08:50:43 来自手机 | 显示全部楼层
谢谢楼主 希望更多的高手来抛一抛 最后集成一块玉
 楼主| 发表于 2012-5-23 11:42:53 | 显示全部楼层
本帖最后由 sfzyr 于 2012-5-23 16:05 编辑

秋枫 在这个帖子
[函数] 请问 LOGAND 的详细用法 (陈老师你那本书也说得太不详细了,就HELP里那两个例子,
的6楼讲到

autocad的许多系统变量与位运算有关,比如undoctl, pickstyle。使用位存储是比较节省空间的方法
并以 一组undo函数为例,源码详见http://bbs.mjtd.com/thread-2747-1-1.html 讲解了。

并在此帖的
12楼,回答了:4楼所说,为什么判断多义线是否闭合,dxf 的70 码值,为什么不直接判断是否及值等于1

(setq en (car(entsel))
      el (entget en)
      flag70 (cdr (assoc 70 el))  
)
(if (= (logand flag70 1) 1)
  (print "此多义线闭合")
)
你也许要说我直接判断其是否等于1不就好了
回答详见http://bbs.mjtd.com/thread-2747-2-1.html 12楼
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-5-16 21:06 , Processed in 0.355379 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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