-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathclip_testD.c
More file actions
173 lines (116 loc) · 3.54 KB
/
clip_testD.c
File metadata and controls
173 lines (116 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include <FPT.h>
int Clip_Polygon_Against_Line(
double a, double b, double c,
double *polyx, double *polyy, int size,
double *resx, double *resy)
// Clip polygon against the line ax + by + c = 0,
// where ax + by + c < 0 is considered IN.
// Incoming poly defined in arrays polyx, polyy with numverts = size.
// Clipped result values are stored in arrays resx, resy,
// The numverts of the clipped result is returned as value of the function.
{
int num, i, j ;
double x1, y1, x2, y2, x21, y21, den, t, xintsct, yintsct ;
double s1, s2 ;
num = 0 ;
for (i = 0 ; i < size ; i++) {
j = (i + 1) % size ;
// load up segment to be clipped
x1 = polyx[i] ; y1 = polyy[i] ;
x2 = polyx[j] ; y2 = polyy[j] ;
// clip line segment (x1,y1)-(x2,y2) against line
s1 = (a * x1 + b * y1 + c) ;
s2 = (a * x2 + b * y2 + c) ;
if ((s1 >= 0) && (s2 >= 0)) {
// out to out, do nothing
} else if ((s1 < 0) && (s2 < 0)) {
// in to in
resx[num] = x2 ; resy[num] = y2 ; num++ ;
} else {
// one is in, the other out, so find the intersection
x21 = x2 - x1 ; y21 = y2 - y1 ;
den = a * x21 + b * y21 ;
if (den == 0) continue ; // do nothing-should never happen
t = -(a * x1 + b * y1 + c) / den ;
xintsct = x1 + t * x21 ;
yintsct = y1 + t * y21 ;
if (s1 < 0) {
// in to out
resx[num] = xintsct ; resy[num] = yintsct ; num++ ;
} else {
// out to in
resx[num] = xintsct ; resy[num] = yintsct ; num++ ;
resx[num] = x2 ; resy[num] = y2 ; num++ ;
}
}
} // end for i
return num ; // return size of the result poly
}
int Clip_Polygon_Against_Convex_Window (
double *px, double *py, int psize,
double *wx, double *wy, int wsize)
{
double nx[100], ny[100], a, b, c, cwx, cwy ;
int i, k, m ;
// find center of mass of window
cwx = 0.0 ; cwy = 0.0 ;
for (k = 0 ; k < wsize ; k++) {
cwx += wx[k] ;
cwy += wy[k] ;
}
cwx /= wsize ;
cwy /= wsize ;
// clip the polygon against each edge of the window
for (k = 0 ; k < wsize ; k++) {
m = k + 1 ;
if (m == wsize) { m = 0 ; }
// ax + by + c = 0 is eqn of this window edge
a = wy[m] - wy[k] ;
b = wx[k] - wx[m] ;
c = -(a * wx[k] + b * wy[k]) ;
// but we need for ax + by + c < 0 to reflect "inside"
if (a * cwx + b * cwy + c > 0) {
a = -a ; b = -b ; c = -c ;
}
psize = Clip_Polygon_Against_Line (a, b, c,
px, py, psize,
nx, ny) ;
// copy back in preparation for next pass
for (i = 0 ; i < psize ; i++) {
printf("%d : %lf %lf\n", k, nx[i], ny[i]) ;
px[i] = nx[i] ;
py[i] = ny[i] ;
}
printf("\n") ;
G_rgb(drand48(), drand48(), drand48()) ;
G_fill_polygon(px, py, psize) ;
G_wait_key() ;
} // end for k
return psize ;
}
int main()
// this tests clipping of polygon to convex window
{
int pn, wn ;
double pt[2], u, v, q ;
double px[100] = { 70, 460, 400} ;
double py[100] = { 350, 25, 550} ;
pn = 3 ;
double wx[100] = { 100, 600, 550, 150} ;
double wy[100] = { 150, 200, 450, 500} ;
wn = 4 ;
srand48(100) ;
G_init_graphics (700, 700) ;
G_rgb (0, 0, 0) ;
G_clear() ;
G_rgb (1, 0, 0) ;
G_polygon(wx, wy, wn) ;
G_rgb (0, 0, 1) ;
G_polygon(px, py, pn) ;
q = G_wait_key() ;
pn = Clip_Polygon_Against_Convex_Window (px, py, pn,
wx, wy, wn) ;
G_rgb (1, 1, 0) ;
G_fill_polygon(px, py, pn) ;
q = G_wait_key() ;
}