snddd2000 发表于 2012-5-6 20:20:09

写函数的思路扩展

举个最简单的例子。
一开始想计算1+2等于多少。
后来希望适用于其他数据,于是写了函数
(defun calcul (num1 num2)
(+ num1 num2)
)
再进一步,希望适用于其他加减乘除运算
(defun calcul (num1 symbol num2)
(symbol num1 num2)
)
上面的例子没有应用lisp的强项,表结构。

wowan1314 发表于 2012-5-6 20:29:24

深入浅出,希望多多开课。

smartstar 发表于 2012-5-6 20:59:13

学习了,谢谢!

snddd2000 发表于 2012-5-9 06:13:59

本帖最后由 snddd2000 于 2013-1-2 11:56 编辑

既然想到用函数来改善代码的可读性和简洁度,可能也考虑到函数的效率性。下面给出一个简单的测试运行时间的函数,以备后用。(条条大路通罗马,那条是比较快捷的,没有最快只有更快。)
测试结果依硬件和硬件的被占用情况会有比较大的出入,此不稳定性望坛友改进。(时间差分等次数平均求得)
[code=lisp(defun runtime (TestFunction arg Times / StartTime EndTime xx StartTime-i)
;_TestFunction as Function ,arg as Function's parameter Times as Integer
(setq StartTime (getvar "DATE") xx 0)
(repeat Times
    (setq StartTime-i (getvar "DATE"))
    (apply 'TestFunction arg)
    (setq EndTime (getvar "DATE"))
    (princ
      (strcat "\nNo."
       (itoa (setq xx (1+ xx)))
       " Time: "
       (rtos (* 86400 (- EndTime StartTime-i)) 2 8)
       " seaconds"
      )
    )
)
(princ
    (strcat "\nTotal Time: "
   (rtos (setq TotalTime (* 86400 (- EndTime StartTime))) 2 8)
   " seaconds"
    )
)
(princ (strcat "\nAverage Time: "
   (rtos (/ TotalTime Times) 2 16)
   " seaconds"
)
)
(print)
)
(defun test1(n)
(setq      sum 0
      n   (1+ n))
(while (< 0 n)
    (setq sum (+ sum (setq n (1- n))))
    )
sum
)

(defun test2(n m)
(setq      sum (1- n)
      m   (1+ m))
(while (< n m)
    (setq sum (+ sum (setq m (1- m))))
    )
sum
)

调用方法

(RUNTIME test1 (list 100) 10000)

(RUNTIME test2 (list 1 100) 10000)


Andyhon 发表于 2012-5-9 08:47:19

另版测试运行时间的函数
http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/defun-vs-lambda/td-p/805005

snddd2000 发表于 2012-5-9 13:48:40

Andyhon 发表于 2012-5-9 08:47 static/image/common/back.gif
另版测试运行时间的函数
http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/defun-vs-lamb ...

测试计算时间的函数,有问题,但不知道为什么?望指教。
_$ (RUNTIME (test 1) 10000)
0.0319853
_$ (RUNTIME (test 10) 10000)
0.0300139
_$ (RUNTIME (test 100) 10000)
0.0309795
_$ (RUNTIME (test 1000) 10000)
0.0319853
_$ (RUNTIME (test 10000) 10000)
0.0319853
上边是结果,显然不对。
下面是我将代码直接执行的结果
_$ (setq StartTime (getvar "DATE"))
   (repeat 10000
   (eval (test 10000))
   )
   (setq EndTime (getvar "DATE"))
   (* 86400 (- EndTime StartTime))
2.45606e+006
50005000
2.45606e+006
60.195
应该是对的。
下面是测试的函数
(defun test(n)
(setq        sum 0
        n   (1+ n))
(while (< 0 n)
    (setq sum (+ sum (setq n (1- n))))
    )
sum
)

Andyhon 发表于 2012-5-9 14:27:50

Command: (setq n 1)
1

Command: (Bench '(test) (list n) 10000)

TEST
Elapsed: 0.0310
Average: 0.0000031019747257

Command: (setq n 10)
10

Command: (Bench '(test) (list n) 10000)

TEST
Elapsed: 0.0940
Average: 0.0000093984603882

Command: (setq n 100)
100

Command: (Bench '(test) (list n) 10000)

TEST
Elapsed: 0.6880
Average: 0.0000687986612320

Command: (setq n 1000)
1000

Command: (Bench '(test) (list n) 10000)

TEST
Elapsed: 6.6250
Average: 0.0006624989211559

snddd2000 发表于 2012-5-9 21:56:48

下面是众多取LWPline的顶点坐标的函数中的一个,不适用于有重复点的多段线,但是恰恰可以去除有重复的点,比如首尾相连但属性里是非闭合的多段线。望坛友们提供同样功能的函数,一起来扩展思路,测试速度。
(defun lwpent->lwppoints (ent) ;_取LWPline的顶点坐标,忽略重复点
(setq lwppoints '())
(if (= (type ent) 'ENAME)
    (progn
      (setq entlist (entget ent))
      (if (= (cdr (assoc 0 entlist)) "LWPOLYLINE")
        (progn
          (while (setq atom10 (assoc 10 entlist))
          (setq entlist (vl-remove atom10 entlist))
          (setq lwppoints (cons (cdr atom10) lwppoints)
          )
          )
          (reverse lwppoints)
        )
      )
    )
)
)

ynhh 发表于 2014-8-9 14:00:43

snddd2000 发表于 2012-5-9 21:56 static/image/common/back.gif
下面是众多取LWPline的顶点坐标的函数中的一个,不适用于有重复点的多段线,但是恰恰可以去除有重复的点,比 ...

思路好啊
把重复点去了省得麻烦
最好也能把在同一直线上的中间点也去掉就更好了
例如一多线中有的无转折的直线段上,中间也有顶点,就应去了更好
请问能改成这样的吗
页: [1]
查看完整版本: 写函数的思路扩展