家园首页· 下载中心· 图纸中心· 文章中心· 教学中心· 晓东词典· 资源中心· FTP联盟· 校友录· 邮购服务
   论坛首页免费注册个人设置帮助退出论坛 爱心币规则  快速链接 游乐园  

  为改善网站速度,本站接受大家捐款,共建家园,点击查看汇款方法和捐款朋友名单...


晓东CAD家园 : Powered by vBulletin version 2.2.1 家园首页 >> 家园论坛 > …编程开发版块 > ※AutoLISP/VLISP 开发技术※ > [求助]:能够创建类似多线的线型么(不平行)?
  上一主题   下一主题
作者
主题 发布新主题    回复主题
file2me [查找更多关于file2me的帖子]
初级会员


ID: No.314175
发贴数: 12

经验值: 25%
等级: 2 级

现金:9¥
存款:

积分: 0
注册日期: 2005.08.27
日均在线: 0.00 小时
来  自:
1楼楼主说:[求助]:能够创建类似多线的线型么(不平行)?

多线命令mline是否由autolisp编写?
如果是,源程序在哪个文件里?
想研究一下

具体问题在三楼



向版主反映该贴 | IP: 已记录


由 file2me 于 2006年06月30日 03:18 最后编辑

2006年06月29日 01:08
file2me 离线引用回复 点这里给 file2me 发送一条悄悄话 查找 file2me 的更多帖子 编辑/删除
zxq0220 [查找更多关于zxq0220的帖子]等级27
青铜长老


ID: No.166843
发贴数: 937

经验值: 24%
等级: 27 级

现金:134¥
存款:1300¥

积分: 1
注册日期: 2004.08.17
日均在线: 0.48 小时
来  自: 北京
2楼楼主说:

不是。有MLINE实体。



向版主反映该贴 | IP: 已记录


2006年06月29日 04:04
zxq0220 离线引用回复 点这里给 zxq0220 发送一条悄悄话 查找 zxq0220 的更多帖子 编辑/删除
file2me [查找更多关于file2me的帖子]
初级会员


ID: No.314175
发贴数: 12

经验值: 25%
等级: 2 级

现金:9¥
存款:

积分: 0
注册日期: 2005.08.27
日均在线: 0.00 小时
来  自:
3楼楼主说:

谢谢回答,但不懂,实体是什么意思?
我现在需要了解多线的实现过程,来编辑我需要的命令。
具体是:
目标:画一条线a的同时,并行自动生成另一条线b(但不一定平行,多线只能平行),接着转折继续画线到,仍有新的并行线,最后的结果是两条并行的折线。如上图。
麻烦:用lisp能够实现并行线的绘制,但转折后的麻烦就来了,新的并行线与转折前的要不分离要不交叉。如下图
实际如果能在lisp中实现自动fillet,也就解决了问题,但似乎fillet在lisp中很难使用,对于我这样的生手很成问题。
请指点。



file2me 附带了这个的图片 :

向版主反映该贴 | IP: 已记录


由 file2me 于 2006年07月03日 03:07 最后编辑

2006年06月30日 03:06
file2me 离线引用回复 点这里给 file2me 发送一条悄悄话 查找 file2me 的更多帖子 编辑/删除
xiao_longxin [查找更多关于xiao_longxin的帖子]
超级会员


ID: No.224081
发贴数: 382

经验值: 21%
等级: 18 级

现金:271¥
存款:200¥

积分: 5
注册日期: 2005.03.09
日均在线: 0.24 小时
来  自: 杭州
4楼楼主说:

先用多义线带宽度绘出线段,再把此线段的轮廓勾绘出来



向版主反映该贴 | IP: 已记录



举一要反三
触类要旁通

2006年06月30日 09:04
xiao_longxin 离线引用回复 点这里给 xiao_longxin 发送一条悄悄话 查找 xiao_longxin 的更多帖子 编辑/删除
snoopychen [查找更多关于snoopychen的帖子]积分28
超级会员


ID: No.8476
发贴数: 365

经验值: 82%
等级: 17 级

现金:633¥
存款:

积分: 28
注册日期: 2002.08.04
日均在线: 0.31 小时
来  自:
5楼楼主说:

Autodesk早期版本的双线程序dline.lsp,假如看透的说不定可以写出需要的代码

;;;   DLINE.LSP
;;;   Copyright (C) 1990-1994 by Autodesk, Inc.
;;;      
;;;   
Permission to use, copy, modify, and distribute this software
;;;   for any purpose and without fee is hereby granted, provided
;;;   that the above copyright notice appears in all copies and that
;;;   both that copyright notice and this permission notice appear in
;;;   all supporting documentation.
;;;
;;;   
THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED
;;;   WARRANTY.  ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR
;;;   PURPOSE AND OF MERCHANTABILITY ARE HEREBY DISCLAIMED.
;;;
;;;   
DESCRIPTION
;;;     
;;;     
This is a general purpose "double-line/arc" generator.  It performs
;;;     automatic corner intersection cleanups, as well as a number of other
;;;     features described below.
;;;  
;;;     
The user is prompted for a series of endpoints.  As they are picked
;;;     "DLINE"  segments are drawn on the current layer.  Options are
;;;     available for changing the Width of the DLINE, specifying whether
;;;     or not to Snap to existing lines or arcs, whether or not to
;;;     Break the lines or arcs when snapping to them, and which of the
;;;     following to do:  
;;;     
;;;     
Set the global variable dl:ecp to the values listed below:
;;;  
;;;     
Value  Meaning
;;;     ---------------------------
;;;       
0    No end caps
;;;       1    Start end cap only
;;;       2    Ending end cap only
;;;       3    Both end caps
;;;       4    Auto ON -- Cap any end not on a line or arc.
;;;       
;;;     
The user may choose to back up as far as the beginning of the command
;;;     by typing "U" or "Undo", both of which operate as AutoCAD's "UNDO 1"
;;;     does.
;;;     
;;;     Curved DLINE'
s are drawn using the AutoCAD ARC command and follow as
;;;     
closely as possible its command structure for the various options.
;;;  
;;;----------------------------------------------------------------------------
;;;   
OPERATION
;;;
;;;     
The routine is executed, after loading, by typing either DL or DLINE
;;;     at which time you are presented with the opening line and menu of
;;;     choices:
;;;     
;;;       
Dline, Version 1.12, (c) 1990-1994 by Autodesk, Inc.  
;;;       Break/
Caps/Dragline/Offset/Snap/Undo/Width/<start point>:
;;;     
;;;     
Typing Break allows you to set breaking of lines and arcs found at
;;;     the start and end points of any segment either ON or OFF.
;;;     
;;;       Break
Dline's at start and end points?  OFF/<ON>:
;;;     
;;;     Typing Caps allows you to specify how the DLINE will be finished
;;;     off when exiting the routine, per the values listed above.
;;;     
;;;       Draw which endcaps?  Both/End/None/Start/<Auto>:
;;;       
;;;     The default of Auto caps an end only if you did not snap to an arc
;;;     or line.
;;;     
;;;     Typing Dragline allows you to set the location of the dragline
;;;     relative to the centerline of the two arcs or lines to any value
;;;     between - 1/2 of "tracewid" and + 1/2 of "tracewid".  (There is a
;;;     local variable you may set if you want to experiment with offsets
;;;     outside this range;  the results may not be correct, your choice.
;;;     See the function (dl_sao) for more information.)
;;;     
;;;       Set dragline position to Left/Center/Right/<Offset from center = 0.0>:
;;;     
;;;     Enter any real number or one of the keywords.  The value in the angle
;;;     brackets is the default value and changes as you change the dragline
;;;     position.
;;;     
;;;     Offset allows the first point you enter to be offset from a known
;;;     point.
;;;     
;;;       Offset from:  (enter a point)
;;;       Offset toward:    (enter a point)
;;;       Enter the offset distance:   (enter a distance or real number)
;;;  
;;;     Snap allows you to set the snapping size and turn snapping ON or OFF.
;;;     
;;;       Set snap size or snap On/Off.  Size/OFF/<ON>:
;;;       New snap size (1 - 10):
;;;     
;;;     The upper limit may be reset by changing the value of MAXSNP to a
;;;     value other than 10.  Higher values may be necessary for ADI display
;;;     drivers, but generally, you should keep this value somewhere in the
;;;     middle of the allowed range for snapping to work most effectively
;;;     in an uncluttered drawing, and toward the lower end for a more
;;;     cluttered drawing.  You may also use object snap to improve your
;;;     aim.
;;;     
;;;     This feature allows you to very quickly "snap" to another line or arc,
;;;     breaking it at the juncture and performing all of the intersection
;;;     cleanups at one time without having to be precisely on the line, i.e.,
;;;     you can be visually one the line and it will work, or you can use
;;;     object snap to be more precise.
;;;     
;;;     Undo backs you up one segment in the chain of segments you are drawing,
;;;     stopping when there are no more segments to be undone.  All of the
;;;     necessary points are saved in lists so that the DLINE will close, cap,
;;;     and continue correctly after any number of undo'
s.
;;;     
;;;     
Width prompts you for a new width.
;;;     
;;;       New
DLINE width <1.0000>:
;;;       
;;;     
You may enter a new width and continue the DLINE in the same direction
;;;     you were drawing before;  if you do this, connecting lines from the
;;;     endpoints of the previous segment are drawn to the start points of
;;;     the new segment.
;;;     
;;;     If
you press RETURN after closing a DLINE or before creating any
;;;     DLINE's, you will see this message:
;;;     
;;;       No continuation point -- please pick a point.  
;;;       Break/Caps/Dragline/Offset/Snap/Undo/Width/<start point>:  
;;;     
;;;     After you pick the first point, you will see this set of options:
;;;     
;;;       Arc/Break/CAps/CLose/Dragline/Snap/Undo/Width/<next point>:
;;;       
;;;     Picking more points will draw straight DLINE segments until either
;;;     RETURN is pressed or the CLose option is chosen.
;;;     
;;;     CLose will close the lines if you have drawn at least two segments.
;;;     
;;;     Selecting Arc presents you with another set of choices:
;;;     
;;;       Break/CAps/CEnter/CLose/Dragline/Endpoint/Line/Snap/Undo/Width/<second point>:
;;;     
;;;     All of the options here are the same as they are for drawing straight
;;;     DLINE'
s except CEnter, Endpoint, and Line.
;;;     
;;;     
The default option, CEnter, and Endpoint are modeled after the ARC
;;;     command in AutoCAD and exactly mimic its operation including all of
;;;     the subprompts.  Refer to the AutoCAD reference manual for exact usage.
;;;     
;;;     
The Line option returns you to drawing straight DLINE segments.
;;;     
;;;     
Snapping to existing LINE's an ARC's accomplishes all of the trimming
;;;     and extending of lines and arcs necessary, including cases where arcs
;;;     and lines do not intersect.  In these cases a line is drawn from either;
;;;     
a point on the arc at the perpendicular point from the center of the
;;;     arc to the line, to the line, or along the line from the centers of the
;;;     two arcs that do not intersect at the points where this line crosses
;;;     the two arcs.  In this way, we ensure that all DLINE's can be closed
;;;     visually.
;;;     
;;;     Breaking will not work unless Snapping is turned on.
;;;     
;;;----------------------------------------------------------------------------
;;;  GLOBALS:
;;;     dl:osd -- dragline alignment offset from center of two lines or arcs.
;;;     dl:snp -- T if snapping to existing lines and arcs.
;;;     dl:brk -- T if breaking existing lines and arcs.
;;;     dl:ecp -- Bitwise setting of caps when exiting.
;;;     v:stpt -- Continuation point.
;;;----------------------------------------------------------------------------
;;;
;;; ===========================================================================
;;; ===================== load-time error checking ============================
;;;

  (defun ai_abort (app msg)
;;LCA - COMMENT: *error* defun no longer evaluates as a list.
     (defun *error* (s)
        (if old_error (setq *error* old_error))
        (princ)
     )
     (if msg
       (alert (strcat " Application error: "
                      app
                      " \n\n  "
                      msg
                      "  \n"
              )
       )
     )
     (exit)
  )

;;; Check to see if AI_UTILS is loaded, If not, try to find it,
;;; and then try to load it.
;;;
;;; If it can'
t be found or it can't be loaded, then abort the
;;; loading of this file immediately, preserving the (autoload)
;;; stub function.

  (cond
     (  (and ai_dcl (listp ai_dcl)))          ; it'
s already loaded.

     (  (
not (findfile "ai_utils.lsp"))                     ; find it
        
(ai_abort "DLINE"
                  
(strcat "Can't locate file AI_UTILS.LSP."
                          "\n Check support directory."
)))

     (  (
eq "failed" (load "ai_utils" "failed"))            ; load it
        
(ai_abort "DLINE" "Can't load file AI_UTILS.LSP"))
  )

  (if (
not (ai_acadapp))               ; defined in AI_UTILS.LSP
      
(ai_abort "DLINE" nil)         ; a Nil <msg> supresses
  
)                                    ; ai_abort's alert box dialog.

;;; ==================== end load-time operations ===========================
;;; Main function

(defun dline  (/ strtpt nextpt pt1    pt2    spts   wnames elast
                 uctr   pr     prnum  temp   ans    dir    ipt
                 v      lst    dist   cpt    rad    orad   ftmp
                 spt    ept    pt     en1    en2    npt    cpt1
                 flg    cont   flg2   flgn   ang    tmp    undo_setting
                 brk_e1 brk_e2 bent1  bent2  nn     nnn    
                 dl_osm dl_oem dl_oce dl_opb dl_obm dl_ver
                 dl_err dl_oer dl_arc fang   MAXSNP ange   
                 savpt1 savpt2 savpt3 savpt4 savpts
              )

  ;; Version number.  Reset this local if you make a change.
  (setq dl_ver "1.12")  
  
  ;; Reset this value higher for ADI drivers.
  (setq MAXSNP 10)              

  (setq dl_osm (getvar "osmode")
        dl_oce (getvar "cmdecho")
        dl_opb (getvar "pickbox")
  )

  ;;
  ;; Internal error handler defined locally
  ;;

  (defun dl_err (s)                   ; If an error (such as CTRL-C) occurs
                                      ; while this command is active...
    (if (/= s "Function cancelled")
      (if (= s "quit / exit abort")
        (princ)
        (princ (strcat "\nError: " s))
      )
    )
    (command "_.UNDO" "_EN")
    (ai_undo_off)
    (if dl_oer                        ; If an old error routine exists
      (setq *error* dl_oer)           ; then, reset it
    )
;;LCA - WARNING: The OSMODE sysvar has changed.
    (if dl_osm (setvar "osmode" dl_osm))
    (if dl_opb (setvar "pickbox" dl_opb))
    
    ;; Reset command echoing on error
    (if dl_oce (setvar "cmdecho" dl_oce))      
    (princ)
  )
  
  ;; Set our new error handler
  (if (not *DEBUG*)
    (if *error*
      (setq dl_oer *error* *error* dl_err)
      (setq *error* dl_err)
    )
  )

  (setvar "cmdecho" 0)
  (ai_undo_on)                       ; Turn on UNDO
  (command "_.UNDO" "_GROUP")
;;LCA - WARNING: The OSMODE sysvar has changed.
  (setvar "osmode" 0)
  (if (null dl:opb) (setq dl:opb (getvar "pickbox")))

  
  (setq nextpt "Straight")

  ;; Get the first segment'
s start point

  
(menucmd "s=dline1")
  (
graphscr)
  (
princ (strcat "\nDline, Version " dl_ver ", (c) 1990-1994 by Autodesk, Inc. "))
  
  (
setq cont T)
  (while
cont
    
(dl_m1)

    ;;
Ready to draw successive DLINE segments

    
(dl_m2)
  )
  
;;
LCA - WARNING: The OSMODE sysvar has changed.
  (if
dl_osm (setvar "osmode" dl_osm))
  (if
dl_opb (setvar "pickbox" dl_opb))

  (
ai_undo_off)                      ; Return UNDO to initial state

  
;; Reset command echoing
  
(if dl_oce (setvar "cmdecho" dl_oce))      
  (
menucmd "s=s")
  (
princ)
)
;;;
;;;
Main function subsection 1.
;;;
;;;
dl_m1 == DLine_Main_1
;;;
(
defun dl_m1 ()
  (
setq temp T
        uctr nil
  
)
  (if
dl_arc
    
(setq nextpt "Arc")
    (
setq nextpt "Line")
  )
  ;;
temp set to nil when a valid point is entered.
  (while
temp
    
(initget "Break Caps Dragline Offset Snap Undo Width")
    (
setq strtpt (getpoint
      
"\nBreak/Caps/Dragline/Offset/Snap/Undo/Width/<start point>: "))
    (
cond
      
((= strtpt "Dragline")
        (
dl_sao)
      )
      ((=
strtpt "Break")
        (
initget "ON OFf")
        (
setq dl:brk (getkword
          
"\nBreak Dline's at start and end points?  OFf/<ON>: "))
        (
setq dl:brk (if (= dl:brk "OFf") nil T))    
      )
      ((=
strtpt "Offset")
        (
dl_ofs)
      )
      ((=
strtpt "Snap")
        (
dl_sso)
      )
      ((=
strtpt "Undo")
        (
princ "\nAll segments already undone. ")
        (
setq temp T)
      )
      ((=
strtpt "Width")
        (
initget 6)
        (
dl_snw)
        (
setq temp T)
      )
      ((
null strtpt)
        (if
v:stpt
          
(setq strtpt v:stpt
                temp   nil
          
)
          (
progn
            
(princ "\nNo continuation point -- please pick a point. ")
          )
        )
      )
      ((=
strtpt "Caps")
        (
endcap)    
      )
      ;; If
none of the above, it must be OK to continue - a point has been
      
;; picked or entered from the keyboard.
      (
T
        
(setq v:stpt strtpt
              temp   nil
        
)
      )
    )
  )
)
;;;
;;;
Main function subsection 2.
;;;
;;;
dl_m3 == DLine_Main_2
;;;
(
defun dl_m2 (/ temp)
  (
setq spts (list strtpt)
        
uctr 0
  
)
  (if
dl:snp
    
(dl_ved "brk_e1" strtpt)
  )
  ;;
Make sure that the offset is not greater than 1/2 of "tracewid", even
  
;; if the user transparently resets it while the command is running.
  (
setq temp (/ (getvar "tracewid") 2.0))
  (if (<
dl:osd (- temp))
    (
setq dl:osd (- temp))
  )
  (if (>
dl:osd temp)
    (
setq dl:osd temp)
  )
    
  (while (and
nextpt (/= nextpt "CLose"))
    (if (/=
nextpt "Quit")
      (if
dl_arc
        
(progn
          
(menucmd "s=dline2")
          (
initget
            
"Break CAps CEnter CLose Dragline Endpoint Line Snap Undo Width")
          (
setq nextpt (getpoint strtpt (strcat
            
"\nBreak/CAps/CEnter/CLose/Dragline/Endpoint/"
            "Line/Snap/Undo/Width/<second point>: "
))
          )
        )
        (
progn
          
(menucmd "s=dline3")
          (
initget "Arc Break CAps CLose Dragline Snap Undo Width")
          (
setq nextpt (getpoint strtpt
            
"\nArc/Break/CAps/CLose/Dragline/Snap/Undo/Width/<next point>: ")
          )
          (
grdraw nextpt strtpt 1)
        )
      )
    )
    (
setq v:stpt (last spts))
    (
cond
      
((= nextpt "Dragline")
        (
dl_sao)
      )
      ((=
nextpt "Width")
        (
dl_snw)
        
      )
      ((=
nextpt "Undo")
        (
cond
          
;;((= uctr 0) (princ "\nNothing to undo. ") )
          ((=
uctr 0) (setq nextpt nil) )
          ((>
uctr 0)
            (
command "_.U")
            (
setq spts   (dl_lsu spts 1))
            (
setq savpts (dl_lsu savpts 2))
            (
setq wnames (dl_lsu wnames 2))
            (
setq uctr (- uctr 2))
            (
setq strtpt (last spts))
          )
        )
        (if
dl:snp
          
(if (= uctr 0)
            (
dl_ved "brk_e1" strtpt)
          )
        )
      )
      ((=
nextpt "Break")
        (
initget "ON OFf")
        (
setq dl:brk (getkword
          
"\nBreak Dline's at start and end points?  OFF/<ON>: "))
        (
setq dl:brk (if (= dl:brk "OFf") nil T))    
        
        (if
dl:snp
          
(dl_ved "brk_e1" strtpt)
        )
        (if
dl_arc
          
(setq nextpt "Arc")
          (
setq nextpt "Line")
        )
      )
      ((=
nextpt "Snap")
        (
dl_sso)
      )
      ((=
nextpt "Arc")
        (
setq dl_arc T)               ; Change to Arc segment prompt.
      )
      ((=
nextpt "Line")
        (
setq dl_arc nil)             ; Change to Line segment prompt.
      )
      ((=
nextpt "CLose")
        (
dl_cls)
      )
      ((= (
type nextpt) 'LIST)
        (dl_ds)
      )
      ((= nextpt "CEnter")
        (dl_ceo)
      )
      ((= nextpt "Endpoint")
        (dl_epo)
      )
      ((= nextpt "CAps")
        (endcap)                      ; Set which caps to draw when exiting.
      )
      (T
        (setq nextpt nil cont nil)
        (if (> uctr 1)
          (if (= (logand 4 dl:ecp) 4)
            (progn
              (if (null brk_e1) (command "_.LINE" savpt1 savpt2 ""))
              (dl_ssp)
              (if (null brk_e2) (command "_.LINE" savpt3 savpt4 ""))
            )
            (progn
              (if (= (logand 1 dl:ecp) 1)
                (command "_.LINE" savpt1 savpt2 "")
              )
              (if (= (logand 2 dl:ecp) 2)
                (progn
                  (dl_ssp)
                  (command "_.LINE" savpt3 savpt4 "")
                )
              )
            )
          )
        )
        (if brk_e1 (setq brk_e1 nil))
        (if brk_e2 (setq brk_e2 nil))
        (command "_.UNDO" "_EN")
      )                               ; end of inner cond  
    )                                 ; end of outer cond  
  )                                   ; end of while
)
;;; ------------------ End Main Functions ---------------------------
;;; ---------------- Begin Support Functions ------------------------


;;;
;;; Close the DLINE with either straight or arc segments.  
;;; If closing with arcs, the minimum number of segments already drawn
;;; is 1, otherwise it is 2.
;;;
;;; dl_cls == DLine_CLose_Segments
;;;
(defun dl_cls ()
  (if (or (and (null dl_arc) (< uctr 4)
               (if (> uctr 1)
                 (/= (dl_val 0 (entlast)) "ARC")
                 (not (> uctr 1))
               )
          )
          (and dl_arc (< uctr 2)))
    (progn
      (princ "\nCannot close -- too few segments. ")
      (if dl_arc
        (setq nextpt "Arc")
        (setq nextpt "Line")
      )
    )
    (progn
      (command "_.UNDO" "_GROUP")
      (setq nextpt (nth 0 spts))
      (if (null dl_arc)
        ;; Close with line segments
        (dl_mlf 3)
        (progn
          (setq tmp (last wnames)
                ange (trans '
(1 0 0) (dl_val -1 tmp) 1)
                
ange (angle '(0 0 0) ange)
                dir (if (= (dl_val 0 tmp) "LINE")
                      (angle (trans (dl_val 10 tmp) 0 1)
                             (trans (dl_val 11 tmp) 0 1))
                      (progn
                        (setq dir (+ (dl_val 50 tmp) ange)
                              dir (if (> dir (* 2 pi))
                                    (- dir (* 2 pi))
                                    dir
                                  )
                        )
                        (if (equal dir
                                   (setq dir (angle (trans (dl_val 10 tmp)
                                                           (dl_val -1 tmp)
                                                           1)
                                                    strtpt
                                             )
                                   )
                                   0.01)
                          (- dir (/ pi 2))
                          (+ dir (/ pi 2))
                        )
                      )
                    )
          )
          (command "_.ARC"
                   strtpt
                   "_E"
                   nextpt
                   "_D"
                   (* dir (/ 180 pi))
          )
          ;; Close with arc segments
          (dl_mlf 4)
        )
      )
      ;; set nextpt to "CLose" which will cause an exit.
      (setq nextpt "CLose"
            v:stpt nil
            cont   nil
      )
    )
  )
)
;;;
;;; A point was entered, do either an arc or line segment.
;;;
;;; dl_ds == DLine_Do_Segment
;;;
(defun dl_ds ()
  (if (equal strtpt nextpt 0.0001)
    (progn
      (princ "\nCoincident point -- please try again. ")
      (if dl_arc
        (setq nextpt "Arc")
        (setq nextpt "Line")
      )
    )
    (progn
      (command "_.UNDO" "_GROUP")
      (setq nextpt (list (car nextpt) (cadr nextpt) (caddr strtpt)))
      (if dl_arc
        (progn
          (command "_.ARC" strtpt nextpt)
          (prompt "\nEndpoint: ")
          (command pause)
          (setq nextpt (getvar "lastpoint")
                v:stpt nextpt)
          (setq temp (entlast))
          ;; Delete the last arc segment so we can find the line or
          ;; arc under it.
          (entdel temp)
          (if dl:snp
            (dl_ved "brk_e2" nextpt)
          )
          ;; Restore the arc previously deleted.
          (entdel temp)
          ;; Draw the arc segments.
          (dl_mlf 2)
        )
        (progn
          (setq v:stpt nextpt)
          (if dl:snp
            (dl_ved "brk_e2" nextpt)
          )
          (if (and brk_e1 (eq brk_e1 brk_e2) (= (dl_val 0 brk_e1) "LINE"))
            (progn
              (princ "\nSecond point cannot be on the same line segment. ")
              (setq brk_e2 nil)
            )
            ;; Draw the line segments.
            (dl_mlf 1)
          )
        )
      )
      (if brk_e2 (setq nextpt "Quit"))
    )
  )
)
;;;
;;; The CEnter option for drawing arc segments was selected.
;;;
;;; dl_ceo == DLine_CEnter_Option
;;;
(defun dl_ceo ()
  (command "_.UNDO" "_GROUP")
  (setq temp T)
  (while temp
    (initget 1)
    (setq cpt (getpoint strtpt "\nCenter point: "))
    (if (<= (distance cpt strtpt) (- (/ (getvar "tracewid") 2.0) dl:osd))
      (progn
        (princ
        "\nThe radius defined by the selected center point is too small ")
        (princ "\nfor the current Dline width.  ")
        (princ "Please select another point.")
      )
      (setq temp nil)
    )
  )
  ;; Start the ARC command so that we can get visual dragging.
  (command "_.ARC" strtpt "_C" cpt)
  (initget "Angle Length Endpoint")
  (setq nextpt (getkword "\nAngle/Length of chord/<Endpoint>: "))
  (cond
    ((= nextpt "Angle")
      (prompt "\nIncluded angle: ")
      (command "_A" pause)
      (setq nextpt (dl_vnp)
            v:stpt nextpt
      )
      ;; Draw the arc segments.
      (dl_mlf 2)
    )
    ((= nextpt "Length")
      (prompt "\nChord length: ")
      (command "_L" pause)
      (setq nextpt (dl_vnp)
            v:stpt nextpt
      )
      ;; Draw the arc segments.
      (dl_mlf 2)
    )
    (T
      (prompt "\nEndpoint: ")
      (command pause)
      (setq nextpt (dl_vnp)
            v:stpt nextpt
      )
      ;; Draw the arc segments.
      (dl_mlf 2)
    )
  )
)
;;;
;;; Endpoint option was selected.
;;;
;;; dl_epo == DLine_End_Point_Option
;;;
(defun dl_epo ()
  (command "_.UNDO" "_GROUP")
  (initget 1)
  (setq cpt (getpoint "\nEndpoint: "))
  ;; Start the ARC command so that we can get visual dragging.
  (command "_.ARC" strtpt "_E" cpt)
  (initget "Angle Direction Radius Center")
  (setq nextpt (getkword "\nAngle/Direction/Radius/<Center>: "))
  (cond
    ((= nextpt "Angle")
      (prompt "\nIncluded angle: ")
      (command "_A" pause)
      (setq nextpt (dl_vnp)
            v:stpt nextpt
      )
      ;; Draw the arc segments.
      (dl_mlf 2)
    )
    ((= nextpt "Direction")
      (prompt "\nTangent direction: ")
      (command "_D" pause)
      (setq nextpt (dl_vnp)
            v:stpt nextpt
      )
      ;; Draw the arc segments.
      (dl_mlf 2)
    )          
    ((= nextpt "Radius")
      (setq temp T)
      (while temp
        (initget 1)
        (setq rad (getdist cpt "\nRadius: "))
        
        (if (or (<= rad (/ (getvar "tracewid") 2.0))
                (< rad (/ (distance strtpt cpt) 2.0)))
          (progn
            (princ "\nThe radius entered is less than 1/2 ")
            (princ "of the Dline width or is invalid")
            (princ "\nfor the selected endpoints.  ")
            (princ "Please enter a radius greater than ")
            (if (< (/ (getvar "tracewid") 2.0)
                   (/ (distance strtpt cpt) 2.0))
              (princ (rtos (/ (distance strtpt cpt) 2.0)))
              (princ (rtos (/ (getvar "tracewid") 2.0)))
            )
            (princ ". ")
          )
          (setq temp nil)
        )
      )
      (command "_R" rad)
      (setq nextpt (dl_vnp)
            v:stpt nextpt
      )
      ;; Draw the arc segments.
      (dl_mlf 2)
    )
    (T
      (prompt "\nCenter: ")
      (command pause)
      (setq nextpt (dl_vnp)
            v:stpt nextpt
      )
      ;; Draw the arc segments.
      (dl_mlf 2)
    )
  )
)
;;;
;;; Set the ending save points for capping the DLINE.
;;;
;;; dl_ssp == DLine_Set_Save_Points
;;;
(defun dl_ssp ( / temp)
  (setq temp (length savpts))
  (if (> temp 1)
    (progn
      (setq savpt3 (nth (- temp 2) savpts)
            savpt4 (nth (- temp 1) savpts)
      )
    )
  )
)
;;;
;;; Set the alignment of the "ghost" line to one of the following values:
;;;   
;;;   Left   == -1/2 of width (Real number)
;;;           > -1/2 of width (Real number)
;;;   Center == 0.0
;;;           < +1/2 of width (Real number)
;;;   Right  == +1/2 of width (Real number)
;;;
;;; All of the alignment options are taken as if you are standing at the
;;; start point of the line or arc looking toward the end point, with
;;; left and negative values being on the left, center or 0.0 being
;;; directly in line, and right or positive on the right.
;;;
;;; Entering a real number equal to 1/2 of the width sets an absolute offset
;;; distance from the centerline, while specifying the same offset distance
;;; with the keywords tells the routine to change the offset distance to
;;; match 1/2 of the width, whenever it is changed.
;;;
;;; NOTE:  If you wish to allow the dragline to be positioned outside
;;;      of the two arcs or lines being created, you may set the local
;;;      variable "dragos" = T, on the 4th line of the defun, which  
;;;      checks that the offset value entered is not greater or less
;;;      than + or - TRACEWID / 2.
;;;      
;;;      You should be aware that the results of allowing this to occur
;;;      may not be obvious or necessarily correct.  Specifically, when
;;;      drawing lines with a width of 1 and an offset of 4, if you draw
;;;      segments as follows, the lines will cross back on themselves.
;;;      
;;;      dl 0,0,0 10,0,0 10,5 then 5,5
;;;      
;;;      However, this can be quite useful for creating parallel DLINE'
s.
;;;      
;;;
dl_sao == DLine_Set_Alignment_Option
;;;
(
defun dl_sao (/ temp dragos)
  (
initget "Left Center Right")
  (
setq temp dl:osd)
  ;;(
setq dragos T)                   ; See note above.
  (
setq dl:osd (getreal (strcat
    
"\nSet dragline position to Left/Center/Right/<Offset from center = "
    
(rtos dl:osd) ">: ")))
  (
cond
    
((= dl:osd "Left")
      (
setq dl:aln 1
            dl
:osd (- (/ (getvar "tracewid") 2.0))
      )
    )
    ((=
dl:osd "Center")
      (
setq dl:aln 0
            dl
:osd 0.0
      
)
    )
    ((=
dl:osd "Right")
      (
setq dl:aln 2
            dl
:osd (/ (getvar "tracewid") 2.0)
      )
    )
    ((= (
type dl:osd) 'REAL)
      (if dragos
        (setq dl:aln nil)
        (progn
          (setq dl:aln nil)
          (if (> dl:osd (/ (getvar "tracewid") 2.0))
            (progn
              (princ "\nValue entered is out of range.  Reset to ")
              (princ (/ (getvar "tracewid") 2.0))
              (setq dl:osd (/ (getvar "tracewid") 2.0))
            )
          )
          (if (< dl:osd (- (/ (getvar "tracewid") 2.0)))
            (progn
              (princ "\nValue entered is out of range.  Reset to ")
              (princ (- (/ (getvar "tracewid") 2.0)))
              (setq dl:osd (- (/ (getvar "tracewid") 2.0)))
            )
          )
        )
      )
    )
    (T
      (setq dl:osd temp)
    )
  )
)
;;;
;;; Set a new DLINE width.
;;;
;;; dl_snw == DLine_Set_New_Width
;;;
(defun dl_snw ()
  (initget 6)
  (setvar "tracewid"
    (if (setq temp (getdist (strcat
      "\nNew DLINE width <" (rtos (getvar "tracewid")) ">: ")))
      temp
      (getvar "tracewid")
    )
  )
  (if dl:aln
    (cond
      ((= dl:aln 1) ; left aligned
        (setq dl:osd (- (/ (getvar "tracewid") 2.0)))
      )
      ((= dl:aln 2) ; right aligned
        (setq dl:osd (/ (getvar "tracewid") 2.0))
      )
      (T
        (princ)     ; center aligned
      )
    )
  )
)
;;;
;;; Get an offset from a given point to the start point toward a second
;;; point.  The distance between the two points is the default, but any
;;; positive distance may be entered.  If a negative number is entered,
;;; it is used as a percentage distance from the "Offset from" point
;;; toward the "Offset toward" point, i.e., if -75 is entered, a point
;;; 75% of the distance between the two points listed above is returned.
;;;
;;;
;;; dl_ofs == DLine_OFfset_Startpoint
;;;
(defun dl_ofs ()
  (menucmd "s=osnapb")
  (initget 1)
  (setq strtpt (getpoint "\nOffset from: "))
  (initget 1)
  (setq nextpt (getpoint strtpt "\nOffset toward: "))
  
  (setq dist (getdist strtpt (strcat
    "\nEnter the offset distance <" (rtos (distance strtpt nextpt))
    ">: ")))
  (setq dist (if (or (= dist "") (null dist))
               (distance strtpt nextpt)
               (if (< dist 0)
                 (* (distance strtpt nextpt) (/ (abs dist) 100.0))
                 dist
               )
             )
  )              
  (setq strtpt (polar strtpt
                      (angle strtpt nextpt)
                      dist
               )
  )
  (setq temp nil)
  (command "_.UNDO" "_GROUP")
)
;;;
;;; Set snap options to ON, OFF or set the size of the area to be searched
;;; by (ssget point) via "pickbox".  This value is being limited for built-
;;; in display drivers at 10 pixels.  For ADI drivers it may be necessary
;;; to bump up this number by adjusting "MAXSNP" at the top of this file.
;;;
;;; dl_sso == DLine_Set_Snap_Options
;;;
(defun dl_sso ()
  (initget "ON OFf Size")
  (setq ans (getkword
    "\nSet snap size or snap On/Off.  Size/OFF/<ON>: "))
  (if (= ans "OFf")
    (progn
      (setq dl:snp nil)
      (setvar "pickbox" 0)
    )
    (if (= ans "Size")
      (progn
        (setq dl:snp T ans 0)
        (while (or (< ans 1) (> ans MAXSNP))
          (setq ans (getint (strcat
            "\nNew snap size (1 - " (itoa MAXSNP) ") <" (itoa dl:opb) ">: ")))

          (if (or (= ans "") (null ans))
            (setq ans dl:opb)
          )
        )
        (setvar "pickbox" ans)
        (setq dl:opb ans)
      )
      (progn
        (setq dl:snp T)
        (setvar "pickbox" dl:opb)
      )  
    )
  )
  (if dl:snp
    (if (= uctr 0)
      (dl_ved "brk_e1" strtpt)
    )
  )
  (if dl_arc
    (setq nextpt "Arc")
    (setq nextpt "Line")
  )

)
;;;
;;; Obtain and verify the extrusion direction of an entity at the
;;; start point or endpoint of the line or arc we are drawing.
;;;
;;; dl_ved == DLine_Verify_Extrusion_Direction
;;;
(defun dl_ved (vent pt)
  ;; Get entity to break if the user snapped to a DLINE.
  ;; Make sure that it is a line or arc and that its extrusion
  ;; direction is parallel to the current UCS.
  (if (set (read vent) (ssget pt))
    (progn
      (set (read vent) (ssname (eval (read vent)) 0))
      (if (and
            (or (= (dl_val 0 (eval (read vent))) "ARC")
                (= (dl_val 0 (eval (read vent))) "LINE")
            )
            (equal (caddr(dl_val 210 (eval (read vent))))
                   (caddr(trans '
(0 0 1) 1 0)) 0.001)
          )
        (
princ)
        (
progn
          
(princ (strcat
            
"\nEntity found is not an arc or line, "
            "or is not parallel to the current UCS. "
))
          (
set (read vent) nil)
        )
      )
    )
  )
  (eval (
read vent))
)
;;;
;;;
Verify nextpt.
;;;
Get the point on the arc at the opposite
;;; end from the start point (strtpt).
;;;
;;;
dl_vnp == DLine_Verify_NextPt
;;;
(
defun dl_vnp (/ temp cpt ang rad)

  (
setq temp (entlast))
  (if (= (
dl_val 0 temp) "LINE")
    (
setq nextpt (if (equal strtpt (dl_val 10 temp) 0.001)
                   (
dl_val 11 temp)
                   (
dl_val 10 temp)
                 )
    )
    ;;
Then it must be an arc...
    (
progn
      
;; get its center point
      
(setq cpt  (trans (dl_val 10 temp) (dl_val -1 temp) 1)
            
ang  (dl_val 50 temp)     ; starting angle
            rad  
(dl_val 40 temp)     ; radius
      
)
      (
setq ange (trans '(1 0 0) (dl_val -1 temp) 1)
            ange (angle '
(0 0 0) ange)
            
ang (+ ang ange)
      )
      (if (>
ang (* 2 pi))
        (
setq ang (- ang (* 2 pi)))
      )
      (
setq nextpt (if (equal strtpt (polar cpt ang rad) 0.01)
                     (
polar cpt (dl_val 51 temp) rad)
                     (
polar cpt ang rad)
                   )
      )
    )
  )
)
;;; -----------------
Main Line Drawing Function -------------------
;;;
;;;
Draw the lines.
;;;
;;;
dl_mlf == DLine_Main_Line_Function
;;;
(
defun dl_mlf (flg / temp1 temp2 newang ang1 ang2
                     ent cpt ang rad1 rad2 sent1 sent2
                     tmpt1 tmpt2 tmpt3 tmpt4
)

  ;;
Verify nextpt
  
(if (null nextpt) (setq nextpt (dl_vnp)))
  
  (if (
equal nextpt (nth 0 spts) 0.01)
    (if
dl_arc
      
(setq flg 4)
      (
setq flg 3)
    )
  )
   
  (
setq temp1  (+ (/ (getvar "tracewid") 2.0) dl:osd)
        
temp2  (- (getvar "tracewid") temp1)
        
newang (angle strtpt nextpt)
        
ang1   (+ (angle strtpt nextpt) (/ pi 2))
        
ang2   (- (angle strtpt nextpt) (/ pi 2))
  )
  (
cond
    
((= flg 1)                        ; if drawing lines
      
(dl_dls nil ang1 temp1)         ; Draw line segment 1
      
(dl_dls nil ang2 temp2)         ; Draw line segment 2
    
)
    ((or (=
flg 2) (= flg 4))         ; else drawing arcs...
      (
setq tmp (entlast)             ; get the last arc entity
            ent  
(entget tmp)         ; (i.e., the guideline)
            ;;
get its center point
            cpt  
(trans (dl_val 10 tmp) (dl_val -1 tmp) 1)
            
ang  (dl_val 50 tmp)      ; starting angle
      
)
      (
setq ange (trans '(1 0 0) (dl_val -1 tmp) 1)
            ange (angle '
(0 0 0) ange)
            
ang (+ ang ange)
      )
      (if (>
ang (* 2 pi))
        (
setq ang (- ang (* 2 pi)))
      )
     
      ;; if
start angle needs revision
      
(if (equal (angle cpt strtpt) ang 0.01)   
        (
progn
          
;; Start angle needs revision.
          (
setq strt_a T
                rad1  
(+ (dl_val 40 tmp) temp2) ; outer radius
                rad2  
(- (dl_val 40 tmp) temp1) ; inner radius
          
)
          (
setq ent (subst (cons 40 rad2) ; modify its radius
                           
(assoc 40 ent)
                           
ent))
          (
entmod ent)
          (
dl_atl)                    ; Add ename to list
          (
setq save_1 ent)
          (
setq sent1 (dl_val -1 tmp))                            
          (if (=
flg 4)
            (if (>
uctr 2)
              (
dl_das 0 rad2 50)      ; modify arc endpt and close
            
)
            (
dl_das nil rad2 50)      ; else modify arc endpt
          
)
          ;;
Create the "parallel" arc
          
(command "_.OFFSET" (getvar "tracewid") ; offset the arc
                              
(list tmp '(0 0 0))
                              (polar cpt ang (+ 1 rad1 rad2))
                              "")
          (setq tmp (entlast)         ; get the offset arc
                ent  (entget tmp))
          (dl_atl)                    ; Add ename to list
          (setq save_2 ent)
          (setq sent2 tmp)
          (if (= flg 4)
            (if (> uctr 3)
              (progn
                (dl_das 1 rad1 50)    ; modify arc endpt and close

                ;; set nextpt to "CLose" which will cause an exit.
                (setq nextpt "CLose"
                      v:stpt nil
                      cont   nil
                )
              )
            )
            (dl_das nil rad1 50)      ; else modify arc endpt
          )

        )
        (progn                        ; if end angle needs revision
          ;; End angle needs revision.
          (setq strt_a nil
                rad1  (+ (dl_val 40 tmp) temp1) ; outer radius
                rad2  (- (dl_val 40 tmp) temp2) ; inner radius
          )
          (setq ent (subst (cons 40 rad1) ; modify its radius
                           (assoc 40 ent)
                           ent))
          (entmod ent)                             
          (dl_atl)                    ; Add ename to list
          (setq save_1 ent)
          (setq sent1 (dl_val -1 tmp))                            
          (if (= flg 4)
            (if (> uctr 2)
              (dl_das 0 rad1 51)      ; modify arc endpt and close
            )
            (dl_das nil rad1 51)      ; else modify arc endpt
          )
          ;; Create the "parallel" arc
          (command "_.OFFSET" (getvar "tracewid")    
                            (list tmp '
(0 0 0))
                            
cpt
                            
"")
          (
setq tmp (entlast)         ; get the last arc entity
                ent  
(entget tmp))
          (
dl_atl)                    ; Add ename to list
          (
setq save_2 ent)
          (
setq sent2 tmp)
          (if (=
flg 4)
            (if (>
uctr 3)
              (
progn
                
(dl_das 1 rad2 51)    ; modify arc endpt and close

                
;; set nextpt to "CLose" which will cause an exit.
                (
setq nextpt "CLose"
                      
v:stpt nil
                      cont   nil
                
)
              )
            )
            (
dl_das nil rad2 51)      ; else modify arc endpt
          
)
        )
      )

    )
    ((=
flg 3)                        ; if straight closing
      
(setq nextpt (nth 0 spts)
            
ang1   (+ (angle strtpt nextpt) (/ pi 2))
            
ang2   (- (angle strtpt nextpt) (/ pi 2))
      )
      (
dl_dls 0 ang1 temp1)
      (
dl_dls 1 ang2 temp2)

      ;;
set nextpt to "CLose" which will cause an exit.
      (
setq nextpt "CLose"
            
v:stpt nil
            cont   nil
      
)
    )
    (
T
      
(princ "\nERROR:  Value out of range. ")
      (exit)
    )
  )
  (
setq strtpt nextpt   
        spts   
(append spts (list strtpt))
        
savpts (append savpts (list savpt3))
        
savpts (append savpts (list savpt4))
  )
  (
command "_.UNDO" "_E")                ; only end when DLINE's have been drawn
)
;;; ------------------- End Support Functions -----------------------
;;; ---------------- Begin Line Drawing Functions -------------------
;;;
;;; Straight DLINE function
;;;
;;; dl_dls == DLine_Draw_Line_Segment
;;;
(defun dl_dls (flgn ang temp / j k pt1 pt2 tmp1 ent1 p1 p2)

  (mapcar                             ; get endpoints of the offset line
    '
(lambda (j k)
       (
set j (polar (eval k) ang temp))
     )      
     
'(pt1 pt2)
     '
(strtpt nextpt)
  )
  (
cond
    
((= uctr 0)
      ;;
Set points 1 and 2 for segment 1.
      
(setq p1 (if (dl_l01 brk_e1 "1" pt1 pt2 strtpt) ipt savpt1))
      (
setq pt2 (if (dl_l01 brk_e2 "3" pt2 pt1 nextpt) ipt savpt3))
      (
setq pt1 p1)
    )
    ((=
uctr 1)
      ;;
Set points 1 and 2 for segment 2.
      
(setq p1 (if (dl_l01 brk_e1 "2" pt1 pt2 strtpt) ipt savpt2))
      (
setq pt2 (if (dl_l01 brk_e2 "4" pt2 pt1 nextpt) ipt savpt4))
      (
setq pt1 p1)
      
      ;;
Now break the line or arc found at the start point
      
;; if there is one, and we are in a breaking mood.
      (if (and
dl:brk brk_e1)
        (
progn
          
(command "_.BREAK" brk_e1 savpt1 savpt2)
        )
      )
      ;;
Now break the line or arc found at the end point
      
;; if there is one, and we are in a breaking mood.
      (if (and
dl:brk brk_e2)
        (
progn
          
(if (eq brk_e1 brk_e2)
            (
progn
              
;; Delete first line so we can find the arc or line that
              
;; we found previously.
              (
entdel (nth 0 wnames))  
              (
dl_ved "brk_e2" nextpt)
              ;;
Restore first line
              
(entdel (nth 0 wnames))
            )
          )
          (
command "_.BREAK" brk_e2 savpt3 savpt4)
        )
      )
      ;; Do
not set brk_e2 nil... it will be set later.
    )
    ((= (
rem uctr 2.0) 0)    
      (
setq fang nil)
      (
setq p1 (dl_dl2 pt1))          ; Draw line part 2
      
(setq pt2 (if (dl_l01 brk_e2 "3" pt2 pt1 strtpt)
                  
ipt
                  savpt3
                
)
      )
      (
setq pt1 p1)
      (if
flgn                        ; if closing
        
(progn
          
(setq tmp1 (nth flgn wnames)
                
ent1 (entget tmp1)    ; get the corresponding prev. entity
          
)
          (if (= (
dl_val 0 tmp1) "LINE")
            ;; if
it's a line
            (setq pt2 (dl_mls nil 10))           
            ;; if it'
s an arc
            
(setq pt2 (dl_mas T nil pt2 pt1 nil))  
          )
        )                             
      )
    )
    (
T
      
(setq p1 (dl_dl2 pt1))              ; Draw line part 2
      
(setq pt2 (if (dl_l01 brk_e2 "4" pt2 pt1 nextpt)
                  
ipt
                  savpt4
                
)
      )
      (
setq pt1 p1)
      (if
flgn                        ; if closing
        
(progn
          
(setq tmp1 (nth flgn wnames)
                
ent1 (entget tmp1)    ; get the corresponding prev. entity
                brk_e1 nil
                brk_e2 nil
          
)
          (if (= (
dl_val 0 tmp1) "LINE")
            ;; if
it's a line
            (setq pt2 (dl_mls nil 10))           
            ;; if it'
s an arc
            
(setq pt2 (dl_mas T nil pt2 pt1 nil))  
          )
        )                             
      )
      ;;
Now break the line or arc found at the end point
      
;; if there is one, and we are in a breaking mood.
      (if (and
dl:brk brk_e2)
        (
progn
          
(command "_.BREAK" brk_e2 savpt3 savpt4)
        )
      )
      ;; Do
not set brk_e2 nil... it will be set later.
    )
  )
  (
command "_.LINE" pt1 pt2 "")         ; draw the line
  
(setq wnames (if (null wnames)
                 (list (
setq elast (entlast)) )
                 (
append wnames (list (setq elast (entlast)))))
        
uctr   (1+ uctr)
  )
  
wnames
)
;;;
;;;
Set pt1 or pt2 based on whether there is an arc or line to be broken.
;;;
;;;
dl_l01 == DLine_draw_Lines_0_and_1
;;;
(
defun dl_l01 (bent1 n p1 p2 pt / temp)
  (
setq n (strcat "savpt" n))
  (
setq spt nil)
  (if
bent1
    
(if (= (dl_val 0 bent1) "LINE")
      (
progn
        
(setq temp (inters (trans (dl_val 10 bent1) 0 1)
                            (
trans (dl_val 11 bent1) 0 1)
                            
p1
                            p2
                            nil
                    
)
        )
        (if
temp
          
(set (read n) temp)
          (
progn
            
(set (read n) p1)
            (
setq brk_e1 nil)
          )
        )
      )
      (
progn
        
(set (read n) (dl_ial bent1 p1 p2 pt))
        ;;
Spt is set only if there was no intersection point.
        (if
spt
          
(progn
            
(setq ipt (eval (read n)))
            (
set (read n) spt)
          )
        )
      )
    )
    (
set (read n) p1)
  )
  (if
spt
    T
    nil
  
)
)
;;;
;;; Do
more of the line drawing stuff.  This is where we call the modify
;;; functions for the previous arc or line segment.  The line end being
;;; modified is always the group 11 end, but we have to test the start
;;; and end angle of an arc to tell which end to modify.
;;;
;;;
dl_dl2 == DLine_Draw_Line_segment_part_2
;;;
(
defun dl_dl2 (npt)
  (
setq tmp1 (nth (- uctr 2) wnames)
        
ent1 (entget tmp1))           ; get the corresponding prev. entity
   
  
(if (= (dl_val 0 tmp1) "LINE")  
    ;;
Check angles 0 180, -180  and 360...   
    (if (or  (
equal (angle strtpt nextpt)
                   (
angle (trans (dl_val 10 tmp1) 0 1)
                          (
trans (dl_val 11 tmp1) 0 1)) 0.001)
             (
equal (angle strtpt nextpt)
                   (
angle (trans (dl_val 11 tmp1) 0 1)
                          (
trans (dl_val 10 tmp1) 0 1)) 0.001)
             (
equal (+ (* 2 pi) (angle strtpt nextpt))
                   (
angle (trans (dl_val 10 tmp1) 0 1)
                          (
trans (dl_val 11 tmp1) 0 1)) 0.001)
        )
      ;; if
it's a line
      (progn
        (setq brk_e2 nil)
        (command "_.LINE" (trans (dl_val 11 tmp1) 0 1) pt1 "")
        pt1
      )
      ;; else, if it'
s an arc
      
(progn
        
(dl_mls nil 11)
      )
    )
    ;; if
it's an arc
    (dl_mas nil nil pt1 pt2 strtpt)  
  )
)
;;;
;;; Modify line endpoint
;;;
;;; dl_mls == DLine_Modify_Line_Segment
;;;
(defun dl_mls (flg2 nn / spt ept pt)  ; flg2 = nil if line to line
                                      ;      = T   if line to arc

  ;; This is the previous entity; a line
  (setq spt (trans (dl_val 10 tmp1) 0 1)   
        ept (trans (dl_val 11 tmp1) 0 1)
  )
  (if flg2
    ;; find intersection with arc; tmp == ename of arc
    (progn
      ;; Find arc intersection with line; tmp == ename of arc.
      (setq pt (dl_ial tmp spt ept (if flgn nextpt strtpt)))
    )

    ;; find intersection with line
    (setq pt (inters spt ept pt1 pt2 nil))
  )
  ;; modify the previous line
  (if pt
    (entmod (subst (cons nn (trans pt 1 0))
                   (assoc nn ent1)
                   ent1))
    (setq pt pt2)
  )
  pt
)
;;;
;;; This routine does a variety of tasks: it calculate the distance from
;;; the center of the arc (or congruent circle) to a line, then it
;;; calculates up to two intersection points of a line and the arc,
;;; then it attempts to determine which of the points serves as a
;;; best-fit to the following criteria:
;;;
;;;   1) One end of the arc must lie "on" the line, or
;;;      one end of the line must lie on the arc.
;;;   2) Given that the point given in 1 above is p1,
;;;      and that the other point is p2, then if the arc crosses over
;;;      the line then use p2, otherwise the arc does not cross over
;;;      the line so use p1.
;;;      
;;; If the line and the arc do not intersect, then a line will be drawn
;;; from the point of intersection of the arc and the perpendicular from
;;; the line to the arc centerpoint, and the line;  The line and arc will be
;;; trimmed or extended as needed to meet these points.
;;;
;;; If the line and arc are tangent, then the arc and line are
;;; trimmed/extended to this point.
;;;
;;; p1 and p2 are two points on a line
;;; ename  == entity name of arc
;;; flg == T when the segment being drawn ends on an arc,
;;; flg == nil when the segment being drawn starts on an arc.
;;;
;;; dl_ial == DLine_Intersect_Arc_with_Line
;;;
(defun dl_ial (arc pt_1 pt_2 npt / d pi2 rad ang nang temp ipt)

  (setq cpt  (trans (dl_val 10 arc) (dl_val -1 arc) 1)  
        pi2  (/ pi 2)                 ; 1/2 pi
        ang  (angle pt_1 pt_2)                   
        nang (+ ang pi2)              ; Normal to "ang"
        temp (inters pt_1 pt_2 cpt (polar cpt nang 1) nil)
        nang (angle cpt temp)
  )
  ;; Get the perpendicular distance from the center of the arc to the line.
  (setq d (distance cpt temp))

  (cond
    ((equal (setq rad (dl_val 40 arc)) d 0.01)
      ;; One intersection.
      (setq ipt temp)
    )
    ((< rad d)                       
      ;; No intersection.
      (setq spt (polar cpt nang rad)
            ipt temp
      )
      (command "_.LINE" spt ipt "")
      ipt
    )
    (T
      ;; Two intersections. Now...
      ;; If drawing arcs, fang is set, we'
re past the first segment...
      ;;
Reset the `near' point based on the previous ipt.  This can be
      ;; quite different and necessary from the
`npt' passed in.
      (if (and dl_arc fang (> uctr 1))
        (setq npt (polar cpt fang rad))
      )
      (dl_g2p npt)
      (setq ipt (dl_bp arc pt_1 pt_2 ipt1 ipt2))
      ;; If `fang'
is not set, set it, otherwise set it to nil.
      (if
fang
        
(setq fang nil)
        (if
dl_arc (setq fang (angle cpt ipt)))
      )
      
ipt
    
)
  )
)
;;;
;;;
Get two intersection points, ordering them such that ipt1
;;; is the closer of the two points to the passed-in point "npt".
;;;
;;;
dl_g2p == DLine_Get_2_Points
;;;
(
defun dl_g2p (npt / temp l theta)
  (if (
equal d 0.0 0.01)
    (
setq theta pi2
          nang
(+ ang pi2)            ; Normal to "ang"
    
)
    (
setq l     (sqrt (abs (- (expt rad 2) (expt d 2))))
          
theta (abs (atan (/ l d)))
    )
  )
  ;;
Get the two angles to the infinite intersection points of the
  
;; congruent circle to the arc, and the line, then get the two
  
;; intersection points.
  (
setq ipt1 (polar cpt (- nang theta) rad))
  (
setq ipt2 (polar cpt (+ nang theta) rad))
  ;;
Set the closer of the two points to npt to be ipt1.
  (if (< (
distance ipt2 npt) (distance ipt1 npt))
    ;;
Swap points
    
(setq temp ipt1
          ipt1 ipt2
          ipt2 temp
    
)
    (if (
equal (distance ipt2 npt) (distance ipt1 npt) 0.01)
      (exit)
    )
  )
  
ipt1
)
;;;
;;;
Test a point `pt' to see if it is on the line `sp--ep'.
;;;
;;; dl_onl == DLine_ON_Line_segment
;;;
(defun dl_onl (sp ep pt / cpt sa ea ang)
  (if (inters sp ep pt
              (polar pt (+ (angle sp ep) (/ pi 2))
                     (/ (getvar "tracewid") 10)
              )
              T)
    T
    nil
  )
)
;;;
;;; Test a point `pt'
to see if it is on the arc `arc'.
;;;
;;; dl_ona == DLine_ON_Arc_segment
;;;
(defun dl_ona (arc pt / cpt sa ea ang)
  (setq cpt (trans (dl_val 10 arc) (dl_val -1 arc) 1)
        sa  (dl_val 50 arc)           ; angle of current ent start point
        ea  (dl_val 51 arc)           ; angle of current ent end point
        ang (angle cpt pt)            ; angle to pt.
  )
  (if (> sa ea)
    (if (or (and (> ang sa) (< ang (+ ea (* 2 pi))))
            (and (> ang (- ea (* 2 pi))) (< ang ea))
        )
      T
      nil
    )
    (if (and (> ang sa) (< ang ea)) T nil)
  )
)
;;;
;;; Get the best intersection point of an arc and a line.  The criteria
;;; are as follows:
;;;
;;;   1) The best point will lie on both the arc and the line.
;;;   2) It will be the point which causes the shortest arc to be created
;;;      such that (1) is satisfied.
;;;   3) If closing, then always use the point closest to nextpt.  Unless,
;;;      the points are equidistant, then use 1 and 2 above to tiebreak.
;;;   4) If breaking an arc with a line, always use the points nearest the
;;;      break point.
;;;
;;; dl_bp == DLine_Best_Point_of_arc_and_line
;;;
(defun dl_bp (en1 p1 p2 pp1 pp2 / temp temp1 temp2)
  (setq temp1 (dl_onl p1 p2 pp2)
        temp2 (dl_ona en1 pp2)
        temp  (if (or (= flg 1) (= flg 3)) T nil)
  )
  (if (and temp1 temp2)
    (if (and (< uctr 2)
             (and brk_e1 brk_e2))
      pp1
      (if (and temp (not fang)) pp1 pp2)
    )
    pp1
  )
)
;;; ----------------- End Line Drawing Functions --------------------
;;; ---------------- Begin Arc  Drawing Functions -------------------
;;;
;;; Draw curved DLINE
;;;
;;; dl_das == DLine_Draw_Arc_Segment
;;;
(defun dl_das (flgn orad nn / tmp1 ent1 pt ang )
  (cond
    ((= uctr 0)
      (setq sent1 tmp)
      (dl_a01 brk_e1 "1" strtpt nil)  ; DLine_draw_Arc_0_and_1
      (dl_a01 brk_e2 "3" nextpt T)    ; DLine_draw_Arc_0_and_1
    )
    ((= uctr 1)
      (setq sent1 tmp)
      (dl_a01 brk_e1 "2" strtpt nil)  ; DLine_draw_Arc_0_and_1
      (dl_a01 brk_e2 "4" nextpt T)    ; DLine_draw_Arc_0_and_1
      (dl_mae nil T)
      (dl_mae nil nil)
      ;; Now break the line or arc found at the start point
      ;; if there is one, and we are in a breaking mood.
      (if (and dl:brk brk_e1)
        (progn
          (dl_mae T T)
          (dl_mae T nil)
          (command "_.BREAK" brk_e1 savpt1 savpt2)
        )
      )
      ;; Do not set brk_e1 nil... it will be set later.
      ;; Now break the line or arc found at the end point
      ;; if there is one, and we are in a breaking mood.
      (if (and dl:brk brk_e2)
        (progn
          (if (eq brk_e1 brk_e2)
            (progn
              ;; Delete both arcs so we can find the arc or line that
              ;; we found previously.
              (entdel (nth 0 wnames))  
              (entdel (nth 1 wnames))  
              (dl_ved "brk_e2" nextpt)
              ;; Restore first line
              (entdel (nth 0 wnames))
              (entdel (nth 1 wnames))
            )
          )
          (if (null brk_e1)
            (progn
              (dl_mae T T)
              (dl_mae T nil)
            )
          )
          (command "_.BREAK" brk_e2 savpt3 savpt4)
        )
      )
      ;; Do not set brk_e2 nil... it will be set later.
    )
    ((= (rem uctr 2.0) 0)
      (setq fang nil)
      (dl_da2)                        ; Draw arc part 2
      (if fang
        (setq ftmp fang
              fang nil
        )
      )
      (setq save_1 ent)
      (setq sent1 (cdr(assoc -1 ent)))
      (setq pt2 (dl_a01 brk_e2 "3" nextpt T)) ; DLine_draw_Arc_0_and_1
      (if ftmp
        (setq fang ftmp
              ftmp nil
        )
      )
    )
    (T
      (dl_da2)                        ; Draw arc part 2
      (if fang
        (setq ftmp fang
              fang nil
        )
      )
      (setq save_2 ent)
      (setq sent1 (cdr(assoc -1 ent)))
      (setq pt2 (dl_a01 brk_e2 "4" nextpt T)) ; DLine_draw_Arc_0_and_1
      (if ftmp
        (setq fang fang
              ftmp nil
        )
      )

      ;; Now break the line or arc found at the end point
      ;; if there is one, and we are in a breaking mood.
      (if (and dl:brk brk_e2)
        (progn
          (dl_mae T T)
          (dl_mae T nil)
          (command "_.BREAK" brk_e2 savpt3 savpt4)
        )
      )
      ;; Do not set brk_e2 nil... it will be set later.
    )
  )
  (setq uctr   (1+ uctr))
)
;;;
;;; Set pt1 or pt2 based on whether there is an arc or line to be broken.
;;;
;;; dl_a01 == DLine_draw_Arcs_0_and_1
;;;
(defun dl_a01 (bent1 n pt flg / pt1 pt2 ang1 ang2 anga angb)
  ;; "n" is the point to save for end capping
  (setq n (strcat "savpt" n))
  ;; "tmp" is the arc just created.
  ;; "bent1" is the line or arc to be broken, if there is one...
  (if bent1
    (if (= (dl_val 0 bent1) "LINE")
      (progn
        (set (read n) (dl_ial tmp (trans (dl_val 10 bent1) 0 1)
                                  (trans (dl_val 11 bent1) 0 1) pt))
      )
      (progn
        (setq curcpt (trans (dl_val 10 sent1) (dl_val -1 sent1) 1)
              prvcpt (trans (dl_val 10 bent1) (dl_val -1 bent1) 1)
              pt1    (polar prvcpt (dl_val 50 bent1) (dl_val 40 bent1))
              pt2    (polar curcpt (dl_val nn sent1) (dl_val 40 sent1))
              ang1   (angle prvcpt pt1)
        )
        (if (not (equal ang1 (angle prvcpt strtpt) 0.01))
          (setq pt1  (polar prvcpt (dl_val 51 bent1) (dl_val 40 bent1))
                ang1 (angle prvcpt pt1)
                ang2 (angle curcpt pt2)
                anga (- ang1 ang2)
                angb (- ang2 ang1)
          )
        )
        (if (or (and (< anga 0.0872665)
                     (> anga -0.0872665))
                (and (< angb 0.0872665)
                     (> angb -0.0872665))
            )
          (progn
            (set (read n) pt)
            (if (= bent1 brk_e1)
              (setq brk_e1 nil)
              (setq brk_e2 nil)
            )
          )
          (set (read n) (dl_iaa sent1 bent1 pt flg))
        )
      )
    )
    (progn
      (setq cpt (trans (dl_val 10 tmp) (dl_val -1 tmp) 1))
      (set (read n) (polar cpt (angle cpt pt) orad))
    )
  )
  (eval (read n))
)
;;;
;;; Do more of the arc drawing stuff.  This is where we call the modify
;;; functions for the previous arc or line segment.  The line end being
;;; modified is always the group 11 end, but we have to test the start
;;; and end angle of an arc to tell which end to modify.
;;;
;;; dl_da2 == DLine_Draw_Arc_segment_part_2
;;;
(defun dl_da2 (/ pt)
  ;; get the corresponding previous entity
  (setq tmp1 (nth (- uctr 2) wnames)
        ent1 (entget tmp1))
  (if (= (dl_val 0 tmp1) "LINE")     
    ;; if it's a line
    (setq pt (dl_mls T 11))             
    ;; if it's an arc
    (setq pt (dl_mas nil T nil nil strtpt))
  )
  ;; pt is a point in the current UCS, not ECS
  (if pt
    (progn
      (setq ang (- (angle cpt pt) ange))
      (entmod (setq ent (subst (cons nn ang)
                       (assoc nn ent)
                       ent)))         ; modify arc endpt
    )
  )
  (if flgn                            ; if closing
    (progn
      (setq tmp1 (nth flgn wnames)     
            ent1  (entget tmp1))  ; get the flagged entity
      (if (= (dl_val 0 tmp1) "LINE")     
        ;; if it's a line
        (setq pt (dl_mls T 10))   
        ;; if it's an arc
        (setq pt (dl_mas T T nil nil nextpt))
      )
      (if pt
        (progn
          (setq ang (- (angle cpt pt) ange))
          (setq nn (if (= nn 50) 51 50))
          (entmod (setq ent (subst (cons nn ang)
                         (assoc nn ent)
                         ent)))       ; modify arc endpt
        )                             
      )
    )                             
  )
)
;;;
;;; Modify the endpoints of an arc by changing the start and end angles.
;;;
;;; dl_mae == DLine_Modify_Arc_Endpoints
;;;
(defun dl_mae (eflg sflg / nn1 nn2)
  (if (= nn 50)
    (setq nn1 50 nn2 51)
    (setq nn1 51 nn2 50)
  )
  (if sflg
    (if eflg
      (setq save_1 (subst (cons nn2
                                (angle
                                  (trans cpt    1 (cdr(assoc -1 save_1)))
                                  (trans savpt3 1 (cdr(assoc -1 save_1)))
                                )
                          )
                          (assoc nn2 save_1) save_1)
      )
      (setq save_1 (subst (cons nn1
                                (angle
                                  (trans cpt    1 (cdr(assoc -1 save_1)))
                                  (trans savpt1 1 (cdr(assoc -1 save_1)))
                                )
                          )
                          (assoc nn1 save_1) save_1)
      )
    )
    (if eflg
      (setq save_2 (subst (cons nn2
                                (angle
                                  (trans cpt    1 (cdr(assoc -1 save_1)))
                                  (trans savpt4 1 (cdr(assoc -1 save_2)))
                                )
                          )
                          (assoc nn2 save_2) save_2)
      )
      (setq save_2 (subst (cons nn1
                                (angle
                                  (trans cpt    1 (cdr(assoc -1 save_1)))
                                  (trans savpt2 1 (cdr(assoc -1 save_2)))
                                )
                          )
                          (assoc nn1 save_2) save_2)
      )
    )
  )
  (if sflg
    (entmod save_1)
    (entmod save_2)
  )
)
;;;
;;; Modify arc                        ; flg2 = nil if arc to line
;;;                                   ;      = T   if arc to arc
;;;
;;; dl_mas == DLine_Modify_Arc_Segment
;;;
(defun dl_mas (flg3 flg2 spt ept pt / nnn pt1 pt2 rad1 ange)
  ;; get some stuff
  (setq cpt1   (trans (dl_val 10 tmp1) (dl_val -1 tmp1) 1)           
        rad1   (dl_val 40 tmp1)
        ang1   (dl_val 50 tmp1)
  )
  (if (null pt)                       ; if a point is not passed in:
    (setq pt (nth 0 spts))            ; set to initial saved start point.
  )               
  (setq ange (trans '(1 0 0) (dl_val -1 tmp1) 1)
        ange (angle '(0 0 0) ange)
        ang1 (+ ang1 ange)
  )
  (if (> ang1 (* 2 pi))
    (setq ang1 (- ang1 (* 2 pi)))
  )
  (if (equal (angle cpt1 pt) ang1 0.01) ; figure out if we're looking
    (setq nnn 50)                     ; for the start or end point of
    (setq nnn 51)                     ; the beginning arc, then
  )                                   ; get the intersection point
  ;; if arc to arc
  (if flg2
    ;; then
    (progn
      ;; find intersection with arc
      (setq pt1 (dl_iaa tmp tmp1 (if flg3 nextpt strtpt) flg2))   
      (if pt1
        (progn
          (setq ang1 (- (angle cpt1 pt1) ange))
          (setq ent1 (subst (cons nnn ang1)
                            (assoc nnn ent1)
                            ent1))                 
          (entmod ent1)               ; modify arc endpt
        )
      )
    )
    ;; else
    (progn
      ;; find arc intersection with line from spt to ept
      (setq pt1 (dl_ial tmp1 spt ept pt))
      (setq ang1 (- (angle cpt1 pt1) ange))
      (setq ent1 (subst (cons nnn ang1)
                        (assoc nnn ent1)
                        ent1))                 
      (entmod ent1)                   ; modify arc endpt
    )
  )
  pt1
)
;;; ---------------- Begin Arc to Arc Functions ---------------------
;;;
;;; This routine does a variety of tasks: it calculate up to two
;;; intersection points of two arcs,
;;; then it attempts to determine which of the points serves as a
;;; best-fit to the following criteria:
;;;
;;;   1) One end of the arc must lie "on" the arc.
;;;   2) Given that the point given in 1 above is pt1,
;;;      and that the other point is pt2, then if the arc crosses over
;;;      the other arc then use pt2, otherwise the arc does not cross over
;;;      the other arc so use pt1.
;;;      
;;; If the two arcs do not intersect, then a line will be drawn
;;; from the point of intersection of the arc and the perpendicular from
;;; the line of the two arc centerpoints;  The arcs will be
;;; trimmed or extended as needed to meet these points.
;;;
;;; If the two arcs are tangent, then they are
;;; trimmed/extended to this point.
;;;
;;; Intersection point of two arcs or circles
;;; a    = radius of ename 1
;;; b    = distance from curcpt to prvcpt
;;; c    = radius of ename 2
;;; curcpt = center point of first circle or arc  -- bent1, bent2, tmp
;;; prvcpt = center point of second circle or arc -- sent1, sent2, tmp1
;;; npt  = near point for nearest test
;;;
;;; dl_iaa == DLine_Intersect_Arc_and_Arc
;;;
(defun dl_iaa  (en1 en2 npt flga / a b c s ang alpha alph ipt
                                   curcpt prvcpt temp temp1 temp2)
  (setq curcpt  (trans (dl_val 10 en1) (dl_val -1 en1) 1) ; the "last" entity
        prvcpt  (trans (dl_val 10 en2) (dl_val -1 en2) 1) ; the previous entity
        a       (dl_val 40 en2)
        b       (distance curcpt prvcpt)
        c       (dl_val 40 en1)
        s       (/ (+ a b c) 2.0)
        ang     (angle curcpt prvcpt)
  )
  (cond
    ;; circles are tangent
    ;; If (- s a) == 0, this would cause a divide by zero below...
    ((or (= (- s a) 0) (equal b (+ a c) 0.001) (equal b (abs (- a c)) 0.001))
      ;; Circles are tangent.
      (setq ipt nil)
    )
    ;; circles do not intersect
    ((and (or (> b (+ a c)) (if (> c a) (< (+ a b) c) (< (+ c b) a)))                 
          (not (equal (+ a b ) c (/ (+ a b c) 1000000))))
      ;; No intersection.
      (if (= flg 4)
        (progn
          (setq ipt (polar curcpt (angle curcpt prvcpt) c))
          (command "_.LINE" (polar prvcpt (angle prvcpt ipt) a) ipt "")
        )
        (progn
          (setq ipt (polar curcpt (angle curcpt prvcpt) c))
          (command "_.LINE" (polar prvcpt (angle prvcpt ipt) a) ipt "")
        )
      )
    )
    (T
      ;; general law of cosines formula -- (- s a) != 0
      (setq alpha (* 2.0 (atan (sqrt (abs (/ (* (- s b) (- s c))
                                             (* s (- s a)))))))
      )
      
      (setq tpt1 (polar curcpt (+ ang alpha) c)
            tpt2 (polar curcpt (- ang alpha) c)
            anga  (angle curcpt npt)
            angb  (angle prvcpt npt)
      )
      ;; Two intersections. Now...
      ;; If drawing arcs, fang is set, we're past the first segment...
      ;; Reset the
`near' point based on the previous ipt.  This can be
      ;; quite different and necessary from the `npt'
passed in.
      (if (and
dl_arc fang (> uctr 1))
        (
setq npt (polar prvcpt fang c))
      )
      (if (< (
distance tpt1 npt) (distance tpt2 npt))
        (
setq temp tpt1
              tpt1 tpt2
              tpt2 temp
        
)
      )
      (
setq temp (angle prvcpt curcpt)) ; angle from prev ent to this ent
      
(setq ipt (dl_bap en1 en2 tpt2 tpt1 nil))
      (if
fang
        
(setq fang nil)
        (if
dl_arc (setq fang (angle cpt ipt)))
      )
    )
  )
  (
setq cpt curcpt)
  (
setq cpt1 prvcpt)
  
ipt                                 ; return point
)
;;;
;;;
Get the best point for the arc/arc intersection.
;;;
;;;
dl_bap == DLine_Best_Point_to_Arc
;;;
(
defun dl_bap (en1 en2 pp1 pp2 flg / temp1 temp2)
  (
setq temp1 (dl_ona en1 pp2)
        
temp2 (dl_ona en2 pp2)
  )
  (if
temp2
    
(if (and (< uctr 2)
             (and
brk_e1 brk_e2))
      
pp1
      
(if temp1
        
(if (< uctr 2)
          
pp2
          
(if (not fang) pp2 pp1)
        )
        
pp1
      
)
    )
    
pp1
  
)        
)
;;; -----------------
End Arc  Drawing Functions --------------------
;;; --------------------
Begin Misc Functions -----------------------
;;;
;;;
Add the entity name to the list in wnames.
;;;
;;;
dl_atl == DLine_Add_To_List
;;;
(
defun dl_atl ()
  (
setq wnames (if (null wnames)
                 (list (
entlast))
                 (
append wnames (list tmp)))
  )
  
wnames
)
;;;
;;;
The value of the assoc number of <ename>
;;;
(
defun dl_val (v temp)
  (
cdr(assoc v (entget temp)))
)
;;;
;;; List
stripper : strips the last "v" members from the list
;;;
(
defun dl_lsu (lst v / m)
  (
setq m 0 temp '())
  (repeat (- (length lst) v)
    (progn
      (setq temp (append temp (list (nth m lst))))
      (setq m (1+ m))
  ) )
  temp
)
;;;
;;; Bitwise DLINE endcap setting function.
;;;
(defun endcap ()
  (initget "Auto Both End None Start")
  (setq dl:ecp (getkword
    "\nDraw which endcaps?  Both/End/None/Start/<Auto>: "))
  (cond
    ((= dl:ecp "None")
      (setq dl:ecp 0)
    )
    ((= dl:ecp "Start")
      (setq dl:ecp 1)
    )
    ((= dl:ecp "End")
      (setq dl:ecp 2)
    )
    ((= dl:ecp "Both")
      (setq dl:ecp 3)
    )
    (T  ; Auto
      (setq dl:ecp 4)
    )
  )
)
;;;
;;; Set these defaults when loading the routine.
;;;
(if (null dl:ecp) (setq dl:ecp 4))    ; default to auto endcaps
(if (null dl:snp) (setq dl:snp T))    ; default to snapping ON
(if (null dl:brk) (setq dl:brk T))    ; default to breaking ON
(if (null dl:osd) (setq dl:osd 0))    ; default to center alignment
;;;
;;; These are the c: functions.
;;;
(defun c:dl()
  (if (ai_notrans) (dline))           ; DLINE can'
t be used transparently
)
(
defun c:dline()
  (if (
ai_notrans) (dline))           ; DLINE can't be used transparently
)

(princ "  DLINE loaded.")
(princ)



向版主反映该贴 | IP: 已记录



结构分析、CAD Autolisp技术、软件使用技巧
http://qjchen.yo2.cn

2006年06月30日 09:09
snoopychen 离线引用回复 点这里给 snoopychen 发送一条悄悄话 查找 snoopychen 的更多帖子 编辑/删除
xiao_longxin [查找更多关于xiao_longxin的帖子]
超级会员


ID: No.224081
发贴数: 382

经验值: 21%
等级: 18 级

现金:271¥
存款:200¥

积分: 5
注册日期: 2005.03.09
日均在线: 0.24 小时
来  自: 杭州
6楼楼主说:

看得头都晕了!着急是不懂E文。其实我在4楼说的方法可以一试,还可以绘出带凸度的多线



向版主反映该贴 | IP: 已记录



举一要反三
触类要旁通

2006年06月30日 09:27
xiao_longxin 离线引用回复 点这里给 xiao_longxin 发送一条悄悄话 查找 xiao_longxin 的更多帖子 编辑/删除
Dream.Fei [查找更多关于Dream.Fei的帖子]
中级会员


ID: No.457130
发贴数: 127

经验值: 31%
等级: 10 级

现金:178¥
存款:

积分: 0
注册日期: 2006.06.21
日均在线: 0.06 小时
来  自: 〖№①〗
7楼楼主说:

你的另一条线,难度跟你绘的线没有任何联系吗?说出这二条线之间的关系,这样才有可能帮到你啊。



向版主反映该贴 | IP: 已记录



上班时间即在线!可以直接与我聊天。

2006年06月30日 09:44
Dream.Fei 离线引用回复 点这里给 Dream.Fei 发送一条悄悄话 查找 Dream.Fei 的更多帖子 编辑/删除
雨箭风刀 [查找更多关于雨箭风刀的帖子]等级25
青铜长老


ID: No.388422
发贴数: 786

经验值: 27%
等级: 25 级

现金:871¥
存款:

积分: 6
注册日期: 2006.01.28
日均在线: 0.46 小时
来  自:
8楼楼主说:

有点乱,不容易理解楼主的意思



向版主反映该贴 | IP: 已记录



我的博客
QQ: 51050632

2006年06月30日 11:13
雨箭风刀 离线引用回复 点这里给 雨箭风刀 发送一条悄悄话 查找 雨箭风刀 的更多帖子 编辑/删除
lzh741206 [查找更多关于lzh741206的帖子]等级31
斑竹


斑竹
ID: No.76071
发贴数: 1325

经验值: 43%
等级: 31 级

现金:106¥
存款:1800¥

积分: 18
注册日期: 2003.08.30
日均在线: 0.45 小时
来  自: 湖北武汉
9楼楼主说:

简单问题复杂化,你的问题好像和多线没什么关系:)
或者你的表述有问题?



向版主反映该贴 | IP: 已记录



随心飘荡

无梦域

2006年07月01日 00:17
lzh741206 离线引用回复 点这里给 lzh741206 发送一条悄悄话 查找 lzh741206 的更多帖子 编辑/删除
file2me [查找更多关于file2me的帖子]
初级会员


ID: No.314175
发贴数: 12

经验值: 25%
等级: 2 级

现金:9¥
存款:

积分: 0
注册日期: 2005.08.27
日均在线: 0.00 小时
来  自:
10楼楼主说:

回复:
最初由 Dream.Fei 发布
你的另一条线,难度跟你绘的线没有任何联系吗?说出这二条线之间的关系,这样才有可能帮到你啊。


我说的不清,是要有联系。但这个联系是要有变化,或说主观可以选择的。楼上有同学说和多线没什么关系,其实我也不知道和多线的实质有多大关系,只是要求绘制过程类似多线,但又有不同:
1。假设我绘制多线,我需要定制一下,比如偏移距离是10;然后我绘制一条线,随之会有一条偏移距离为10的平行线同时绘制出来,随着转折,平行线也跟着转折,直到绘制完毕
2。我要的,和这个类似,但重要的不同点,是我要的随之生成的线不一定平行,比如a1与b1距离是10,画到a2点时,b2与a2的距离要求是20——这个可以是事先定制,也可能是在绘制过程输入,然后的a3和b3的间距是20或30或10(根据需求)。

谢谢4楼,你的思路很巧妙,我想想

谢谢5楼,非常好的资料,谢谢



向版主反映该贴 | IP: 已记录


由 file2me 于 2006年07月03日 01:51 最后编辑

2006年07月03日 01:48
file2me 离线引用回复 点这里给 file2me 发送一条悄悄话 查找 file2me 的更多帖子 编辑/删除
xiao_longxin [查找更多关于xiao_longxin的帖子]
超级会员


ID: No.224081
发贴数: 382

经验值: 21%
等级: 18 级

现金:271¥
存款:200¥

积分: 5
注册日期: 2005.03.09
日均在线: 0.24 小时
来  自: 杭州
11楼楼主说:

就按我在4楼说的方法完全可以达到你的目的



向版主反映该贴 | IP: 已记录



举一要反三
触类要旁通

2006年07月03日 04:30
xiao_longxin 离线引用回复 点这里给 xiao_longxin 发送一条悄悄话 查找 xiao_longxin 的更多帖子 编辑/删除
snoopychen [查找更多关于snoopychen的帖子]积分28
超级会员


ID: No.8476
发贴数: 365

经验值: 82%
等级: 17 级

现金:633¥
存款:

积分: 28
注册日期: 2002.08.04
日均在线: 0.31 小时
来  自:
12楼楼主说:

写了一段可以变宽度的双线画法
过程:
1)取点
2)根据变化的宽度得到每条线向两边offset的距离
(其中,w1是线左边的起点和终点宽度,w1是起点宽度,w1a是终点宽度,
w2是线左边的起点和终点宽度,w2是起点宽度,w2a是终点宽度,W1和W2中,假如起始终点一样,就是普通的双线了)
在这个程序中,采用了某种模式来构建全线长的宽度
比如给了w1=2 w1a=8
那么就构建了一种(2 8 8 2 2 8 8 2),奇数段用2为起始宽度,8为终点宽度,偶数段取8,2 为起终点宽度的做法,函数是makew,假如自己建立一个宽度列表也是可以的,本程序中的做法只是为了显示效果,便于求交而已。
3)得到偏移线之后,求交,得到修剪线型
4)构建pline

程序没有什么难度和技巧,也有不少地方不足,比如采用grdraw,在缩放时这些临时画的线会丢失等等,不过说真的,我不知道变化线宽有什么必要呢,至少我自己没有遇到过。

图片不知道为什么不能显示
传到这里看看
http://autolisper.googlepages.com/w...change-full.jpg


代码:

;;;=============================================
;;;Most of the following codes are writen by   ;
;;; CHEN QING JUN                              ;
;;; Civil engineering Department,              ;
;;; South China University of Technology       ;
;;; http://autolisper.googlepages.com          ;
;;; http://autolisper.googlepages.com          ;
;;; Purpose:Draw different width double line   ;
;;; 2006.07.02                                 ;
;;; Version:0.1                                ;
;;; ============================================

;;;Main function
(defun c:test (/ p1 plist w1 w1a w2 w2a w1lst w2lst anglist seglist 
seg1list seg2list)
 (setq w1 2
	w1a 10
	w2 8
	w2a 15
  )
  (setq w1lst (makew w1 w1a 100))
  (setq w2lst (makew w2 w2a 100))
  (setq plist (getpointlst w1lst w2lst))
  (setq anglist (mapcar
		  '(lambda (x y)
		     (angle x y)
		   )
		  (1ton_1 plist)
		  (cdr plist)
		)
  )
  (setq seglist (mapcar
		  '(lambda (x y)
		     (cons x (list y))
		   )
		  (1ton_1 plist)
		  (cdr plist)
		)
  )
  (setq w1lst (makew w1 w1a (length seglist)))
  (setq w2lst (makew w2 w2a (length seglist)))
  (setq seg1list (segxlist seglist anglist 1 w1lst))
  (setq seg2list (segxlist seglist anglist (- 1) w2lst))
  (setq seg1list (intlst seg1list))
  (setq seg2list (intlst seg2list))
  (entmakepolyline seg1list)
  (entmakepolyline seg2list)
)
;;;getpointlist
(defun getpointlst (w1lst w2lst / plist p1 p i)
  (setq p1 (getpoint))
  (setq plist (append
		plist
		(list p1)
	      )
  )
  (setq i 0)
  (while (setq p (getpoint p1))
    (grdraw p1 p 9)
    (tempgrdraw p1 p i w1lst w2lst)
    (setq plist (append
		  plist
		  (list p)
		)
    )
    (setq p1 p)
    (setq i (1+ i))
  )
  plist
)
;;;tempdraw
(defun tempgrdraw (p1 p2 n lst1 lst2 / ang)
  (setq ang (angle p1 p2))
  (grdraw (polar p1 (+ ang (* pi 0.5)) (1- (nth (* n 2) lst1)))
	  (polar p2 (+ ang (* pi 0.5)) (1- (nth (1+ (* n 2)) lst1))) 251
  )
  (grdraw (polar p1 (+ ang (* pi 1.5)) (1- (nth (* n 2) lst2))) 
          (polar p2 (+ ang (* pi 1.5)) (1- (nth (1+ (* n 2)) lst2))) 251
  )
)

;; get the 1 to (n-1) element of a list
(defun 1ton_1 (lst)
  (reverse (cdr (reverse lst)))
)
;;;to get the offset segment of two side line
(defun segxlist (lst lst1 direction wlst / i res xa xb x1a x1b)
  (setq i 0)
  (if (= direction 1)
    (setq ang (* pi 0.5))
    (setq ang (* pi 1.5))
  )
  (foreach x lst
    (setq xa (car x)
	  xb (cadr x)
    )
    (setq x1a (polar xa (+ ang (nth i lst1)) (nth (* i 2) wlst)))
    (setq x1b (polar xb (+ ang (nth i lst1)) (nth (1+ (* i 2)) wlst)))
    (setq res (append
		res
		(list x1a x1b)
	      )
    )
    (setq i (1+ i))
  )
  res
)
;;;;find the inter intersections of a list of points
(defun intlst (lst / i res p1 p2 p3 p4)
  (setq i 0)
  (setq res (list (car lst)))
  (repeat (- (/ (length lst) 2) 1)
    (setq p1 (nth i lst))
    (setq i (1+ i))
    (setq p2 (nth i lst))
    (setq i (1+ i))
    (setq p3 (nth i lst))
    (setq p4 (nth (1+ i) lst))
    (setq res (append
		res
		(list (inter p1 p2 p3 p4))
	      )
    )
  )
  (setq res (append
	      res
	      (list (last lst))
	    )
  )
  res
)
(defun inter (a b c d / res)
  (if (equal b c)
    b
    (inters
      a
      b
      c
      d
      nil
    )
  )
)
;;;function of entmake lwpolyline,by ElpanovEvgeniy at 

www.theswamp.org
(defun entmakepolyline (lst)
  (entmakex (append
	      (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . 

"AcDbPolyline")
		    (cons 90 (length lst)) '(70 . 0) ;;;1 is closed
	      ) ;_  list
	      (mapcar
		'(lambda (x)
		   (cons 10 x)
		 )
		lst
	      )
	    ) ;_  append
  )
)
;;;;make width list
(defun makew (w1 w2 n / res i)
  (setq i 1)
  (repeat n
    (if (odd i)
      (setq res (append
		  res
		  (list w1 w2)
		)
      )
      (setq res (append
		  res
		  (list w2 w1)
		)
      )
    )
    (setq i (1+ i))
  )
  res
)
;;;judge whether a number is an odd number
(defun odd (x)
  (/= (/ x 2) (* 0.5 x))
)



snoopychen 附带了这个的图片 :

向版主反映该贴 | IP: 已记录



结构分析、CAD Autolisp技术、软件使用技巧
http://qjchen.yo2.cn

由 snoopychen 于 2006年09月02日 08:39 最后编辑

2006年07月06日 03:19
snoopychen 离线引用回复 点这里给 snoopychen 发送一条悄悄话 查找 snoopychen 的更多帖子 编辑/删除
时区: GMT北京时间. 现在时间: 11:46. 发布新主题    回复主题 
  上一主题   下一主题
快速回复 [字数限制(为0不限制):0]
标题:
选项:
自动分析URL
Email 通知
显示签名

在新主题帖子中上传一个附件上传附件[最大: 1024000 字节:] 附件收爱心币!
有效文件扩展名: gif jpg dwf pdf txt zip jpeg lsp dcl doc c cpp swf rar 7z png
显示可打印版本 | 将本页发送给朋友 | 订阅该主题 | 添加到收藏夹

论坛跳转:
给这个主题评分:

论坛状态:
你不可以发布新主题
你不可以回复主题
你不可以上传附件
你不可以编辑自己的帖子
HTML代码 允许
vB代码 允许
表情符号 禁止
[IMG]代码 允许
 

< 管理员信箱 --辽ICP备05017898号 >
MSN:ad@xdcad.net 点击这里给我发消息 

本论坛属于个人性质的论坛,仅提供会员交流!
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律有抵触的言论!否则后果自负