```   1:
2: /******************************************************************************
3:  *  bitdraw - 	implements the bitmap drawing primitives necessary to turn
4:  *		ditroff draw commands into a pixel vector for interpress
5:  *
6:  *
7:  *	John Mellor-Crummey (Xerox Corp)
8:  *
9:  * 	Copyright (c) 1985 Xerox Corp.
10:  *
11:  ******************************************************************************/
12:
13:
14: #include <math.h>
15: #include <stdio.h>
16: #include <ctype.h>
17:
18: #include "defs.h"
19: #include "externs.h"
20:
21:
22: /*------------------------------------------------------------------------------
23:  *	bitmapDrawCircle	incrementally compute the points for one octant
24:  *				of a circle and complete the figure by
25:  *				reflecting the points into each of the octants.
26:  *
27:  *		based on an algorithm by J. Michener from
28:  *		Fundamentals of Interactive Computer Graphics,
29:  *		Foley & Van Dam, 1982, p. 445
30:  *----------------------------------------------------------------------------*/
31: bitmapDrawCircle(d)
32: int d;
33: {
34:     int x,y,xc,yc,delta;
35:
36:     xc = hor_pos + d/2;
37:     yc = ver_pos;
38:     delta = 3 - d;
39:     x = 0;
40:     y = d/2;
41:     while ( x < y)
42:     {
43:         octPlot(x,y,xc,yc);
44:         if (delta < 0)
45:             delta = delta + 4 * x + 6;
46:         else
47:         {
48:             delta = delta + 4 * (x - y) + 10;
49:             y--;
50:         }
51:         x++;
52:     }
53:     if (x == y) octPlot(x,y,xc,yc);
54:     hMov(xc + d/2);
55:     vMov(yc);
56: }
57:
58:
59: /*------------------------------------------------------------------------------
60:  *	octPlot		reflect the point  x,y into each of the eight
61:  *			octants centered about xc,yc and set the pixels
62:  *			in a bitmap
63:  *----------------------------------------------------------------------------*/
64: octPlot(x,y,xc,yc)
65: int x,y,xc,yc;
66: {
67:     vMov(yc + y);
68:     hMov(xc + x); setpixel();
69:     hMov(xc - x); setpixel();
70:     vMov(yc - y); setpixel();
71:     hMov(xc + x); setpixel();
72:     vMov(yc + x);
73:     hMov(xc + y); setpixel();
74:     hMov(xc - y); setpixel();
75:     vMov(yc - x); setpixel();
76:     hMov(xc + y); setpixel();
77: }
78:
79: /*------------------------------------------------------------------------------
80:  *	bitmapDrawEllipse	incrementally compute the points for one
81:  *				quadrant of an ellipse and complete the figure
82:  *				by reflecting the points into each of the
84:  *----------------------------------------------------------------------------*/
85: bitmapDrawEllipse(xdiam,ydiam)
86: int xdiam,ydiam;
87: {
88:     int x,y,xc,yc,a,b;
89:     int fourAsq,fourAsqY;
90:     int sixBsq,twoBsq,fourBsq,fourBsqX;
91:     int d;
92:     int midpoint;
93:
94:     a = xdiam / 2;
95:     b = ydiam / 2;
96:     xc = hor_pos + a;
97:     yc = ver_pos;
98:
99:     x = 0;
100:     y = b;
101:     fourAsq = a * a * 4;
102:     twoBsq = b * b * 2;
103:     fourBsq = twoBsq + twoBsq;
104:     sixBsq = fourBsq + twoBsq;
105:     fourAsqY = fourAsq * y;
106:     fourBsqX = 0;
107:     midpoint = a * a * sqrt((double) 1.0 / (a * a + b * b));
108:     d = twoBsq +  a * a * (2 * b  + 1);
109:
110:     while(x < midpoint)
111:     {
113:         if (d > 0) /* case 2 -> y-- */
114:         {
115:             d += fourAsq - fourAsqY;
116:             fourAsqY -= fourAsq;
117:             y--;
118:         }
119:         d += fourBsqX + sixBsq;
120:         fourBsqX += fourBsq;
121:         x++;
122:     }
123:     d -= twoBsq * x - b * b;
124:     while(y >= 0)
125:     {
127:         if (d > 0) /* case 3 -> x++ */
128:         {
129:             d += fourBsqX + sixBsq;
130:             fourBsqX += fourBsq;
131:             x++;
132:         }
133:         d += fourAsq - fourAsqY;
134:         fourAsqY -= fourAsq;
135:         y--;
136:     }
137:     hMov(xc + a);
138:     vMov(yc);
139: }
140:
141:
142: /*------------------------------------------------------------------------------
143:  *	quadPlot	reflect the point  x,y into each of the four
145:  *			in a bitmap
146:  *----------------------------------------------------------------------------*/
148: int x,y,xc,yc;
149: {
150:     vMov(yc + y);
151:     hMov(xc + x); setpixel();
152:     hMov(xc - x); setpixel();
153:     vMov(yc - y); setpixel();
154:     hMov(xc + x); setpixel();
155: }
156:
157:
158: /*------------------------------------------------------------------------------
159:  *	bitmapDrawCircle	incrementally draw a circular arc in a c
160:  *				counterclockwise direction. the arguments are
161:  *				relative coordinates for the center point
162:  *				from the current point, and the termination
163:  *				point from the center point.
164:  *
165:  *		based on an algorithm by J. Bresenham
166:  *		A Linear Algorithm for Incremental Digital
167:  *		Display of Circular Arcs, Communications of the ACM,
168:  *		Feb. 1977, pp. 103-104.
169:  *----------------------------------------------------------------------------*/
170: bitmapDrawArc(relxc,relyc,relxt,relyt)
171: int relxc,relyc,relxt,relyt;
172: {
173:     int xc,yc;
174:     int Xsprime,Ysprime,Xtprime,Ytprime;
175:     int Xshat,Yshat,Xthat,Ythat,Xs,Ys,Xt,Yt,Xi,Yi;
176:     int delta,deltai,deltaprime;
177:     int M1x,M1y,M2x,M2y,M3x,M3y;
178:     int q,qs,qt,qstar;
179:     int move;
180:     int xsave;
182:     double angle;
183:     int xplot,yplot;
184:
185:     xc = hor_pos + relxc;
186:     yc = ver_pos + relyc;
187:     Xtprime =  hor_pos;
188:     Ytprime = ver_pos;
189:     Xsprime = relxt + xc;
190:     Ysprime = relyt + yc;
191:
192:     /* get the radius from the start point */
193:     radius = hypot((double) relxc,(double) relyc);
194:
195:     /* readjust start point to be sure it is on proper grid point */
196:     angle = atan2((double) (Ysprime - yc),(double) (Xsprime - xc));
197:     xplot = Xsprime = radius * cos(angle) + xc + .5;
198:     yplot = Ysprime = radius * sin(angle) + yc + .5;
199:
200:     /* readjust termination point to be sure it is on proper grid point */
201:     angle = atan2((double) (Ytprime - yc),(double) (Xtprime - xc));
202:     Xtprime = radius * cos(angle) + xc + .5;
203:     Ytprime = radius * sin(angle) + yc + .5;
204:
205:     /* compute start and end points of the arc as relative coordinates */
206:     Xshat = Xsprime - xc;
207:     Yshat = Ysprime - yc;
208:     Xthat = Xtprime - xc;
209:     Ythat = Ytprime - yc;
210:
212: 	 * for both start and end points
213: 	 */
214:
215:     if (Xshat < 0)
216:     {
217:         if (Yshat < 0)
218:         {
219:             Xs =  abs(Yshat);
220:             Ys =  abs(Xshat);
221:             qs = 3;
222:             M1x = 0; M1y = -1;
223:             M2x = 1; M2y = -1;
224:             M3x = 1; M3y = 0;
225:         }
226:         else
227:         {
228:             Xs =  abs(Xshat);
229:             Ys =  abs(Yshat);
230:             qs = 2;
231:             M1x = -1; M1y =  0;
232:             M2x = -1; M2y = -1;
233:             M3x =  0; M3y = -1;
234:         }
235:     }
236:     else
237:     {
238:         if (Yshat < 0)
239:         {
240:             Xs =  abs(Xshat);
241:             Ys =  abs(Yshat);
242:             qs = 0;
243:             M1x = 1; M1y = 0;
244:             M2x = 1; M2y = 1;
245:             M3x = 0; M3y = 1;
246:         }
247:         else
248:         {
249:             Xs =  abs(Yshat);
250:             Ys =  abs(Xshat);
251:             qs = 1;
252:             M1x =  0; M1y =  1;
253:             M2x = -1; M2y = 1;
254:             M3x = -1; M3y = 0;
255:         }
256:     }
257:
258:     if (Xthat < 0)
259:     {
260:         if (Ythat < 0)
261:         {
262:             Xt =  abs(Ythat);
263:             Yt =  abs(Xthat);
264:             qt = 3;
265:         }
266:         else
267:         {
268:             Xt =  abs(Xthat);
269:             Yt =  abs(Ythat);
270:             qt = 2;
271:         }
272:     }
273:     else
274:     {
275:         if (Ythat < 0)
276:         {
277:             Xt =  abs(Xthat);
278:             Yt =  abs(Ythat);
279:             qt = 0;
280:         }
281:         else
282:         {
283:             Xt =  abs(Ythat);
284:             Yt =  abs(Xthat);
285:             qt = 1;
286:         }
287:     }
288:
289:     /* calculate number of quadrants */
290:     qstar = (4 + qt - qs) % 4;
291:     if ((qstar == 0) && (Xt <= Xs) && (Yt >= Ys))
292:         q = 3;
293:     else    q = qstar - 1;
294:
295:     /* initialize for iteration */
296:     deltai = 2 * (Xs - Ys + 1);
297:     Xi = Xs;
298:     Yi = Ys;
299:
300:     while(TRUE)
301:     {
302:         if ((q < 0) && (Xt <= Xi) && (Yt >= Yi))
303:             break;
304:
305:         hMov(xplot);
306:         vMov(yplot);
307:         setpixel();
308:
309:         if (Yi < 1)
310:         {
311:             xsave = Xi;
312:             Xi = - Yi;
313:             Yi = xsave;
314:             deltai = deltai - 4 * xsave;
315:
316:             q = q - 1;
317:             M1x = M3x;
318:             M1y = M3y;
319:
320:             xsave = M2x;
321:             M2x = - M2y;
322:             M2y = xsave;
323:
324:             xsave = M3x;
325:             M3x = - M3y;
326:             M3y = xsave;
327:
328:             continue;
329:         }
330:         if (deltai <= 0)
331:         {
332:             delta = 2 * (deltai + Yi) - 1;
333:             if (delta > 0)
334:                 move = M2;
335:             else    move = M1;
336:         }
337:         else
338:         {
339:             deltaprime = 2 * (deltai - Xi) - 1;
340:             if (deltaprime > 0)
341:                 move = M3;
342:             else    move = M2;
343:         }
344:
345:         switch(move)
346:         {
347:         case M1:
348:             Xi++;
349:             deltai = deltai + 2* Xi + 1;
350:             xplot += M1x;
351:             yplot += M1y;
352:             break;
353:         case M2:
354:             Xi++;
355:             Yi--;
356:             deltai = deltai + 2* (Xi - Yi) + 2;
357:             xplot += M2x;
358:             yplot += M2y;
359:             break;
360:         case M3:
361:             Yi--;
362:             deltai = deltai - 2 * Yi + 1;
363:             xplot += M3x;
364:             yplot += M3y;
365:             break;
366:         }
367:     }
368: }
369:
370:
371: /*------------------------------------------------------------------------------
372:  *	bitmapDrawWigglyLine	interpolate a curve between the sets of
373:  *				relative points. the interpolation is done
374:  *				using a spline like method to produce a curve
375:  *				compatible with other output of ipic
376:  *				(if the wiggly line should have arrowheads,
377:  *				ipic assumes that the wiggly line will pass
378:  *				close to the 2nd to last point in the curve
379:  *				when it computes the tilt of the arrowheads.
380:  *				For a smoother curve such as a
381:  *				B-spline, the arrowheads will not be tilted
382:  *				correctly as the spline is not guaranteed to
383:  *				pass through the 2nd to last point)
384:  *----------------------------------------------------------------------------*/
385: bitmapDrawWigglyLine(s)
386: char *s;
387: {
388:     int x[maxPointsInSpline],y[maxPointsInSpline];
389:     int xi,yi,i,j,numPoints;
390:     float temp1,temp2,temp3,t,dis;
391:     float euclidDist();
392:
393:     /* skip all leading white space */
394:     while(white(*s)) s++;
395:     if(!isdigit(*s)) return;
396:
397:     /* read in the x y pairs of points for the spline */
398:     for(numPoints = 2; ((numPoints< maxPointsInSpline) &&
401:     numPoints++;
402:
403:     /* first point of curve is current point */
404:     x[1] = hor_pos;
405:     y[1] = ver_pos;
406:
407:     /* turn relative points into absolute points */
408:     for (i = 2; i < numPoints; i++)
409:     {
410:         x[i] += x[i-1];
411:         y[i] += y[i-1];
412:     }
413:
414:     /* if the wiggle's ends meet, insure the curve meets */
415:     if ((x[1] == x[numPoints-1]) && (y[1] == y[numPoints-1]))
416:     {
417:         x[0] = x[numPoints-2];
418:         y[0] = y[numPoints-2];
419:         x[numPoints] = x[2];
420:         y[numPoints] = y[2];
421:     }
422:     else
423:     {
424:         x[0] = x[1];
425:         y[0] = y[1];
426:         x[numPoints] = x[numPoints-1];
427:         y[numPoints] = y[numPoints-1];
428:     }
429:     numPoints++;
430:
431:     /* position next pointers to the start of spline */
432:     hMov((x[0] + x[1]) / 2);
433:     vMov((y[0] + y[1]) / 2);
434:
435:     for (i = 0; i < numPoints - 2; i++)
436:     {
437:         dis = (euclidDist(x[i],y[i], x[i+1],y[i+1]) +
438:                euclidDist(x[i+1],y[i+1], x[i+2],y[i+2])) / 2;
439:         for(j=1;j<dis;j++)
440:         {
441:             t = (float) j/dis;
442:             temp1 = 0.5 * t * t;
443:             temp2 = -temp1 - temp1 + t + 0.5;
444:             temp3 = temp1 - t + 0.5;
445:
446:             xi = temp1 * x[i+2] + temp2 * x[i+1] + temp3 * x[i] + 0.5;
447:             yi = temp1 * y[i+2] + temp2 * y[i+1] + temp3 * y[i] + 0.5;
448:             if (xi != hor_pos || yi != ver_pos)
449:             {
450:                 hMov(xi);
451:                 vMov(yi);
452:                 setpixel();
453:             }
454:         }
455:     }
456: }
457:
458:
459: /*-----------------------------------------------------------------------------
460:  *	readNumber	read an integer from the string pointed to by *ptr,
461:  *			returning the integer in val, and updating *ptr for
462:  *			the caller
463:  *---------------------------------------------------------------------------*/
465: char **ptr;
466: int *val;
467: {
468:     int sign = 1;
469:
470:     *val = 0;
471:
472:     if (**ptr == '-')
473:     {
474:         sign = -1;
475:         ++*ptr;
476:     }
477:     while(isdigit(**ptr))
478:     {
479:         *val = *val * 10 + **ptr - '0';
480:         ++*ptr;
481:     }
482:     *val = *val * sign;
483:
484:     /* skip all trailing white space */
485:     while(white(**ptr) || **ptr == '\n') ++*ptr;
486:
487:     /* return next char -- if at end of string this is NULL */
488:     return(**ptr);
489: }
490:
491:
492: /*-----------------------------------------------------------------------------
493:  *	euclidDist	compute euclidean distance between the two cartesian
494:  *			coordinates
495:  *---------------------------------------------------------------------------*/
496: float euclidDist(x, y, x1, y1)
497: int x1,y1,x,y;
498: {
499:     double deltax, deltay;
500:
501:     deltax = x - x1;
502:     deltay = y - y1;
503:     return(sqrt(deltax*deltax + deltay*deltay) + 0.5);
504: }
```

#### Defined functions

bitmapDrawArc defined in line 170; used 1 times
bitmapDrawCircle defined in line 31; used 1 times
bitmapDrawEllipse defined in line 85; used 1 times
bitmapDrawWigglyLine defined in line 385; used 1 times
euclidDist defined in line 496; used 3 times
octPlot defined in line 64; used 2 times
quadPlot defined in line 147; used 2 times
readNumber defined in line 464; used 4 times
 Last modified: 1985-09-04 Generated: 2016-12-26 Generated by src2html V0.67 page hit count: 1809