AutoLISP绘图从1点到另一点插入比例

时间:2017-06-23 20:25:14

标签: autolisp

我有一个例行程序,用于在AutoCAD中创建管道弯头,然后插入转向叶片。

我让程序工作得非常完美,只是当我去插入块时,我将它设置为使得块的比例是从点2到点5的横截面距离(这分别是肘部的内角和外角)插入的块可怕地扭曲。

我不知道是否有办法避免这种情况。

; Garrett Ford 6/23/17

; The purpose of this program is to allow the user to enter a few
; dimensions and then insert and elbow with a turning vane

(defun C:bow(/ oldsnap oldlayer oldblip flag iw fw tt rot ip ang bend p1 p2 p3 p4 p5 p6 ss)
 ;***********************************************************************
    ; Save System Variables

    (setq oldsnap (getvar "osmode"))
    (setq oldlayer (getvar "clayer"))
    (setq oldblip (getvar "blipmode"))
 ;***********************************************************************
    ;Change Settings & User Input

    (setvar "osmode" 35)
    (setvar "blipmode" 0)
    (setq flag (tblsearch "Layer" "LP-DUCT")) ; checks for LP-DUCT
        (if flag
            (setvar "clayer" "LP-DUCT") ; changes layer to LP-DUCT
            (alert ("No LP-DUCT Layer!")) ; if layer doesn't exist fuction terminates
        )
    (setq iw (getdist "\nWhat is the Initial Width? : "))
    (setq fw (getdist "\nWhat is the Final Width? : "))
    (setq tt (getdist "\nWhat is the Throat Length: "))
    ;(setq rot (getangle "\nWhat is the Angle of Rotation? : "))
    (setq ip (getpoint "\nSelect an Insertion Point: "))
    (setq ang (getangle ip "\nWhat is the Initial Throat direction from the Insertion point?: "))
    (initget 1 "Left Right")
    (setq bend (if (= (getkword "\nBend direction [Left/Right]: ") "Right") - +))
;***********************************************************************
    ; Polar Calculations

    (setq p1 (polar ip (bend ang (/ pi 2)) (/ iw 2)))
    (setq p2 (polar p1 ang tt)) ; Inside Corner
    (setq p3 (polar p2 (bend ang (/ pi 2)) tt))
    (setq p4 (polar p3 ang fw))
    (setq p5 (polar p4 (bend ang (- (/ pi 2))) (+ tt iw)))  ;  Outside Corner
    (setq p6 (polar p5 (+ ang pi) (+ tt fw)))
 ;***********************************************************************
; Line & Insert Commands

    ;(setq ss (ssadd))
    (setvar "osmode" 0)
    (command "_.pline" ip p1 p2 p3 p4 p5 p6 "_close")
    ;(ssadd (entlast) ss)
    (setvar "osmode" 7079)
    (command "_.insert" "tvain" p2 (distance p2 p5) (+ ang (/ pi 2)))
    ;(ssadd (entlast) ss)
    ;(command "rotate" ss "rot" ip pause)
    (setvar "osmode" oldsnap)
    (setvar "clayer" oldlayer)
    (setvar "blipmode" oldblip)
)   ; End Defun
;************************************************************************
    ;Converts the Degrees into Radians

(defun dtr (ang) ;define degrees to radians function
 (* pi (/ ang 180.0)) 
 ;divide the angle by 180 then
 ;multiply the result by the constant PI
) ;end of function
;************************************************************************

1 个答案:

答案 0 :(得分:0)

您的代码存在一些问题:

  • (alert ("No LP-DUCT Layer!"))会出错。

    应改为:(alert "No LP-DUCT Layer!")

  • 您应该测试每个getXXX个来电(例如getpointgetdist等)是否会在继续之前返回非零值。由于在AutoLISP中,任何非零的结果都被视为True结果,因此可以使用ifand的组合轻松实现此目标,例如:

    (if
        (and
            (setq iw (getdist "\nWhat is the Initial Width? : "))
            (setq fw (getdist "\nWhat is the Final Width? : "))
            (setq tt (getdist "\nWhat is the Throat Length: "))
            (setq ip (getpoint "\nSelect an Insertion Point: "))
            (setq ang (getangle ip "\nWhat is the Initial Throat direction from the Insertion point?: "))
            ...
        )
        (progn
            ;; Do your thing
        )
    )
    

    由于AutoLISP支持短路评估,因此只要表达式返回andnil函数就会停止对参数的求值。因此,如果用户未提供初始宽度的值,则不会验证and表达式,并且不会提示他们指定最终宽度

  • 我建议使用INSERT命令的命令行版本,在命令前面加一个连字符(即-INSERT)。

    我还建议明确指定比例&使用此命令提供的关键字进行轮换,例如:

    (command "_.-insert" "tvain" "_S" (distance p2 p5) "_R" (angtos (+ ang (/ pi 2))) "_non" p2)
    

    在这种情况下需要angtos函数作为-INSERT命令(实际上使用command函数评估的任何命令)使用图形中设置的角度单位,而不是弧度。

  • 您的代码中定义的dtr函数未被评估,因此可能会被省略。

  • 您可能希望使用以下表达式来设置位OSMODE,而不是将0系统变量设置为16384

    (setvar 'osmode (logior 16384 (getvar 'osmode)))
    

    这相当于用户按 F3 禁用对象捕捉而不是将OSMODE设置为0,这相当于用户取消选中所有对话框中的对象捕捉模式。

    这样做的好处是,如果您的代码出于任何原因出错(包括用户在程序执行期间按下 Esc ),Object Snap将仅被禁用,并且可以使用重新启用F3 ,而不是完全擦除用户的对象捕捉设置。

    或者,您可以完全避免更改OSMODE系统变量,而是使用"_non"捕捉修饰符(意为“无”)为点输入添加前缀,这会导致AutoCAD忽略所有活动捕捉模式下一个点输入,例如:

    (command "_.pline" "_non" ip "_non" p1 ... etc ... "_close")
    

    或者,作为另一种选择,您可以使用本地定义的错误处理程序,该错误处理程序会在代码中出现错误后重置OSMODE系统变量(以及所有其他已修改的系统变量)。我在Error Handling的教程中描述了如何执行此操作。