Jump to content

My first Lisp : Draw Clothoid Curves (what do you think ?)


jbreard

Recommended Posts

Dear all,

 

Please find below the code for a lisp that will enable you to plot clothoid curves given 2 parameter (lenght of clothoid and clothoid parameter A):

 

; Lisp to draw clothoid curves
; By Jacques BREARD 19th of June 2012
; First Issue


(defun FCS (x / e xa px c s u r k m su f0 f1 f q g t0) ; Algortihm to compute Fresnel integrals C(x) and S(x). Translation of a VL routine found in Xnumber excel add-in by FOREX team. Original algorithm : Shanjie Zhang and Jianming Jin, 2001
 
 (setq e (expt 10.0 -15))
 (setq xa (abs x))
 (setq px (* pi xa))
 (setq u (* 0.5 px xa))

 (cond ((= xa 0)
	(setq c 0)
	(setq s 0)
)
((< xa 2.5)
	(setq r xa)
	(setq c r)
	(setq k 1)
	(while (> (abs r) (* (abs c) e))
	 	(setq r (/ (* -0.5 r (* u u) (- (* 4 k) 3)) (* k (- (* 2 k) 1) (+ (* 4 k) 1))))
		(setq c (+ c r))
		(setq k (1+ k))
	)

	(setq s (/ (* xa u) 3))
	(setq r s)
	(setq k 1)
	(while (> (abs r) (* (abs s) e))
	 	(setq r (/ (* -0.5 r (* u u) (- (* 4 k) 1)) (* k (+ (* 2 k) 1) (+ (* 4 k) 3))))
		(setq s (+ s r))
		(setq k (1+ k))
	 )
 )

((< xa 4.5)
	(setq m (fix (+ 42 (* 1.75 u))))
	(setq su 0)
 	(setq c 0)
 	(setq s 0)
	(setq f1 0)
	(setq f0 (expt 10.0 -100))
	(setq k m)
	(while (>= k 0)
	 	(setq f (- (/ (* (+ (* 2 k) 3) f0) u) f1))

	 		(if (= k (* (/ (fix k) 2) 2))
			  (setq c (+ c f))
			  (setq s (+ s f))
			)
		(setq su (+ su (* f (* f (+ (* 2 k) 1)))))
		(setq f1 f0)
		(setq f0 f)
	 	(setq k (1- k))	
	)
	(setq q (sqrt su))
	(setq c (/ (* c xa) q))
	(setq s (/ (* s xa) q))
)

(t
  	(setq r 1)
	(setq f 1)
	(setq k 1)

	(while (<= k 20)
	  	(setq r (/ (* -0.25 r (- (* 4 k) 1) (- (* 4 k) 3)) (* u u)))
	  	(setq f (+ f r))
	  	(setq k (1+ k))
	 )
	(setq r (/ 1 (* px xa)))
	(setq g r)
 	(setq k 1)
	(while (<= k 12)
	  	(setq r (/ (* -0.25 r (- (* 4 k) 1) (+ (* 4 k) 1)) (* u u)))
	  	(setq g (+ g r))
	  	(setq k (1+ k))
	 )
	(setq t0 (- u (* (fix (/ u (* 2 pi))) 2 pi)))
	(setq c (+ 0.5 (/ (- (* f (sin t0)) (* g (cos t0))) px)))
	(setq s (- 0.5 (/ (+ (* f (cos t0)) (* g (sin t0))) px)))
)
    )
 (if (< x 0)
   (progn
   (setq c (- 0 c))
   (setq s (- 0 s)))
  )
 (list c s)
)


(defun clotho-x (l a / l_a clo_x) ; calculate x coordinate of clothoid (start point is origine, lenght of clothoid l and parameter of clothoid A)
 
 (setq l_a (* l (/ 1 (* a (sqrt pi)))))
 (if (>= l 0)
   (setq clo_x (* (sqrt pi) a (car (fcs l_a))))
   (nil)
  )
)

(defun clotho-y (l a / l_a clo_y) ; ; calculate y coordinate of clothoid (start point is origine, lenght of clothoid l and parameter of clothoid A)
 
 (setq l_a (* l (/ 1 (* a (sqrt pi)))))
 (if (>= l 0)
   (if (minusp a)
   	(setq clo_y (- 0 (* (sqrt pi) a (cadr (fcs l_a)))))
       (setq clo_y (* (sqrt pi) a (cadr (fcs l_a))))
     )
   (nil)
  )
)

(defun c:clodraw (/ l a step step1 aa n k sn) ; Draw Clothoid (lenght L, parameter A, start point = origin). Parameter A is defined as A²=L*R where L is the total lenght of the clothoid and R the radius of the curve at end point

 (if (null (tblsearch "LAYER" "CLOTHOID"))   ; Create layer "CLOTHOID" if non existant and set it current
   (entmake
     (list
'(0 . "LAYER")
'(100 . "AcDbSymbolTableRecord")	
'(100 . "AcDbLayerTableRecord")
'(70 . 0)
 (cons 2 "CLOTHOID")
 (cons 62 2)
)
     )
   )
 (setvar "CLayer" "CLOTHOID")

 (initget 7)                                 ; Clothoid parameters imput. Construction Step correspond to the angle between vectors (point n-1 -> point n) and (point n -> point n+1)
 (setq step (getreal "\n Construction Step (gradians) :"))
 (initget 7)
 (setq l (getreal "\n Lenght of Clothoid (meter) :"))
 (initget 3)
 (setq a (getreal "\n Clothoid Parameter A :"))

 
 
 (setq aa (abs a))                          ; Vertex of clothoid Polyline calculation
 (setq n (min (fix (/ (/ (* l l) (* 2 aa aa)) (* pi (/ step 200)))) 1000)) ; Limitation of vertex number = 1000
 (setq step1 (* 200 (/ (/ (/ (* l l) (* 2 aa aa)) n) pi)))
 (setq k 0)
 	(setq mylist nil)
 	
 	     (while (<= k n)
	(setq sn (sqrt (* 2 aa aa k (* pi (/ step1 200)))))
        (setq mylist
     		(append mylist (list (list (clotho-x sn a) (clotho-y sn a)))))
 		(setq k (1+ k))
    )
 (entmakex                         ; Draw Clothoid
  (append
    (list
    '(0 . "LWPOLYLINE")
     (cons 100 "AcDbEntity")
            (cons 100 "AcDbPolyline")
     (cons 90  (length mylist))
            (cons 70 0))
     (mapcar (function (lambda ( p ) (cons 10 p))) mylist)
  )
 )
 
  (princ)
)

 

Please note the following :

* The lisp doesn't have error handlers as I cannot yet get my head around those. So no "esc" hitting, sorry

* The lisp left all system variable untouched as far as I can say

* The lisp creates a new layer "CLOTHOID" and makes it current. It stays current. Better try it in a new drawing

* I would recommend 0.05 (grad) for the construction step

* I would also recommend for a start the couple of parameters (l A) :

(100 100) (100 -100) (500 100) and (500 -100)

* Typical range for l and A in civil engineer would be something like l (20m -200m) and A +-(50 500) i believe.

 

Can you please tell me what you think of this first try and what you would change / do more effficiently ?

 

Thanks a lot

 

Regards,

 

Jacques BREARD

Link to comment
Share on other sites

The routine looks nice, is quite impressive as the first one. I cannot comment on the result since I'm not familiar at all with the said curved.

At first glance, found a small syntax issue - NIL cannot be used as a function, you should either remove the brackets or the line entirely since is superfluous.

(if (>= l 0)
(setq clo_x (* (sqrt pi) a (car (fcs l_a))))
[s][color=red](nil)[/color][/s]
)

Link to comment
Share on other sites

Another general comment – I suggest you to use descriptive names for your variables instead of just naming them with a single character; later if will want to adjust the code it will be very useful to have self-explanatory variable names. Please check this document on variables naming convention.

 

Also, you may check Lee Mac’s tutorial on error handling.

Link to comment
Share on other sites

Dear Mircea,

 

Thanks for your insight. Will follow it and learn.

 

As for the curves, you need't really to know something about them. They are also known as spirals and if you use these parameters in imput for exemple (0.05 l=700 A=100) you should see quite a funny curve.

 

No use at all but it's nice in ,my opinion.

 

Regqrds,

 

Jacuqes

Link to comment
Share on other sites

  • 2 months later...
  • 3 months later...

Thanks you very much for the codes. This is the code I am searching for.

I m a drafter , still new in drafting about bridge. I think this code should be useful to me.

I will study your codes and formulas for spiral. If you have any revised or improved version of the codes, please post it.

Thanks you very much !!

Link to comment
Share on other sites

  • 6 years later...

Dear Jacques,

 

I am looking for a clothoid Lisp to do some spirals and stumbled upon yours. Looks great. Thank you very much. I want to research further to see how I can get to use this and understand more. BTW, do you have the text reference for the equations you used in the Lisp.?

 

For example, I need to know more how to set the parameter A and the length, grad setting etc?

 

Best Regards

Rakesh Rao

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...