Использование циклов while внутри команды - PullRequest
1 голос
/ 10 марта 2019

Простая программа цикла может использоваться как:

(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)
       ""
  )

1 Ответ

3 голосов
/ 10 марта 2019

Есть несколько способов сделать это.

Использование 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, после косой черты (/) в списке аргументов. Это гарантирует, что переменные, определенные вашей функцией, не будут мешать глобальным переменным с тем же именем, определенным в пространстве имен документа. Для получения дополнительной информации по этой теме вы можете обратиться к моему уроку здесь .

  • Рекомендуется всегда использовать префиксы команд подчеркивания (_) и периода (.) (например, как в "_.pline"), так как подчеркивание гарантирует, что английская версия команды всегда используется независимо от языковой версии AutoCAD, в которой оценивается функция; точка гарантирует, что используется исходное определение команды, игнорируя любые возможные переопределения.

  • Модификатор привязки объекта "_non" (или "_none"), предоставляемый перед вводом любой точки, гарантирует, что любые активные режимы привязки объекта игнорируются при подаче точки в команду. Альтернативой является временное сохранение значения системной переменной OSMODE и установка его на 0 (таким образом отключая все режимы привязки объекта) при подаче точечного ввода, или временное задание системной переменной OSNAPCOORD равной 1, но любое из этих решений требует использования обработчика ошибок для сброса системных переменных в случае сбоя.

  • Выражения (cos (+ (/ pi 2.0) ang)) и (sin (+ (/ pi 2.0) ang)) можно при желании заменить на (sin (- ang)) и (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)
)
...