20 #ifndef DLL_SEGMENT_HPP
21 #define DLL_SEGMENT_HPP
56 template <
typename DLL_Model>
63 typedef std::vector<Coordinates>
Curve;
69 Segment() : myIsValid(false), myCanGrow(true) {}
83 bool isValid()
const {
return myIsValid; }
94 friend std::ostream & operator<<(std::ostream & out, const Segment<U> & dll);
98 const Curve & getUpCurve()
const {
return myUpNeighbors; }
103 const Curve & getDownCurve()
const {
return myDownNeighbors; }
108 void updateConnectedUpDownCurves();
109 unsigned int computeFreemanCode(
const Coordinates & c1,
113 static const int xFromFreeman[];
114 static const int yFromFreeman[];
122 Curve myDownNeighbors;
124 DLL_Model myUnderliyingModel;
128 template <
typename DLL_Model>
130 Segment<DLL_Model>::xFromFreeman[] = {1, 1, 0, -1, -1, -1, 0, 1};
132 template <
typename DLL_Model>
134 Segment<DLL_Model>::yFromFreeman[] = {0, 1 ,1, 1, 0, -1, -1, -1};
137 template <
typename DLL_Model>
142 if (myCurve.size() < 2) {
143 myCurve.push_back(xy);
144 myUnderliyingModel.addInPoint(xy);
145 if (myCurve.size() == 2)
150 if (myIsValid && myCanGrow) {
151 myCurve.push_back(xy);
152 myUnderliyingModel.addInPoint(xy);
153 updateConnectedUpDownCurves<4>();
154 if (myUnderliyingModel.stillGrowableAfterUpdate())
170 template <
typename DLL_Model>
173 const Coordinates & c2)
const
186 int diffX =
static_cast<int>(c2.first - c1.first );
187 int diffY =
static_cast<int>(c2.second - c1.second);
189 for (
size_t i = 0; i < 8; ++i)
190 if (diffX == xFromFreeman[i] && diffY == yFromFreeman[i])
203 template <
typename DLL_Model>
205 void Segment<DLL_Model>::updateConnectedUpDownCurves()
207 size_t size = myCurve.size();
213 const Coordinates & lastPoint = myCurve[--size];
214 const Coordinates & currentPoint = myCurve[--size];
215 const Coordinates & previousPoint = myCurve[--size];
217 unsigned int freemanEnter = computeFreemanCode(previousPoint, currentPoint);
218 unsigned int freemanExit = computeFreemanCode(currentPoint, lastPoint);
220 if ((freemanExit + 8 - freemanEnter) % 4 == 0 &&
221 freemanExit != freemanEnter) {
224 myDownNeighbors.push_back(lastPoint);
225 myUnderliyingModel.addDownPoint(lastPoint);
226 myUpNeighbors.push_back(lastPoint);
227 myUnderliyingModel.addUpPoint(lastPoint);
234 size_t setSize = myDownNeighbors.size();
235 for (
unsigned int i = (freemanEnter + 5) % 8;
236 i != freemanExit; i = (i + 1) % 8)
237 if (N == 8 || i % 2 == 0) {
238 coord = Coordinates(currentPoint.first + xFromFreeman[i],
239 currentPoint.second + yFromFreeman[i]);
241 (coord != myDownNeighbors.back() &&
242 (setSize == 1 || coord != myDownNeighbors[setSize - 2]))) {
243 myDownNeighbors.push_back(coord);
245 myUnderliyingModel.addDownPoint(coord);
250 setSize = myUpNeighbors.size();
251 for (
unsigned int i = (freemanEnter + 3) % 8;
252 i != freemanExit; i = (i + 7) % 8)
253 if (N == 8 || i % 2 == 0) {
254 coord = Coordinates(currentPoint.first + xFromFreeman[i],
255 currentPoint.second + yFromFreeman[i]);
257 (coord != myUpNeighbors.back() &&
258 (setSize == 1 || coord != myUpNeighbors[setSize - 2]))) {
259 myUpNeighbors.push_back(coord);
261 myUnderliyingModel.addUpPoint(coord);
267 template <
typename DLL_Model>
268 std::ostream & operator<<(std::ostream & out, const Segment<DLL_Model> & dll)
271 out << dll.myUnderliyingModel;
273 out <<
"Non valid DLL";
280 #endif // DLL_SEGMENT_HPP