-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfiller.cpp
191 lines (179 loc) · 7.59 KB
/
filler.cpp
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/**
* @file filler.cpp
* Implementation of functions in the filler namespace.
*
*/
//#include "filler.h"
animation filler::fillStripeDFS(PNG& img, int x, int y, HSLAPixel fillColor,
int stripeSpacing, double tolerance, int frameFreq)
{
/**
* @todo Your code here!
*/
stripeColorPicker a(fillColor, stripeSpacing);
return fill<Stack>(img, x, y, a, tolerance, frameFreq);
}
animation filler::fillBorderDFS(PNG& img, int x, int y,
HSLAPixel borderColor, double tolerance, int frameFreq)
{
/**
* @todo Your code here!
*/
borderColorPicker a(borderColor, img, tolerance, *(img.getPixel(x, y)));
return fill<Stack>(img, x, y, a, tolerance, frameFreq);
}
/* Given implementation of a DFS rainbow fill. */
animation filler::fillRainDFS(PNG& img, int x, int y,
long double freq, double tolerance, int frameFreq)
{
rainbowColorPicker a(freq);
return fill<Stack>(img, x, y, a, tolerance, frameFreq);
}
animation filler::fillStripeBFS(PNG& img, int x, int y, HSLAPixel fillColor,
int stripeSpacing, double tolerance, int frameFreq)
{
/**
* @todo Your code here!
*/
stripeColorPicker a(fillColor, stripeSpacing);
return fill<Queue>(img, x, y, a, tolerance, frameFreq);
}
animation filler::fillBorderBFS(PNG& img, int x, int y,
HSLAPixel borderColor, double tolerance, int frameFreq)
{
/**
* @todo Your code here! You should replace the following line with a
*/
borderColorPicker a(borderColor, img, tolerance, *(img.getPixel(x,y)));
return fill<Queue>(img, x, y, a, tolerance, frameFreq);
}
/* Given implementation of a BFS rainbow fill. */
animation filler::fillRainBFS(PNG& img, int x, int y,
long double freq, double tolerance, int frameFreq)
{
rainbowColorPicker a(freq);
return fill<Queue>(img, x, y, a, tolerance, frameFreq);
}
template <template <class T> class OrderingStructure>
animation filler::fill(PNG& img, int x, int y, colorPicker& fillColor,
double tolerance, int frameFreq)
{
/**
* @todo You need to implement this function!
*
* This is the basic description of a flood-fill algorithm: Every fill
* algorithm requires an ordering structure, which is passed to this
* function via its template parameter. For a breadth-first-search
* fill, that structure is a Queue, for a depth-first-search, that
* structure is a Stack. To begin the algorithm, you simply place the
* given point in the ordering structure, marking it processed
* (the way you mark it is a design decision you'll make yourself).
* We have a choice to either change the color, if appropriate, when we
* add the point to the OS, or when we take it off. In our test cases,
* we have assumed that you will change the color when a point is added
* to the structure.
*
* Until the structure is empty, you do the following:
*
* 1. Remove a point from the ordering structure, and then...
*
* 1. add its unprocessed neighbors whose color values are
* within (or equal to) tolerance distance from the center,
* to the ordering structure.
* 2. use the colorPicker to set the new color of the point.
* 3. mark the point as processed.
* 4. if it is an appropriate frame, send the current PNG to the
* animation (as described below).
*
* 2. When implementing your breadth-first-search and
* depth-first-search fills, you will need to explore neighboring
* pixels in some order.
*
* For this assignment, each pixel p has 8 neighbors, consisting of
* the 8 pixels who share an edge or corner with p. (We leave it to
* you to describe those 8 pixel locations, relative to the location
* of p.)
*
* While the order in which you examine neighbors does not matter
* for a proper fill, you must use the same order as we do for
* your animations to come out like ours!
*
* The order you should put
* neighboring pixels **ONTO** the ordering structure (queue or stack)
* is as follows: **UPRIGHT(+x,-y), UP(-y), UPLEFT(-x,-y), LEFT(-x),
* DOWNLEFT(-x,+y), DOWN(+y), DOWNRIGHT(+x,+y), RIGHT(+x)**
*
* If you do them in a different order, your fill may
* still work correctly, but your animations will be different
* from the grading scripts!
*
* IMPORTANT NOTE: *UP*
* here means towards the top of the image, so since an image has
* smaller y coordinates at the top, this is in the *negative y*
* direction. Similarly, *DOWN* means in the *positive y*
* direction.
*
* 3. For every k pixels filled, **starting at the kth pixel**, you
* must add a frame to the animation, where k = frameFreq.
*
* For example, if frameFreq is 4, then after the 4th pixel has
* been filled you should add a frame to the animation, then again
* after the 8th pixel, etc. You must only add frames for the
* number of pixels that have been filled, not the number that
* have been checked. So if frameFreq is set to 1, a pixel should
* be filled every frame.
* 4. Finally, as you leave the function, send one last frame to the
* animation. This frame will be the final result of the fill, and
* it will be the one we test against.
*/
animation a;
OrderingStructure<int> osX;
OrderingStructure<int> osY;
int width = img.width();
int height = img.height();
vector<vector<bool>> processed(width,vector<bool>(height,false));
// int processed [width][height];
// for(unsigned int i=0; i<img.width(); i++) {
// for(unsigned int j=0; j<img.height(); j++) {
// processed[i][j] = 0;
// }
// }
// memset(processed,0,sizeof(int)*width*height);
int pixelCount = 0;
HSLAPixel center = *img.getPixel(x,y);
osX.add(x);
osY.add(y);
// fillColor.operator()(x,y);
*(img.getPixel(x, y)) = fillColor(x, y);//fillColor.operator()(processX+1, processY-1);
processed[x][y] = 1;
pixelCount++;
if(pixelCount % frameFreq == 0) {
// add frame to animation
a.addFrame(img);
}
int x_diff[8]={1,0,-1,-1,-1,0,1,1};
int y_diff[8]={-1,-1,-1,0,1,1,1,0};
// do fill until ordering structure is empty
while(!osX.isEmpty() && !osY.isEmpty()) {
int processX = osX.remove();
int processY = osY.remove();
for (int i=0;i<8;i++) {
int x_tmp = processX+x_diff[i];
int y_tmp = processY+y_diff[i];
if(x_tmp < width && y_tmp >= 0 && x_tmp >= 0 && y_tmp < height) { //check to make sure the pixel is within the size of image
if(processed[x_tmp][y_tmp] == 0 && center.dist(*(img.getPixel(x_tmp, y_tmp))) <= tolerance) {
osX.add(x_tmp);
osY.add(y_tmp);
*(img.getPixel(x_tmp, y_tmp)) = fillColor(x_tmp, y_tmp);
processed[x_tmp][y_tmp] = 1;
pixelCount++;
if(pixelCount % frameFreq == 0) { //check to see if we should add frame to animation
a.addFrame(img);
}
}
}
}
}
a.addFrame(img); // add one last frame
return a;
}