123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- #ifndef BOOST_POLYGON_DETAIL_SIMPLIFY_HPP
- #define BOOST_POLYGON_DETAIL_SIMPLIFY_HPP
- #include <vector>
- namespace boost { namespace polygon { namespace detail { namespace simplify_detail {
-
-
-
- template <typename T>
- std::size_t simplify(std::vector<T>& dst, const std::vector<T>& src,
- typename coordinate_traits<
- typename point_traits<T>::coordinate_type
- >::coordinate_distance len)
- {
- using namespace boost::polygon;
- typedef typename point_traits<T>::coordinate_type coordinate_type;
- typedef typename coordinate_traits<coordinate_type>::area_type ftype;
- typedef typename std::vector<T>::const_iterator iter;
- std::vector<T> out;
- out.reserve(src.size());
- dst = src;
- std::size_t final_result = 0;
- std::size_t orig_size = src.size();
-
- bool closed = equivalence(src.front(), src.back());
-
-
-
- bool not_done = true;
- while(not_done) {
- if(dst.size() < 3) {
- dst.clear();
- return orig_size;
- }
-
-
- ftype len2 = ftype(len) * ftype(len);
- for(iter prev=dst.begin(), i=prev+1, next; ; i = next) {
- next = i+1;
- if(next == dst.end())
- next = dst.begin();
-
- ftype ax = x(*prev), ay = y(*prev);
- ftype bx = x(*i), by = y(*i);
- ftype cx = x(*next), cy = y(*next);
-
- ftype abx = bx-ax, aby = by-ay;
- ftype bcx = cx-bx, bcy = cy-by;
- ftype acx = cx-ax, acy = cy-ay;
-
- ftype ab_ab = abx*abx + aby*aby;
- ftype bc_bc = bcx*bcx + bcy*bcy;
- ftype ac_ac = acx*acx + acy*acy;
- ftype ab_ac = abx*acx + aby*acy;
-
- ftype projf = ab_ac / ac_ac;
- ftype projx = acx * projf, projy = acy * projf;
-
- ftype perpx = abx - projx, perpy = aby - projy;
-
-
-
-
- ftype f2 = (projx*acx + projy*acx) / ac_ac;
-
- ftype dist2;
- if (f2 < 0) dist2 = ab_ab;
- else if(f2 > 1) dist2 = bc_bc;
- else dist2 = perpx*perpx + perpy*perpy;
- if(dist2 > len2) {
- prev = i;
- out.push_back(*i);
- }
- if(i == dst.begin())
- break;
- }
- std::size_t result = dst.size() - out.size();
- if(result == 0) {
- not_done = false;
- } else {
- final_result += result;
- dst = out;
- out.clear();
- }
- }
- if(closed) {
-
- --final_result;
- dst.push_back(dst.front());
- }
- return final_result;
- }
- }}}}
- #endif
|