簡體   English   中英

自動將矩形轉換為已知度數的凹弧

[英]Automatically convert rectangle into concave arcs with a known degree

我想自動將用戶繪制的矩形的所有邊轉換為凹弧(周圍大約 10 度)。 我發現 Marko Ribar 編寫的這個美妙的例程(對不起,如果這不是正確的信用),它完全符合我的要求,除了用戶必須使用鼠標手動定義弧的方向和度數。 推動鼠標正 Y 方向 = 凸。 拉鼠標負Y方向=凹(這是​​我想要的)。 有誰知道如何添加代碼以在選擇矩形后自動向負 Y 方向拉約 ​​10 度? 有沒有更簡單的方法來完成這個任務,在繪制矩形時只畫 10 度弧而不是直線?

;Code to convert rectangle lines into arcs:

(defun c:lwstraight2arced ( / nthmassocsubst lw enx vs gr enxb p b i pt1 pt2 pt3 pt4 myrec )

;My added code to draw a rectangle by the user picking two opposite corners-----------------
(setq pt1 (getpoint "\nEnter first corner: "))
(setq pt3 (getcorner pt1 "\nEnter cross corner: "))
(setq pt2 (list (car pt1) (cadr pt3)))
(setq pt4 (list (car pt3) (cadr pt1)))
(setq myrec (command "rectangle" pt1 pt3 ""))
;end of my added code------------------------


  (defun nthmassocsubst ( n key value lst / k slst p j plst m tst pslst )
    (setq k (length (setq slst (member (assoc key lst) lst))))
    (setq p (- (length lst) k))
    (setq j -1)
    (repeat p
      (setq plst (cons (nth (setq j (1+ j)) lst) plst))
    )
    (setq plst (reverse plst))
    (setq j -1)
    (setq m -1)
    (repeat k
      (setq j (1+ j))
      (if (equal (assoc key (member (nth j slst) slst)) (nth j slst) 1e-6)
        (setq m (1+ m))
      )
      (if (and (not tst) (= n m))
        (setq pslst (cons (cons key value) pslst) tst t)
        (setq pslst (cons (nth j slst) pslst))
      )
    )
    (setq pslst (reverse pslst))
    (append plst pslst)
  )

;
; ----removed original code that has user select a line or rectangle manually-----
;          (setq lw (car (entsel "\nPick LWPOLYLINE straight polygon...")))
;-----end of original code-----



;-------My new code to have a previously drawn rectangle above automatically selected-----------------------------------
            (setq lw (entlast))
;-----End of my new code------


  (setq enx (entget lw))
  (setq vs (getvar 'viewsize))
  (while (= 5 (car (setq gr (grread t))))
    (setq enxb (acet-list-m-assoc 42 enx))
    (setq p (cadr gr))
    (setq b (/ (cadr p) vs))
    (setq i -1)
    (foreach dxf42 enxb
      (setq enx (nthmassocsubst (setq i (1+ i)) 42 b enx))
    )
    (entupd (cdr (assoc -1 (entmod enx))))
  )
  (princ)
)

這是用戶繪制矩形后我希望實現的目標。 沒有用戶輸入的略微凹陷的矩形。

在此處輸入圖像描述

我在例程中添加了以下步驟:

- 通過將長度乘以寬度來獲取矩形的面積。 - 根據矩形的平方英尺(以英寸為單位)在每個角落繪制具有特定尺寸的圓形和矩形。

這是上面添加的工作代碼:

(defun c:concavearc ( / b p q s z myrecarea convertrecarea pt1 pt2 pt3 pt4 circleset24 circleset36 circleset48)
; Create concave arcs from a rectangle
    (setq s 20.0) ;; Arc sagitta
    
    (if (and (setq p (getpoint "\nSpecify first corner: "))
             (setq q ((if (zerop (getvar 'worlducs)) getpoint getcorner) p "\nSpecify opposite corner: "))
             (mapcar 'set '(p q) (mapcar '(lambda ( x ) (mapcar x p q)) '(min max)))
             (setq z (trans '(0 0 1) 1 0 t)
                   b (mapcar '(lambda ( a b c ) (/ s (- a b) -0.5)) q p '(0 0))
             )
        )
        (entmake
            (list
               '(000 . "LWPOLYLINE")
               '(100 . "AcDbEntity")
               '(100 . "AcDbPolyline")
               '(090 . 4)
               '(070 . 1)
                (cons 010 (trans p 1 z))
                (cons 042 (car b))
                (cons 010 (trans (list (car q) (cadr p)) 1 z))
                (cons 042 (cadr b))
                (cons 010 (trans q 1 z))
                (cons 042 (car b))
                (cons 010 (trans (list (car p) (cadr q)) 1 z))
                (cons 042 (cadr b))
                (cons 210 z)
            )
        )
    )


;Add width of 2" and dashed line to arc polyline -----------------------------------------
  
(setvar "cmdecho" 0); disable command echo 
(setq Plnwdth (ssget "L"));get last entity
(command "pedit" Plnwdth "W" 2 "");set last entity width to 2

 (if (null (tblsearch "ltype" "dashed"))  
  (command ".linetype" "load" "dashed" "acad.lin" "")
 )

(command "change" Plnwdth "" "p" "LType" "Dashed" "" "ltScale" "30" "");lynetype
(setvar "cmdecho" 1); restore command echo
;end add width of 2 to arc polyline-----------------------------------------



;End concave arcs-----------------------------------------


;Setting corners of rectangle to variables --------------------------------------------------------------


; Get the four points of rectangle drawn by user above
(setq pt1 p)
(setq pt3 q)
(setq pt2 (list (car pt1) (cadr pt3)))
(setq pt4 (list (car pt3) (cadr pt1)))
(setq mylength (distance pt1 pt2)); length
(setq mywidth (distance pt1 pt4)); width
(setq myrecarea (* mylength mywidth)); Get area of rectangle (length x width)


(setvar "unitmode" 1);units to be displayed as entered
(setq convertrecarea (rtos myrecarea 4 2)); converts "convertrecarea" string into architectural format:

; Change units from decimal to Architectural
  (if *decimal*
    (progn
      (command "_.-units" "2" "" "" "" "" "")
      (setq *decimal* nil)
    )
    (progn
      (command "_.-units" "4" "" "" "" "" "")
      (setq *decimal* t)
    )
  )







; create conditional "if/and" functions based on rectangle area in square inches.
; if area of rectangle below 14400 SQ.Inches, give message to redraw rectangle
      (if
        (<= myrecarea 14400)
        (prompt "Area to small. Redraw area again")
      ); End IF
; if area of rectangle is between 14401 SQ.Inches and 57600 SQ.Inches, place a 24" circle at each corner of rectangle points
  
    (if
        (and
          (>= myrecarea 14401)
          (<= myrecarea 57600)
        ); End AND
              (progn
        (command "-color" "t" "99,100,102" ""); Change color
                (command "circle" pt1 "d" 24 0 ""); Create circle
        (command "_copy" "last" "" "M" pt1 pt2 pt3 pt4 ""); Copy circle to all four points of rectangle
        (setq circleset24 (ssget "_C" pt1 pt3 '((0 . "CIRCLE")))); Create selection set of circles using fencing around rectangle
        (command "_hatch" "p" "AR-Conc" "2" "0" "s" circleset24 ""); Hatch selected circles
        
;Create rectangle from centerpoint. Copy to each corner
    (command "-color" "t" "255,255,255" "")
    (setq len 2)
    (setq wid 2)
    (setq z1 (trans '(0 0 1) 1 0 t))
    (if (setq cnt1 pt1)
        (entmake
            (list
               '(000 . "LWPOLYLINE")
               '(100 . "AcDbEntity")
               '(100 . "AcDbPolyline")
               '(090 . 4)
               '(070 . 1)
                (cons 010 (trans (mapcar '+ cnt1 '(-2 -2)) 1 z1))
                (cons 010 (trans (mapcar '+ cnt1 '( 2 -2)) 1 z1))
                (cons 010 (trans (mapcar '+ cnt1 '( 2  2)) 1 z1))
                (cons 010 (trans (mapcar '+ cnt1 '(-2  2)) 1 z1))
                (cons 210 z1)

            )
        )
    )
        (command "_copy" "last" "" "M" pt1 pt2 pt3 pt4 "")
        
          ); End Progn
    ); End IF
  
; if area of rectangle is between 57601 SQ.Inches and 129600 SQ.Inches, place a 36" circle at each corner of rectangle points
    (if
        (and
          (>= myrecarea 57601)
          (<= myrecarea 129600)
        ); End AND
          (progn
        (command "-color" "t" "99,100,102" "")
            (command "circle" pt1 "d" 36 0 "")
            (command "_copy" "last" "" "M" pt1 pt2 pt3 pt4 "")
        (setq circleset36 (ssget "_C" pt1 pt3 '((0 . "CIRCLE"))))
        (command "_hatch" "p" "AR-Conc" "2" "0" "s" circleset36 "")

;Create rectangle from centerpoint. Copy to each corner
    (command "-color" "t" "255,255,255" "")
    (setq len 3)
    (setq wid 3)
    (setq z1 (trans '(0 0 1) 1 0 t))
    (if (setq cnt1 pt1)
        (entmake
            (list
               '(000 . "LWPOLYLINE")
               '(100 . "AcDbEntity")
               '(100 . "AcDbPolyline")
               '(090 . 4)
               '(070 . 1)
                (cons 010 (trans (mapcar '+ cnt1 '(-3 -3)) 1 z1))
                (cons 010 (trans (mapcar '+ cnt1 '( 3 -3)) 1 z1))
                (cons 010 (trans (mapcar '+ cnt1 '( 3  3)) 1 z1))
                (cons 010 (trans (mapcar '+ cnt1 '(-3  3)) 1 z1))
                (cons 210 z1)

            )
        )
    )
        (command "_copy" "last" "" "M" pt1 pt2 pt3 pt4 "")

        
          ); End Progn
    ); End IF
  
; if area of rectangle is between 129601 SQ.Inches and 230400 SQ.Inches, place a 48" circle at each corner of rectangle points

    (if
        (and
         (>= myrecarea 129601)
         (<= myrecarea 230400)
        ); End AND
          (progn
       (command "-color" "t" "99,100,102" "")
           (command "circle" pt1 "d" 48 0 "")
       (command "_copy" "last" "" "M" pt1 pt2 pt3 pt4 "")
       (setq circleset48 (ssget "_C" pt1 pt3 '((0 . "CIRCLE"))))
       (command "_hatch" "p" "AR-Conc" "2" "0" "s" circleset48 "")
       

;Create rectangle from centerpoint. Copy to each corner
    (command "-color" "t" "255,255,255" "")
    (setq len 4)
    (setq wid 4)
    (setq z1 (trans '(0 0 1) 1 0 t))
    (if (setq cnt1 pt1)
        (entmake
            (list
               '(000 . "LWPOLYLINE")
               '(100 . "AcDbEntity")
               '(100 . "AcDbPolyline")
               '(090 . 4)
               '(070 . 1)
                (cons 010 (trans (mapcar '+ cnt1 '(-4 -4)) 1 z1))
                (cons 010 (trans (mapcar '+ cnt1 '( 4 -4)) 1 z1))
                (cons 010 (trans (mapcar '+ cnt1 '( 4  4)) 1 z1))
                (cons 010 (trans (mapcar '+ cnt1 '(-4  4)) 1 z1))
                (cons 210 z1)

            )
        )
    )
        (command "_copy" "last" "" "M" pt1 pt2 pt3 pt4 "")

          ); End Progn
    ); End IF


; if area of rectangle is above 230401 SQ.Inches tell user to redraw area

    (if
        (>= myrecarea 230401)
        (prompt "Area to big. Redraw area again")
    ); End IF
    (princ convertrecarea)

);End "concavearc"

新增功能正在運行,但我希望能夠執行以下操作:

將 Arc 代碼段放在“IF”語句中,如果用戶繪制的矩形太大或太小,提示用戶“超出范圍”並結束例程。 現在,無論是否超出范圍,它都會繪制弧線。

我試圖在下面添加一個 IF 語句,但沒有奏效。 這是其中的一個片段:

        (defun c:concavearc ( / b p q s z myrecarea convertrecarea pt1 pt2 pt3 pt4)
          
        ; ------------------ Create concave arcs from a rectangle----------
            (setq s 20.0) ;; Arc sagitta
            
        (if (and (setq p (getpoint "\nSpecify first corner: "))
                     (setq q ((if (zerop (getvar 'worlducs)) getpoint getcorner) p "\nSpecify opposite corner: "))
        
            ; Get the four points of rectangle drawn by user above
            (setq pt1 p)
            (setq pt3 q)
            (setq pt2 (list (car pt1) (cadr pt3)))
            (setq pt4 (list (car pt3) (cadr pt1)))
            (setq mylength (distance pt1 pt2)); length
            (setq mywidth (distance pt1 pt4)); width
            (setq myrecarea (* mylength mywidth)); Get area of rectangle (length x width)
             
        
        ; If area drawn is above 129601square inches or below 14400 square inches display message the "not in range". Else, draw concave arcs.   
            (if
                (and
                 (>= myrecarea 129601)
                 (<= myrecarea 14400)
                ); End and
             (prompt "Not in range. Redraw area again")   
        
             (progn
                     Concave Arc code here....
    
              );End Progn
           );End "if/and" conditional statement
   );End "get points"

就像一個內部問題。 您如何輸入平方英尺而不是英寸的數字?

例子:

(<= myrecarea 14400)

進入

(<= myrecarea 100 Sq. Ft.)

對於這項任務,我建議使用以下功能:

(defun c:caverec ( / b p q s z )

    (setq s 1.0) ;; Arc sagitta
    
    (if (and (setq p (getpoint "\nSpecify first corner: "))
             (setq q ((if (zerop (getvar 'worlducs)) getpoint getcorner) p "\nSpecify opposite corner: "))
             (mapcar 'set '(p q) (mapcar '(lambda ( x ) (mapcar x p q)) '(min max)))
             (setq z (trans '(0 0 1) 1 0 t)
                   b (mapcar '(lambda ( a b c ) (/ s (- a b) -0.5)) q p '(0 0))
             )
        )
        (entmake
            (list
               '(000 . "LWPOLYLINE")
               '(100 . "AcDbEntity")
               '(100 . "AcDbPolyline")
               '(090 . 4)
               '(070 . 1)
                (cons 010 (trans p 1 z))
                (cons 042 (car b))
                (cons 010 (trans (list (car q) (cadr p)) 1 z))
                (cons 042 (cadr b))
                (cons 010 (trans q 1 z))
                (cons 042 (car b))
                (cons 010 (trans (list (car p) (cadr q)) 1 z))
                (cons 042 (cadr b))
                (cons 210 z)
            )
        )
    )
    (princ)
)

這里,矩形四個邊的曲率由代碼頂部定義的單個參數s控制——這個參數對應於弧的長度,跨越弧中點和弧中點的距離每對頂點之間的弦。

代碼提示用戶指定對應於矩形對角的兩個點,並將繼續構造一個封閉的 4 頂點 2D 多段線 ( LWPOLYLINE ),通過將矢狀面除以弦長的一半來計算每個段的凸度(這等於弧所跨越的角度的四分之一的切線,這是折線段的凸出的定義 - 我在這里更詳細地描述了這種關系)。

代碼獲取相對於活動 UCS 的兩個點並計算相對於活動 UCS 的剩余兩個頂點,然后將所有坐標轉換為相對於對象坐標系 (OCS)。 這意味着矩形將與活動 UCS 的 x 軸對齊,並將在 AutoCAD 中的所有 UCS 和視圖設置下按預期運行。

該函數使用getpoint函數在 UCS 不等於 WCS 時提示輸入對角,以避免使用getcorner引起的混淆,它不支持 UCS 旋轉。

生成的多段線將在當前圖層上構建,繼承在評估程序時活動的所有對象屬性(顏色、線寬、線型等)。

(defun c:caverec ( / *error* acos newton postprocess cmd tst a b c d e f g l n p q r s w x z a1 a2 b1 b2 c1 c2 ii cmin cmax lw dx dy ll )

    (defun *error* ( m )
        (if command-s
            (command-s "_.undo" "_e")
            (vl-cmdf "_.undo" "_e")
        )
        (if cmd
            (setvar 'cmdecho cmd)
        )
        (if m
            (prompt m)
        )
        (princ)
    )

    (defun acos ( x )
        (cond
            (   (equal x 1.0 1e-8) 0.0   )
            (   (equal x -1.0 1e-8) pi   )
            (   (and (> x 0) (equal x 0.0 1e-8)) (/ pi 2.0)   )
            (   (and (< x 0) (equal x -0.0 1e-8)) (* 3.0 (/ pi 2.0))   )
            (   (atan (sqrt (- 1.0 (* x x))) x)   )
        )
    )

    (defun newton ( chord arclen / k x ) ;; use the Newton method to compute the arc half angle acminording to its length and chord
        (setq k (/ chord arclen)
              x pi
        )
        (repeat 10
            (setq x (- x (/ (- (sin x) (* k x)) (- (cos x) k))))
        )
    )

    (defun n ( m c / r ) ;; n - area between arc and its chord ; m - sagitta of arc ; c - chord of arc
        (if (> (setq r (/ (+ (expt m 2) (/ (expt c 2) 4.0)) (* 2.0 m))) m)
            (-
                (*
                    (* (expt r 2) pi)
                    (/ (acos (/ (- r m) r)) pi)
                )
                (*
                    (- r m)
                    (/ c 2.0)
                )
            )
            (progn (prompt "\nr not bigger than m...") (exit))
        ) ;; if
    ) ;; Area between arc and its chord

    (defun r ( c l / a ) ;; r - radius of arc ; c - chord of arc ; l - length of arc

        ;; (setq r (/ (+ (expt i 2) (expt (/ c 2) 4.0)) (* 2.0 i))) ;;; ( * )
        ;; (setq i (- r (sqrt (- (expt r 2) (/ (expt c 2) 4.0)))))

        ;; i^2+c^2/4=2*r^2(1-(cos(a/2))) ;; cosine theorem
        ;; i^2=2*r^2(1-(cos(a/2)))-c^2/4 ;;; ( 0 ) ;;;
        ;; ( * ) => r=(i^2+c^2/4)/(2*i)
        ;; r=(2*r^2(1-(cos(a/2)))-c^2/4+c^2/4)/(2*i)
        ;; r=r^2*(1-(cos(a/2)))/i
        ;; i=r*(1-(cos(a/2)))
        ;; i/r=1-cos(a/2)
        ;; cos(a/2)=1-i/r
        ;; a/2=acos(1-i/r)
        ;; a=2*acos(1-i/r)
        ;; <) = r^2*pi*(a/(2*pi))
        ;; <) = r^2*pi*2*acos(1-i/r)/(2*pi)
        ;; <) = r^2*acos(1-i/r)
        ;; |) = <) - <|
        ;; |) n = r^2*acos(1-i/r)-(r-i)*c/2 ;;; ( I ) ;;;
        ;; n=r^2*acos(1-i/r)-r*c/2+i*c/2
        ;; n=r^2*a/2-r*c/2+i*c/2 ;;; ( II ) ;;;
        ;; r^2*a/2-r*c/2+i*c/2-n=0
        ;; r=(c/2[+/-]sqrt(c^2/4-2*a*(i*c/2-n)))/a
        ;; ) = r*a=c/2+sqrt(c^2/4-a*i*c+2*a*n) ;; must be "+" [  )  is acways bigger than  |  ,pcus here is hacf of  |  ,so here this is especiaccy the case  ] ;;; ( III ) ;;;
        ;; |> = i*c/2 ;;; ( IV ) ;;;
        
        ;; c'=sqrt(i^2+c^2/4) ;;; ( V ) ;;;
        ;; i'^2+c'^2/4=2*r^2(1-(cos(a/4))) ;; cosine theorem
        ;; ( V ) => i'^2+(i^2+c^2/4)/4=2*r^2(1-(cos(a/4)))
        ;; i'^2=2*r^2(1-(cos(a/4)))-(i^2+c^2/4)/4 ;;; ( VI ) ;;;
        ;; ( * ) => r=(i'^2+c'^2/4)/(2*i')
        ;; ( V ) => r=(i'^2+(i^2+c^2/4)/4)/(2*i')
        ;; ( VI ) => r=(2*r^2(1-(cos(a/4)))-(i^2+c^2/4)/4+(i^2+c^2/4)/4)/(2*i')
        ;; r=r^2(1-(cos(a/4))/i'
        ;; i'=r*(1-(cos(a/4))) ;;; ( VII ) ;;;
        ;; i'/r=1-cos(a/4)
        ;; cos(a/4)=1-i'/r
        ;; a/4=acos(1-i'/r)
        ;; a=4*acos(1-i'/r)
        ;; <) = r^2*pi*(a/(2*pi))
        ;; <) = r^2*pi*4*acos(1-i'/r)/(2*pi)
        ;; <) = 2*r^2*acos(1-i'/r)
        ;; ( I ) => /) = \) [ |) = <) - <| ] => n1=n2 = 2*r^2*acos(1-i'/r)-(r-i')*c'/2
        ;; ( V ) => n1=n2 = 2*r^2*acos(1-i'/r)-(r-i')*sqrt(i^2+c^2/4)/2 ;;; ( VIII ) ;;;
        ;; |) = n = |> + /) + \) <=> ( IV ) & ( VIII ) => n = i*c/2 + 4*r^2*acos(1-i'/r)-(r-i')*sqrt(i^2+c^2/4)/2
        ;; ( VII ) => n=i*c/2+4*r^2*acos(1-r*(1-(cos(a/4)))/r)-(r-r*(1-(cos(a/4))))*sqrt(i^2+c^2/4)/2
        ;; n=i*c/2+r^2*a/4-r*(cos(a/4))*sqrt(i^2+c^2/4)/2 ;;; ( IX ) ;;;
        ;; ( II ) & ( IX ) => n = r^2*a/2-r*c/2+i*c/2=i*c/2+r^2*a/4-r*(cos(a/4))*sqrt(i^2+c^2/4)/2
        ;; r^2*(a/4-a/2)+r*(c/2-(cos(a/4)*sqrt(i^2+c^2/4)/2))=0 |/r
        ;; -r*a/4+c/2-cos(a/4)*sqrt(i^2+c^2/4)/2=0 |*-4
        ;; r*a-2*c+2*cos(a/4)*sqrt(i^2+c^2/4)=0
        ;; r*a=2*(c-cos(a/4)*sqrt(i^2+c^2/4)) ;;; ( X ) ;;;
        ;; r=2*(c-cos(a/4)*sqrt(i^2+c^2/4))/a
        ;; ( 0 ) => r=2*(c-cos(a/4)*sqrt(2*r^2(1-(cos(a/2)))-c^2/4+c^2/4))/a
        ;; r=2*(c-cos(a/4)*sqrt(2)*r*sqrt(1-(cos(a/2))))/a |*(a/r)
        ;; a=2*(c-cos(a/4)*sqrt(2)*sqrt(1-(cos(a/2))))
        ;; a=2*c-2*sqrt(2)*cos(a/4)*sqrt(1-(cos(a/2)))
        ;; a=2*c-2*sqrt(2)*cos(a/4)*sqrt(1-((cos(a/4))^2-(sin(a/4))^2))
        ;; a=2*c-2*sqrt(2)*cos(a/4)*sqrt(2*(cos(a/4))^2)
        ;; a=2*c-4*(cos(a/4))^2
        ;; a+4*(cos(a/4))^2=2*c ; t=a/4
        ;; 4*t+4*(cos(t))^2=2*c |/4
        ;; t+(cos(t))^2=c/2
        ;; t=acos(sqrt(c/2-t))

        (setq a (newton c l))
        (setq r (abs (/ c 2.0 (sin a))))
    ) ;; Arc radius

    (defun x ( e l1 l2 ii / n1 n2 )
        (setq ii (- ii 0.01))
        (setq n1 (n ii c1))
        (setq n2 (n ii c2))
        (setq r1 (/ (+ (expt ii 2) (expt (/ c1 2) 4.0)) (* 2.0 ii)))
        (setq a1 (* 2.0 (acos (/ (- r1 ii) r1))))
        (setq r2 (/ (+ (expt ii 2) (expt (/ c2 2) 4.0)) (* 2.0 ii)))
        (setq a2 (* 2.0 (acos (/ (- r2 ii) r2))))
        (if (< e (+ n1 n2))
            (x e (l c1 a1 ii) (l c2 a2 ii) ii)
            ii
        )
    )

    (defun l ( c a i ) ;; l - length of arc ; c - chord of arc ; a - angle of arc ; i - sagitta of arc
        (* 2.0
            (-
                c
                (*
                    (cos (/ a 4.0))
                    (sqrt (+ (expt i 2) (/ (expt c 2) 4.0)))
                )
            )
        )
    )

    (defun postprocess ( lw / lwx a1 a2 b1 b2 r1 r2 ii g loop dxf42 )
        (setq lwx (entget lw))
        (setq b1 (cdr (assoc 42 lwx)))
        (setq b2 (cdr (assoc 42 (cdr (member (cons 42 b1) lwx)))))
        (setq a1 (* 4.0 (atan b1)) a2 (* 4.0 (atan b2)))
        (setq r1 (abs (/ c1 2.0 (sin (/ a1 2.0)))))
        (setq r2 (abs (/ c2 2.0 (sin (/ a2 2.0)))))
        (setq ii (- r1 (sqrt (- (expt r1 2) (/ (expt c1 2) 4.0)))))
        (setq loop 1)
        (prompt "\nleft mouse click for finish ; < - concaving ; > - convexing shape ; speed - type : 1,2,3,4,5,6,7,8,9...")
        (while (/= (car (setq g (grread))) 3)
            (if (and (= (car g) 2) (< 48 (cadr g) 58))
                (progn (prompt "\nselected speed : ") (princ (setq loop (- (cadr g) 48))))
                (repeat loop
                    (cond
                        (   (equal g (list 2 60))
                            (setq ii (+ ii (* loop 0.01)))
                        )
                        (   (equal g (list 2 62))
                            (setq ii (- ii (* loop 0.01)))
                        )
                    )
                    (setq b1 (/ ii c1 -0.5) b2 (/ ii c2 -0.5))
                    (setq dxf42 (vl-remove-if '(lambda ( x ) (/= (car x) 42)) lwx))
                    (entupd (cdr (assoc -1 (entmod (mapcar '(lambda ( x ) (cond ( (and (= (car x) 42) (= (rem (vl-position x dxf42) 2) 0)) (cons 42 b1) ) ( (and (= (car x) 42) (/= (rem (vl-position x dxf42) 2) 0)) (cons 42 b2) ) ( t x ))) lwx)))))
                )
            )
        )
    )

    (setq cmd (getvar 'cmdecho))
    (setvar 'cmdecho 0)
    (if (equal 0 (getvar 'undoctl)) 
        (vl-cmdf "_.undo" "_all")
    )
    (if
        (or
            (not (equal 1 (logand 1 (getvar 'undoctl))))
            (equal 2 (logand 2 (getvar 'undoctl)))
        ) ;; or
        (vl-cmdf "_.undo" "_control" "_all")
    )
    (if (equal 4 (logand 4 (getvar 'undoctl)))
        (vl-cmdf "_.undo" "_auto" "_off")
    )
    (while (equal 8 (logand 8 (getvar 'undoctl)))
        (vl-cmdf "_.undo" "_end")
    )
    (vl-cmdf "_.undo" "_begin")
    (if
        (and
            (setq p (getpoint "\nPick or specify first corner : "))
            (progn
                (prompt "\nPick or specify opposite corner : ")
                (while (= (car (setq g (grread t))) 5)
                    (setq q (cadr g))
                    (redraw)
                    (setq dx (- (car q) (car p)))
                    (setq dy (- (cadr q) (cadr p)))
                    (mapcar
                       '(lambda ( pair )
                            (grdraw (car pair) (cadr pair) 2 0)
                        )
                        (mapcar
                           '(lambda ( a b )
                                (mapcar
                                   '(lambda ( c d )
                                        (mapcar '+ c d)
                                    )
                                    a b
                                )
                            )
                            (repeat 4
                                (setq ll (cons (list p q) ll))
                            )
                            (list
                                (list (list 0 0) (list 0 (- dy)))
                                (list (list dx 0) (list 0 0))
                                (list (list dx dy) (list (- dx) 0))
                                (list (list 0 dy) (list (- dx) (- dy)))
                            )
                        )
                    )
                )
                q
            )
            (mapcar 'set '(p q) (mapcar '(lambda ( x ) (mapcar x p q)) '(min max)))
            (setq c1 (- (car q) (car p)) c2 (- (cadr q) (cadr p)))
            (setq cmin (min c1 c2) cmax (max c1 c2))
            (setq z (trans '(0.0 0.0 1.0) 1 0 t))
            (or
                (progn
                    (while
                        (and
                            (not f)
                            (setq a
                                (cond
                                    (   (initget 6)   )
                                    (   (setq a (getreal "\nArcs bulge angle in decimal degrees <90.0> : "))   )
                                    (   (prompt "\nArcs sagitta instead of angle : \nleft mouse click for \"Yes\" (sagitta input) / enter for \"No\" (proceed with 90.0 degree) : ")   )
                                    (   t
                                        (while
                                            (and
                                                (not (equal (setq g (grread)) (list 2 13)))
                                                (/= (car g) 3)
                                            )
                                        )
                                        (if (= (car g) 3)
                                            (setq f nil a nil)
                                            (progn (setq f t) 90.0)
                                        )
                                    )
                                )
                            )
                            (setq tst
                                (> a 90.0) ;; Adjacent arcs do not cross each other
                            )
                            (setq f (not tst))
                            (setq a (cvunit a "degree" "radian"))
                            (setq tst
                                (not
                                    (<=
                                        (- (/ (sin (/ a 4.0)) (cos (/ a 4.0))))
                                        (/ (/ cmin 2.0) cmax -0.5)
                                        0.0
                                    )
                                ) ;; Opposite arcs do not cross each other
                            )
                            (setq f (not tst))
                        ) ;; and
                    ) ;; Arcs bulge angle
                    a
                )
                (progn
                    (while
                        (and
                            (not f)
                            (setq s
                                (cond
                                    (   (initget 6)    )
                                    (   (setq s (getdist "\nArcs sagitta <1.0> : "))   )
                                    (   (prompt "\nArcs by area instead of angle or sagitta : \nleft mouse click for \"Yes\" (area input) / enter for \"No\" (proceed with 1.0 sagitta distance) : ")   )
                                    (   t
                                        (while
                                            (and
                                                (not (equal (setq g (grread)) (list 2 13)))
                                                (/= (car g) 3)
                                            )
                                        )
                                        (if (= (car g) 3)
                                            (setq f nil s nil)
                                            (progn (setq f t) 1.0)
                                        )
                                    )
                                )
                            )
                            (setq tst
                                (> s (/ cmin 2.0)) ;; Opposite arcs do not cross each other
                            )
                            (not (setq f (not tst)))
                        ) ;; and
                        (if tst
                            (prompt "\ntoo large sagitta... retry...")
                        )
                    ) ;; Arcs sagitta
                    s
                )
                (progn
                    (while
                        (and
                            (not f)
                            (or
                                (setq tst
                                    (not
                                        (<=
                                            (setq c
                                                (-
                                                    (setq d (* c1 c2))
                                                    (* 2 (n (- (abs (/ c1 2.0 (sin (/ pi 4.0)))) (sqrt (- (expt (abs (/ c1 2.0 (sin (/ pi 4.0)))) 2) (/ (expt c1 2) 4.0)))) c1))
                                                    (* 2 (n (- (abs (/ c2 2.0 (sin (/ pi 4.0)))) (sqrt (- (expt (abs (/ c2 2.0 (sin (/ pi 4.0)))) 2) (/ (expt c2 2) 4.0)))) c2))
                                                )
                                            )
                                            (setq w
                                                (cond
                                                    (   (initget 7)   )
                                                    (   (setq w (getreal (strcat "\nSpecify desired area from : " (rtos c 2 20) " to " (rtos d 2 20) " : ")))
                                                        w
                                                    )
                                                )
                                            )
                                            d
                                        )
                                    ) ;; Choosen area in valid range
                                )
                                (not (setq f (not tst)))
                            ) ;; or
                        )
                        (prompt "\nInvalid area input...")
                        (setq f nil)
                    ) ;; Area input
                    w
                ) ;; progn
            ) ;; or
            (setq b
                (cond
                    (   a
                        (list (- (/ (sin (/ a 4.0)) (cos (/ a 4.0)))) (- (/ (sin (/ a 4.0)) (cos (/ a 4.0)))))
                    )
                    (   s
                        (mapcar '(lambda ( c ) (/ s c -0.5)) (list c1 c2))
                    )
                    (   w
                        (setq e (/ (- d w) 2.0))
                        (setq r1 (abs (/ c1 2.0 (sin (/ pi 4.0)))))
                        (setq ii (- r1 (sqrt (- (expt r1 2) (/ (expt c1 2) 4.0)))))
                        (setq a1 (* 2.0 (acos (/ (- r1 ii) r1))))
                        (setq r2 (abs (/ c2 2.0 (sin (/ pi 4.0)))))
                        (setq a2 (* 2.0 (acos (/ (- r2 ii) r2))))
                        (setq s (x e (l c1 a1 ii) (l c2 a2 ii) ii))
                        (mapcar '(lambda ( c ) (/ s c -0.5)) (list c1 c2))
                    )
                )
            )
        ) ;; and
        (setq lw
            (entmakex
                (list
                   '(000 . "LWPOLYLINE")
                   '(100 . "AcDbEntity")
                   '(100 . "AcDbPolyline")
                   '(090 . 4)
                   '(070 . 1)
                    (cons 038 (caddr (trans '(0.0 0.0 0.0) 1 z)))
                    (cons 010 (trans p 1 z))
                    (cons 042 (car b))
                    (cons 010 (trans (list (car q) (cadr p)) 1 z))
                    (cons 042 (cadr b))
                    (cons 010 (trans q 1 z))
                    (cons 042 (car b))
                    (cons 010 (trans (list (car p) (cadr q)) 1 z))
                    (cons 042 (cadr b))
                    (cons 210 z)
                )
            )
        )
    ) ;; if
    (prompt "\nleft mouse click to finish, enter to adjust with (grread)...")
    (while
        (and
            (not (equal (setq g (grread)) (list 2 13)))
            (/= (car g) 3)
        )
        (prompt "\nenter or left click...")
    )
    (if (/= (car g) 3)
        (postprocess lw)
    )
    (*error* "\ndone...")
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM