;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;	French Curve Command - FCURVE - Copyright © 2007 by Jim Dee at www.caddee.com
;;;;
;;;;	This code allows the user to continue any arc tagentially from either end.
;;;;	Basically it's like a french curve for AutoCAD. AutoCAD allows you to
;;;;	continue the Last ARC drawn, but there is no easy way to continue any ARC
;;;;	tangentially from either end. When you select an arc the FCURVE command
;;;;	sets the current layer to the selected arc's layer and continues
;;;;	tangentially from whichever end the selected point was closest to.
;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;save default AutoCAD error function to global variable
(if (not #error)(setq #error *error*))

;function to set current error function
(defun erse (err)
	(setq *error* err)
);defun

;function to reset current error function to saved AutoCAD error fuction
(defun errese ()
	(setq  *error* #error)
);defun

;user defined error function
(defun err_default (str)
	(princ "\nResetting environment!  ")
	(command)
	(command)
	(command)
	(command "._undo" "_end")
	(command "._undo" "1")
	(errese)
	(redraw)
(princ)
);defun

(defun c:FCURVE ( / lastarcent selpoint entinfo entlay arccenterp arcdiameter arcang1 arcang2 arcangmid pt1 pt2 ptmid clay)
	;;;;French Curve Command by Jim Dee at www.caddee.com
	(princ "French Curve command by Jim Dee at www.caddee.com ")
	(erse err_default)
	(command "._undo" "_group")
	(command "._ucs" "_w")												;Set ucs to world
	(while (not (setq lastarcent (entsel "\nSelect arc to continue tangentially: "))))
	(setq selpoint (cadr lastarcent))										;Store selection point
	(setq entinfo (entget (car lastarcent)))									;Get entity info
	(if (= (cdr (assoc 0 entinfo)) "ARC")										;Verify that ARC was selected
		(progn
			(setq entlay (cdr (assoc 8 entinfo)))								;Store selected entity's layer
			(setq arccenterp (cdr (assoc 10 entinfo)))							;Store selected entity's center point
			(setq arcdiameter (cdr (assoc 40 entinfo)))							;Store selected entity's diameter
			(setq arcang1 (cdr (assoc 50 entinfo)))								;store selected entity's start angle
			(setq arcang2 (cdr (assoc 51 entinfo)))								;Store selected entity's end angle
			(if (< arcang1 arcang2)										;Does the arc straddle 0/360 then set the mid angle accordingly
				(setq arcangmid (/ (+ arcang1 arcang2) 2))						;Split the start and end angle or
				(setq arcangmid (/ (+ arcang1 arcang2 (* pi 2)) 2))					;Split the angles that straddle 0/360
			);if
			(setq pt1 (polar arccenterp arcang1 arcdiameter))						;Set first point of arc
			(setq pt2 (polar arccenterp arcang2 arcdiameter))						;Set second point of arc
			(setq ptmid (polar arccenterp arcangmid arcdiameter))						;Set mid point of arc
			(setq clay (getvar "clayer"))									;Store current layer
			(command "._-layer" "_s" entlay "")								;Set current layer to selected entity's layer
			(cond
				((< (distance selpoint pt1)(distance selpoint pt2))(command "._arc" pt2 ptmid pt1))	;If selected point is closer to start point draw a temp arc in reversed direction
				((> (distance selpoint pt1)(distance selpoint pt2))(command "._arc" pt1 ptmid pt2))	;If selected point is closer to the end point draw a temp arc in equal direction
				(command "._arc" pt1 ptmid pt2)								;If selected point is at the mid point draw a temp arc in equal direction
			);cond
			(entdel (entlast))										;Delete temp arc
			(command "._arc" "" pause)									;Continue arc tanget to temp arc
			(command "._-layer" "_s" clay "")								;Set current layer to stored layer
		);progn
	);if
	(command "._ucs" "_p")												;Set ucs to previous
	(command "._undo" "_end")
	(errese)
(princ)
);defun

(defun c:FC ( / ) (c:fcurve))

(princ "French Curve command by Jim Dee at www.caddee.com - type FCURVE or FC to execute.")