首页 > 解决方案 > 在命令中使用 While 循环

问题描述

一个简单的循环程序可以用作:

(setq y 0)
(while (< q 12) (setq q (1+ q)) 
(print "Hello")
)

但是如何在 Autocad 命令中使用这样的循环呢?

我相信下面的代码可以使用循环来简化,但是如何在运行命令中使用它们。

(defun PX (_angle)
  (list (* BaseRadius
       (+ (cos (+ 1.570796 _angle)) (* _angle (cos _angle)))
    )
    (* BaseRadius
       (+ (sin (+ 1.570796 _angle)) (* _angle (sin _angle)))
    )
  )
)

(defun c:cir ()
  (setq BaseRadius 8)
  (command "_pline"
       "qua"
       (PX 0)
       (PX 0.1)
       (PX 0.2)
       (PX 0.3)
       (PX 0.4)
       (PX 0.5)
       (PX 0.6)
       (PX 0.7)
       (PX 0.8)
       (PX 0.9)
       (PX 1)
       (PX 1.1)
       (PX 1.2)
       (PX 1.3)
       (PX 1.4)
       (PX 1.5)
       ""
  )

标签: autocadautolisp

解决方案


有几种方法可以实现这一点。

使用repeat

最简单的方法可能是使用repeat循环来评估一组表达式预定次数,每次迭代都会增加角度变量:

(defun c:cir ( / ang rad )
    (setq ang 0.0
          rad 8.0
    )
    (command "_.pline")
    (repeat 16
        (command "_non"
            (list
                (* rad (+ (cos (+ (/ pi 2.0) ang)) (* ang (cos ang))))
                (* rad (+ (sin (+ (/ pi 2.0) ang)) (* ang (sin ang))))
            )
        )
        (setq ang (+ ang 0.1))
    )
    (command "")
    (princ)
)

笔记:

关于上面的代码有几点需要注意:

  • 局部变量(即只需要在此函数范围内定义的变量)被声明为表达式的一部分,在参数列表中defun的正斜杠 ( ) 之后。/这可确保您的函数定义的变量不会干扰 Document 命名空间中定义的同名全局变量。有关此主题的更多信息,您可能希望在此处参考我的教程。

  • 始终使用下划线 ( _) 和句点 ( .) 命令前缀(例如 in "_.pline")是一种很好的做法,因为下划线可确保始终使用英文版本的命令,而不管功能所在的 AutoCAD 语言版本如何评估;句点确保使用命令的原始定义,忽略任何可能的重新定义。

  • 在任何点输入之前提供的"_non"(或"_none")对象捕捉修改器可确保在将点提供给命令时忽略任何活动的对象捕捉模式。另一种方法是在提供点输入的同时临时存储OSMODE系统变量的值并将其设置为0(从而禁用所有对象捕捉模式),或者临时将OSNAPCOORD系统变量设置为1,但是这些解决方案中的任何一个都需要使用错误处理程序如果发生任何故障,请重置系统变量。

  • 表达式(cos (+ (/ pi 2.0) ang))and(sin (+ (/ pi 2.0) ang))可以可选地分别替换为(sin (- ang))and (cos ang)。但我不想偏离您的原始代码太远,以便您更好地理解我所做的更改。

使用while

或者,如果您希望迭代由超过给定限制的变量值确定的次数,while循环可能是更合适的选择:

(defun c:cir2 ( / ang rad )
    (setq ang 0.0
          rad 8.0
    )
    (command "_.pline")
    (while (< ang 1.6)
        (command "_non"
            (list
                (* rad (+ (sin (- ang)) (* ang (cos ang))))
                (* rad (+ (cos    ang)  (* ang (sin ang))))
            )
        )
        (setq ang (+ ang 0.1))
    )
    (command "")
    (princ)
)

推荐阅读