Message 1 of 16
NURBS Equations evaluation, De Boor's algorithm with Autolisp
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
How to evaluate the NURBS Equations, De Boor's algorithm by Autolisp?
I checked this forum to see if the topic has been addressed before, but I did not find anything relevant.
However, here is the code.
; ***
; * Nurbs@u Evaluates the coordinates of a point on a Nurbs curve (Spline)
; * Simulates the function 'vlax-curve-getPointAtParam
; * #Author - _Bilal
; * p [int] the degree of the curve.
; * @u [Real] the parameter value of the knot vector at a specified point
; * ulst [List] the knot vectors as sequence of parameter values
; * plst [List] the list of control points of the Nurbs curve
;======================================================
(defun Nurbs@u ( p @u ulst plst / addlist nips i clst )
;======================================================
;This function Adds the atoms(sublist) in the list (lst)
;the atoms are a sublist of reals numbers like a point.
(defun addlist ( lst / v )
(setq v (car lst))
(while (setq lst (cdr lst)) (setq v (mapcar '+ v (car lst))))
);end
;Loop over plst
(setq i 0 clst nil)
(repeat (length plst)
(if (setq nips (Nips@u i p @u ulst)) (setq clst (cons nips clst)))
(setq i (1+ i))
)
(addlist (mapcar '(lambda (c p) (mapcar '(lambda (x) (* c x)) p)) (reverse clst) plst))
;---------------
);Endof//Nurbs@u
;---------------
; ***
; * Nips@u The B-spline basis functions used in the construction of NURBS curves
; * i [int] Corresponds to the ith control point
; * p [int] Corresponds with the degree of the basis function.
; * @u [Real] The parameter value of the knot vector at a specified point
; * ulst [List] The knot vectors as sequence of parameter values
;==============================================================================
(defun Nips@u ( i p @u ulst / f@u g@u Bin@u i@u binlst n b1 b2 bin bin+ niplst )
;==============================================================================
(defun f@u ( i p @u ulst / dn )
(if (= (setq dn (- (nth (+ i p) ulst) (nth i ulst))) 0.0) 0.0 (/ (- @u (nth i ulst)) dn))
);end
(defun g@u ( i p @u ulst / dn )
(if (= 0.0 (setq dn (- (nth (+ i p 1) ulst) (nth (+ i 1) ulst)))) 0.0 (/ (- (nth (+ i p 1) ulst) @u) dn))
);end
(defun i@u ( p @u ulst / i imx )
;Initial values
(setq i 0 imx (- (length ulst) p 2))
;Is @u within the knots domain definition?
(if (<= (car ulst) @u (nth (1+ imx) ulst))
(if (= @u (nth (1+ imx) ulst)) imx (while (<= (nth (1+ i) ulst) @u) (setq i (1+ i))))
)
);end
(defun Bin@u ( i p @u ulst / i* iu binlst )
(if (setq iu (i@u p @u ulst))
(progn
(setq i* i binlst nil)
(While (<= i* (+ i p))
(setq binlst
(if (= i* iu)
(cons (list i* 0 1.0) binlst)
(cons (list i* 0 0.0) binlst)
)
)
(setq i* (1+ i*))
)
;Retval
(reverse binlst)
)
)
);end
;Loop
(if (setq binlst (Bin@u i p @u ulst))
(repeat p
(setq n 0 niplst nil)
(setq binlst
(reverse
(repeat (1- (length binlst))
(setq b1 (nth n binlst) b2 (nth (setq n (1+ n)) binlst))
(setq i (car b1) p (1+ (cadr b1)) bin (caddr b1) bin+ (caddr b2))
(setq bin (list i p (+ (* (f@u i p @u ulst) bin) (* (g@u i p @u ulst) bin+))))
(setq niplst (cons bin niplst))
)
)
)
)
)
;Retval
(caddar binlst)
;-------------
);Endof//Nips@u
;-------------
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;+++++++++++++++++ DEMONSTRATION ++++++++++++++++++++++
; * grSpline GRDRAW an spline
; * st [int] Spline status Clamped, Closed...
; * p [int] Spline degree 1-2-3--5-6 .... 10
; * ulst [list] List of Knots vectors u0 u1 .... um
; * plst [list] List of control points in WCS
; * ns [Real] Number of segments for each knot vectors
; * (precision for curve presentation)
; *
; * +++++++++++ FOR EXAMPLE ++++++++++++++++
; * +++++ Let say we have the following data
;|
(setq p 3 st 0 ns 10) Clamped opened curve of degree 3
(setq plst
'( (74.8 96.5 0.0) (105.6 51.6 0.0) (163.7 130.5 0.0) (209.8 130.6 0.0)
(252.3 85.2 0.0) (310.1 223.9 0.0) (111.3 237.4 0.0)
)
)
m=n+p+1=7+3+1=11 m:length of ulst n:number of control points p:degree
(setq ulst '(0.0 0.0 0.0 0.0 1.0 2.0 3.0 4.0 4.0 4.0 4.0))
Now, Grdraw the Spline curve according to the above data
(grSpline st p ulst plst ns)
|;
;==========================================================
(defun grSpline ( st p ulst plst ns / imx @umx n du @u pt )
;==========================================================
;Initial values
(setq imx (- (length ulst) p 2))
(setq @umx (nth (1+ imx) ulst) n (length plst) du (/ (apply 'min (vl-remove 0.0 ulst)) ns))
;Nurbs status
(cond
;Uniform Non-Rational Nurbs (Clamped)
((= st 0) (setq @u (nth 0 ulst)))
;Uniform Non-Rational Nurbs (AutoCAD Closed)
((= st 1) (setq @u (nth 0 ulst)))
;Uniform Non-Rational Nurbs (Opened)
((= 2 st)) ;Not applicable at moment
;Uniform Non-Rational Nurbs (Closed)
((= 3 st) (setq @u (nth (1- p) ulst)))
)
;Loop over Knots vectors
(setq pt (Nurbs@u p @u ulst plst))
(while (< (setq @u (+ @u du)) (+ @umx du))
(if (> @u @umx) (setq @u @umx))
(cond
((vl-position st '(0 1)) (grdraw pt (setq pt (Nurbs@u p @u ulst plst)) 1))
((= 2 st))
((= 3 st)
(if (< (nth (1- p) ulst) @u (nth (+ n (* -2 p) 1) ulst))
(grdraw pt (setq pt (Nurbs@u p @u ulst plst)) 1)
)
)
)
)
;----------------
);Endof//grSpline
;----------------
The above code is based on the form shown in the figure