1 /* $Id: line.c,v 1.4 2002-07-17 21:55:19 bradleyb Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
15 * Graphical routines for drawing lines.
42 Symmetric Double Step Line Algorithm
44 from "Graphics Gems", Academic Press, 1990
47 /* non-zero flag indicates the pixels needing EXCHG back. */
48 void plot(int x,int y,int flag)
55 int gr_hline(int x1, int x2, int y)
58 if (x1 > x2) EXCHG(x1,x2);
59 for (i=x1; i<=x2; i++ )
64 int gr_vline(int y1, int y2, int x)
66 if (y1 > y2) EXCHG(y1,y2);
67 for (i=y1; i<=y2; i++ )
72 void gr_universal_uline(int a1, int b1, int a2, int b2)
74 int dx, dy, incr1, incr2, D, x, y, xend, c, pixels_left;
76 int sign_x = 1, sign_y = 1, step, reverse, i;
100 /* decide increment sign by the slope sign */
101 if (sign_x == sign_y)
106 if (dy > dx) { /* chooses axis of greatest movement (make * dx) */
113 /* note error check for dx==0 should be included here */
114 if (a1 > a2) { /* start from the smaller coordinate */
127 /* Note dx=n implies 0 - n or (dx+1) pixels to be set */
128 /* Go round loop dx/4 times then plot last 0,1,2 or 3 pixels */
129 /* In fact (dx-1)/4 as 2 pixels are already plottted */
131 pixels_left = (dx - 1) % 4; /* number of pixels left over at the
134 plot(x1, y1, reverse); /* plot first two points */
135 incr2 = 4 * dy - 2 * dx;
136 if (incr2 < 0) { /* slope less than 1/2 */
141 for (i = 0; i < xend; i++) { /* plotting loop */
145 /* pattern 1 forwards */
147 plot(++x, y, reverse);
148 /* pattern 1 backwards */
149 plot(x1, y1, reverse);
150 plot(--x1, y1, reverse);
154 /* pattern 2 forwards */
156 plot(++x, y += step, reverse);
157 /* pattern 2 backwards */
158 plot(x1, y1, reverse);
159 plot(--x1, y1 -= step, reverse);
161 /* pattern 3 forwards */
162 plot(x, y += step, reverse);
163 plot(++x, y, reverse);
164 /* pattern 3 backwards */
165 plot(x1, y1 -= step, reverse);
166 plot(--x1, y1, reverse);
172 /* plot last pattern */
175 plot(++x, y, reverse); /* pattern 1 */
177 plot(++x, y, reverse);
179 plot(--x1, y1, reverse);
182 plot(++x, y, reverse); /* pattern 2 */
184 plot(++x, y += step, reverse);
186 plot(--x1, y1, reverse);
189 plot(++x, y += step, reverse);
191 plot(++x, y, reverse);
193 plot(--x1, y1 -= step, reverse);
196 } /* end if pixels_left */
198 /* end slope < 1/2 */
199 else { /* slope greater than 1/2 */
203 for (i = 0; i < xend; i++) {
207 /* pattern 4 forwards */
208 plot(x, y += step, reverse);
209 plot(++x, y += step, reverse);
210 /* pattern 4 backwards */
211 plot(x1, y1 -= step, reverse);
212 plot(--x1, y1 -= step, reverse);
216 /* pattern 2 forwards */
218 plot(++x, y += step, reverse);
220 /* pattern 2 backwards */
221 plot(x1, y1, reverse);
222 plot(--x1, y1 -= step, reverse);
224 /* pattern 3 forwards */
225 plot(x, y += step, reverse);
226 plot(++x, y, reverse);
227 /* pattern 3 backwards */
228 plot(x1, y1 -= step, reverse);
229 plot(--x1, y1, reverse);
234 /* plot last pattern */
237 plot(++x, y += step, reverse); /* pattern 4 */
239 plot(++x, y += step, reverse);
241 plot(--x1, y1 -= step, reverse);
244 plot(++x, y, reverse); /* pattern 2 */
246 plot(++x, y += step, reverse);
248 plot(--x1, y1, reverse);
251 plot(++x, y += step, reverse);
253 plot(++x, y, reverse);
254 if (pixels_left > 2) {
255 if (D > c) /* step 3 */
256 plot(--x1, y1 -= step, reverse);
258 plot(--x1, y1, reverse);
267 //unclipped version just calls clipping version for now
268 int gr_uline(fix _a1, fix _b1, fix _a2, fix _b2)
271 a1 = f2i(_a1); b1 = f2i(_b1); a2 = f2i(_a2); b2 = f2i(_b2);
276 ogl_ulinec(a1,b1,a2,b2,COLOR);
281 gr_universal_uline( a1,b1,a2,b2);
283 gr_linear_line( a1, b1, a2, b2 );
288 modex_line_x1 = a1+XOFFSET;
289 modex_line_y1 = b1+YOFFSET;
290 modex_line_x2 = a2+XOFFSET;
291 modex_line_y2 = b2+YOFFSET;
292 modex_line_Color = grd_curcanv->cv_color;
296 gr_universal_uline( a1, b1, a2, b2 );
303 // Returns 0 if drawn with no clipping, 1 if drawn but clipped, and
304 // 2 if not drawn at all.
306 int gr_line(fix a1, fix b1, fix a2, fix b2)
316 CLIPLINE(a1,b1,a2,b2,x1,y1,x2,y2,return 2,clipped=1, FSCALE );
318 gr_uline( a1, b1, a2, b2 );