2 (:use
:cl
:vol
:vector
)
3 (:export
#:scan-convert-line3
))
5 (in-package :bresenham
)
8 (defun scan-convert-line3x (x1 y1 z1 x2 y2 z2 vol
)
9 (declare (fixnum x1 y1 z1 x2 y2 z2
)
10 ((simple-array (unsigned-byte 8) 3) vol
)
11 (values (simple-array (unsigned-byte 8) 3) &optional
))
12 ;; x2 - x1 has to be the biggest difference between endpoint
16 ;; initialization for y
21 (dy (- (* 2 dely
) delx
)) ;; decision variable along y
22 (yinc1 (* 2 dely
)) ;; increment along y for dy<0
23 (yinc2 (* 2 (- dely delx
))) ;; inc along y for dy>=0
24 ;; same initialization for z
29 (dz (- (* 2 delz
) delx
))
31 (zinc2 (* 2 (- delz delx
))))
33 (error "x2 is <= x1."))
34 (setf (aref vol z y x
) 255)
35 (loop while
(< x x2
) do
37 (if (< dy
0) ;; then no change in y
38 (incf dy yinc1
) ;; update dy
40 (incf dy yinc2
) ;; update dy, and
41 (incf y ysign
)));; increment/decrement y
48 (setf (aref vol z y x
) 255)))
50 ;; start from scan-convert-line3x and replace x->$, y->x, $->y
51 (defun scan-convert-line3y (x1 y1 z1 x2 y2 z2 vol
)
52 (declare (fixnum x1 y1 z1 x2 y2 z2
)
53 ((simple-array (unsigned-byte 8) 3) vol
)
54 (values (simple-array (unsigned-byte 8) 3) &optional
))
61 (dx (- (* 2 delx
) dely
))
63 (xinc2 (* 2 (- delx dely
)))
68 (dz (- (* 2 delz
) dely
))
70 (zinc2 (* 2 (- delz dely
))))
72 (error "y2 is <= y1."))
73 (setf (aref vol z y x
) 255)
74 (loop while
(< y y2
) do
86 (setf (aref vol z y x
) 255)))
88 ;; replace x->$, z->x, $->z
89 (defun scan-convert-line3z (x1 y1 z1 x2 y2 z2 vol
)
90 (declare (fixnum x1 y1 z1 x2 y2 z2
)
91 ((simple-array (unsigned-byte 8) 3) vol
)
92 (values (simple-array (unsigned-byte 8) 3) &optional
))
99 (dy (- (* 2 dely
) delz
))
101 (yinc2 (* 2 (- dely delz
)))
106 (dx (- (* 2 delx
) delz
))
108 (xinc2 (* 2 (- delx delz
))))
110 (error "z2 is <= z1."))
111 (setf (aref vol z y x
) 255)
112 (loop while
(< z z2
) do
125 (setf (aref vol z y x
) 255)))
128 (defun scan-convert-line3 (start end vol
)
129 (declare (vec-i start end
)
130 ((simple-array (unsigned-byte 8) 3) vol
)
131 (values (simple-array (unsigned-byte 8) 3) &optional
))
132 (let* ((diff (v--i end start
))
133 (ls (list (list (vec-i-x diff
) 2)
134 (list (vec-i-y diff
) 1)
135 (list (vec-i-z diff
) 0)))
136 (diffa (mapcar #'(lambda (e) (list (abs (first e
))
138 ;; find the direction with the biggest difference
139 (sorted-diff-a (sort diffa
#'> :key
#'car
))
140 (main-direction (second (first sorted-diff-a
))) ;; 2 corresponds to x, 1->y, 0->z
141 ;; find the order in which to deliver the points
142 (main-diff (aref diff main-direction
))
143 ;; we have to swap the points when main-diff is negative
144 (swap-points?
(< main-diff
0))
145 ;; create the function name to dispatch to
146 (function (ecase main-direction
147 (2 #'scan-convert-line3x
)
148 (1 #'scan-convert-line3y
)
149 (0 #'scan-convert-line3z
))))
150 (when (eq 0 main-diff
)
151 (error "start and end point are the same."))
173 (let ((vol (make-array (list 128 128 128) :element-type
'(unsigned-byte 8))))
174 (save-stack-ub8 "/home/martin/tmp/line"
175 (scan-convert-line3 (make-vec-i :x
0 :y
0 :z
0)
176 (make-vec-i :x
120 :y
127 :z
127)