|
|
1.1 root 1: /*******************************************************************
2: * *
3: * File: CIFPLOT/clip.c *
4: * Written by Dan Fitzpatrick *
5: * copyright 1980 -- Regents of the University of California *
6: * *
7: ********************************************************************/
8:
9: #include <stdio.h>
10: #include "defs.h"
11: #include "globals.h"
12: #include "parser_defs.h"
13: #include "structs.h"
14: #include "out_structs.h"
15: #include "alloc.h"
16:
17: #define YINTERCEPT(y) (x2 + ((x1 - x2)*((y) - y2))/(y1 - y2))
18:
19: Clip(e)
20: iedge *e;
21: /* Clip edge and send to queue */
22: {
23: register int x1,y1,x2,y2; /* edges go from (x1,y1) to (x2,y2) */
24: int x; /* x is a temporary */
25:
26: x1 = e->x1; y1 = e->y1;
27: x2 = e->x2; y2 = e->y2;
28: /* If totally out of range return */
29: if((x1 >= Top) || (x2 <= Bottom)) {
30: return;
31: }
32: /* Clip against xmin */
33: if(x1 < Bottom) {
34: y1 = y2 + ((y1 - y2)*(Bottom - x2))/(x1 - x2);
35: x1 = Bottom;
36: }
37:
38: /* Clip against xmax */
39: if(x2 > Top) {
40: y2 = y1 + ((y2 - y1)*(Top - x1))/(x2 - x1);
41: x2 = Top;
42: }
43:
44: /* Determine slope of line and branch */
45: if(y1 > y2) {
46: /* Check that an end point is in a valid area */
47: if(y1 < 0) y1 = y2 = 0;
48: if(y2 > NoPixcels) y1 = y2 = NoPixcels;
49:
50: /* Clip against ymax */
51: if(y1 > NoPixcels) {
52: x = YINTERCEPT(NoPixcels);
53: if(x1 != x2) {
54: if(x1 <= e->x1)
55: SendEdge(x1,NoPixcels,x,NoPixcels,e->dir,e->poly);
56: else
57: DupEdge(x1,NoPixcels,x,NoPixcels,e->dir,e->poly);
58: }
59: x1 = x; y1 = NoPixcels;
60: }
61: /* Clip against ymin */
62: if(y2 < 0) {
63: x = YINTERCEPT(0);
64: if(x1 != x2) {
65: if(x <= e->x1)
66: SendEdge(x,0,x2,0,e->dir,e->poly);
67: else
68: DupEdge(x,0,x2,0,e->dir,e->poly);
69: }
70: x2 = x; y2 = 0;
71: }
72: }
73: if(y1 < y2) {
74: /* Check that an end point is in a valid area */
75: if(y2 < 0) y1 = y2 = 0;
76: if(y1 > NoPixcels) y1 = y2 = NoPixcels;
77:
78: /* Clip against ymin */
79: if(y1 < 0) {
80: x = YINTERCEPT(0);
81: if(x1 != x2) {
82: if(x1 <= e->x1)
83: SendEdge(x1,0,x,0,e->dir,e->poly);
84: else
85: DupEdge(x1,0,x,0,e->dir,e->poly);
86: }
87: x1 = x; y1 = 0;
88: }
89: /* Clip against ymax */
90: if(y2 > NoPixcels) {
91: x = YINTERCEPT(NoPixcels);
92: if(x1 != x2) {
93: if(x <= e->x1)
94: SendEdge(x,NoPixcels,x2,NoPixcels,e->dir,e->poly);
95: else
96: DupEdge(x,NoPixcels,x2,NoPixcels,e->dir,e->poly);
97: }
98: x2 = x; y2 = NoPixcels;
99: }
100: }
101: if(y1 == y2) {
102: /* y1 == y2 is treated seperately since it would cause
103: * divide by zero in YINTERCEPT */
104: if(y1 < 0) y1 = y2 = 0;
105: if(y2 > NoPixcels) y1 = y2 = NoPixcels;
106: }
107:
108: /* Send clipped edges to queue */
109: if(x1 <= e->x1)
110: SendEdge(x1,y1,x2,y2,e->dir,e->poly);
111: else
112: DupEdge(x1,y1,x2,y2,e->dir,e->poly);
113: return;
114: }
115:
116: int LastA = -999999;
117: SendEdge(a,b,c,d,dir,poly)
118: int a,b,c,d,dir;
119: PolyDesc *poly;
120: /* put the edge (a,b) -- (c,d) into queue */
121: {
122: edge *e;
123:
124: /* Clip */
125: if(a == c && poly->level != 0) return;
126: if(a<Bottom) a = Bottom;
127: if(c>Top) c = Top;
128: if(b < 0 || d < 0 || b > NoPixcels || d > NoPixcels) {
129: Error("Out of range in SendEdge",INTERNAL);
130: }
131:
132: if(a < LastA) Error("Out of order edges",INTERNAL);
133: e = GetEdge();
134: e->ix = a;
135: e->ex = c;
136: e->iy = b;
137: if(c != a)
138: e->dy = ((real) (d-b))/((real) (c-a));
139: else
140: e->dy = 0.0;
141: e->dir = dir;
142: if(!((dir == 1) || (dir == -1)))
143: Error("bad direction vector in SendEdge",INTERNAL);
144: e->poly = poly;
145: (poly->refs)++;
146: if(!extractor)
147: PutQueue(e,&(EdgeQueue[poly->level]));
148: else /* if running extractor everything goes on same layer */
149: PutQueue(e,&(EdgeQueue[0]));
150: }
151:
152: DupEdge(a,b,c,d,dir,poly)
153: int a,b,c,d;
154: PolyDesc *poly;
155: {
156: iedge *e;
157:
158: e = GetIEdge();
159: e->type = EDGE;
160: e->poly = poly;
161: (e->poly->refs)++;
162: e->dir = dir;
163: e->min = a;
164: e->x1 = a; e->y1 = b;
165: e->x2 = c; e->y2 = d;
166: Selector(e);
167: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.