-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path15-Sutherland-Hodgman.py
139 lines (109 loc) · 2.91 KB
/
15-Sutherland-Hodgman.py
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
# Sutherland-Hodgman Polygon Clipping Algorithm
from graphics import*
import numpy as np
win1 = GraphWin("Sutherland-Hodgman: Initial Polygon", 500, 500)
win2 = GraphWin("Sutherland-Hodgman: Clipped Polygon", 500, 500)
left = 0; right = 1; bottom = 2; top = 3
inToIn = 0; inToOut = 1; outToIn = 2; outToOut = 3
def findCase(xmin, xmax, ymin, ymax, boundary, p1, p2):
(x1,y1) = p1
(x2,y2) = p2
if boundary == left:
if x1>=xmin and x2>=xmin:
return inToIn
elif x1>=xmin:
return inToOut
elif x2>=xmin:
return outToIn
else:
return outToOut
elif boundary == right:
if x1<=xmax and x2<=xmax:
return inToIn
elif x1<=xmax:
return inToOut
elif x2<=xmax:
return outToIn
else:
return outToOut
elif boundary == bottom:
if y1>=ymin and y2>=ymin:
return inToIn
elif y1>=ymin:
return inToOut
elif y2>=ymin:
return outToIn
else:
return outToOut
elif boundary == top:
if y1<=ymax and y2<=ymax:
return inToIn
elif y1<=ymax:
return inToOut
elif y2<=ymax:
return outToIn
else:
return outToOut
def findIntersection(xmin, xmax, ymin, ymax, boundary, p1, p2):
(x1,y1) = p1
(x2,y2) = p2
m=0
if x1 != x2:
m = (y2-y1)/(x2-x1)
if boundary == left:
return (xmin, y1+m*(xmin-x1))
elif boundary == right:
return (xmax, y1+m*(xmax-x1))
elif boundary == bottom:
if x1==x2:
return (x1,ymin)
else:
return (x1+(ymin-y1)/m, ymin)
elif boundary == top:
if x1==x2:
return (x1,ymax)
else:
return (x1+(ymax-y1)/m, ymax)
def clipPolygon(xmin, xmax, ymin, ymax, points):
for boundary in range(4):
new_points = []
for i in range(len(points)):
p1 = points[i]
p2 = points[(i+1)%(len(points))]
case = findCase(xmin,xmax,ymin,ymax,boundary,p1,p2)
if case == inToIn:
new_points.append(p2)
elif case == inToOut:
p = findIntersection(xmin,xmax,ymin,ymax,boundary,p1,p2)
new_points.append(p)
elif case == outToIn:
p = findIntersection(xmin,xmax,ymin,ymax,boundary,p1,p2)
new_points.append(p)
new_points.append(p2)
points = new_points
return points
def main():
xmin=150; xmax=350; ymin=150; ymax=350
points = [(250,125),(125,250), (175,275), (240,175)]
r1=Polygon(Point(xmin,ymin), Point(xmin,ymax), Point(xmax,ymax), Point(xmax,ymin))
r1.setOutline("blue")
r1.setWidth(5)
r1.draw(win1)
r2=r1.clone()
r2.draw(win2)
for i in range(len(points)):
(x1,y1) = points[i]
(x2,y2) = points[(i+1)%len(points)]
l = Line(Point(x1,y1), Point(x2,y2))
l.setWidth(3)
l.draw(win1)
new_points = clipPolygon(xmin, xmax, ymin, ymax, points)
for i in range(len(new_points)):
(x1,y1) = new_points[i]
(x2,y2) = new_points[(i+1)%len(new_points)]
l = Line(Point(x1,y1), Point(x2,y2))
l.setWidth(3)
l.draw(win2)
win1.getMouse()
win2.getMouse()
main()