Exemple #1
0
		grid_traits( const boost::tuple<coordinate_type, coordinate_type, coordinate_type, coordinate_type>& bounds, const coordinate_type& cellWidth )
			: m_xmin( boost::get<e_xmin>(bounds) )
			, m_xmax( boost::get<e_xmax>( bounds ) )
			, m_ymin( boost::get<e_ymin>( bounds ) )
			, m_ymax( boost::get<e_ymax>( bounds ) )
			, m_cellWidth( cellWidth )
			, m_cellWidthDivisor(constants::one<dimensionless_type>() / cellWidth )
		{
			GEOMETRIX_ASSERT( cellWidth > constants::zero<coordinate_type>());
			GEOMETRIX_ASSERT( m_xmin < m_xmax && m_ymin < m_ymax );

			m_numberXCells = boost::numeric_cast<boost::uint32_t>((m_xmax - m_xmin) * m_cellWidthDivisor) + 1;
			m_numberYCells = boost::numeric_cast<boost::uint32_t>((m_ymax - m_ymin) * m_cellWidthDivisor) + 1;
		}
Exemple #2
0
        grid_traits( const coordinate_type& xmin, const coordinate_type& xmax, const coordinate_type& ymin, const coordinate_type& ymax, const coordinate_type& cellWidth )
            : m_xmin(xmin)
            , m_xmax(xmax)
            , m_ymin(ymin)
            , m_ymax(ymax)
            , m_cellWidth(cellWidth)
            , m_cellWidthDivisor(constants::one<dimensionless_type>()/cellWidth)
        {
			GEOMETRIX_ASSERT( cellWidth > constants::zero<coordinate_type>());
			GEOMETRIX_ASSERT( xmin < xmax && ymin < ymax );

            m_numberXCells = boost::numeric_cast<boost::uint32_t>( (m_xmax - m_xmin) * m_cellWidthDivisor ) + 1;
            m_numberYCells = boost::numeric_cast<boost::uint32_t>((m_ymax - m_ymin) * m_cellWidthDivisor ) + 1;
        }
    inline typename result_of::point_polygon_closest_point<Point, typename PolygonCollection::value_type>::type point_polygon_collection_closest_point(const Point& p, const PolygonCollection& polygons)
    {
        using polygon_t = typename PolygonCollection::value_type;
        using access = point_sequence_traits<polygon_t>;
        using segment_type = segment<typename geometric_traits<polygon_t>::point_type>;
        using distance_sqrd_type = typename result_of::point_segment_distance_sqrd<Point, segment_type>::type;
        auto distance = std::numeric_limits<distance_sqrd_type>::infinity();
        std::size_t minSegmentI, minSegmentJ;
        polygon_t const* pgon = nullptr;
        for (const auto& poly : polygons) {
            auto size = access::size(poly);
            for (std::size_t i = size - 1, j = 0; j < size; i = j++) {
                auto ldistance = point_segment_distance_sqrd(p, access::get_point(poly, i), access::get_point(poly, j));
                if (ldistance < distance) {
                    pgon = &poly;
                    distance = ldistance;
                    minSegmentI = i;
                    minSegmentJ = j;
                }
            }
        }

        GEOMETRIX_ASSERT(pgon);
        return point_segment_closest_point(p, access::get_point(*pgon, minSegmentI), access::get_point(*pgon, minSegmentJ));
    }
Exemple #4
0
        data_type& get_cell(const Point& point)
        {
			BOOST_CONCEPT_ASSERT(( Point2DConcept<Point> ));
			GEOMETRIX_ASSERT( is_contained( point ) );
            boost::uint32_t i = m_gridTraits.get_x_index(get<0>(point));
            boost::uint32_t j = m_gridTraits.get_y_index(get<1>(point));
            return get_cell(i,j);
        }
Exemple #5
0
		inline void ramer_douglas_peucker_algorithm(const Polyline& poly, Polyline& nPoly, std::size_t start, std::size_t end, const Length& epsilon)
		{
			using access = point_sequence_traits<Polyline>;
			using point_t = typename access::point_type;
			using length_t = typename geometric_traits<point_t>::arithmetic_type;
			using dimensionless_t = typename geometric_traits<point_t>::dimensionless_type;
			using vector_t = vector<dimensionless_t, dimension_of<point_t>::value>;
			using line_t = line<point_t, vector_t>;

			// Find the point with the maximum distance
			auto dmax = constants::zero<length_t>();
			boost::optional<std::size_t> index;
			if ((start + 2) < end)
			{
				line_t l(access::get_point(poly, start), access::get_point(poly, end - 1));
				for (std::size_t i = start + 1; (i + 1) < end; ++i)
				{
					auto d = point_line_distance(access::get_point(poly, i), l);
					if (d > dmax)
					{
						index = i;
						dmax = d;
					}
				}
			}

			// If max distance is greater than epsilon, recursively simplify
			if (dmax > epsilon)
			{
				GEOMETRIX_ASSERT(index);
				ramer_douglas_peucker_algorithm(poly, nPoly, start, *index, epsilon);
				access::pop_back(nPoly);
				ramer_douglas_peucker_algorithm(poly, nPoly, *index, end, epsilon);
			}
			else
			{
				GEOMETRIX_ASSERT((start + 1) != end);
				access::push_back(nPoly, access::get_point(poly,start));
				access::push_back(nPoly, access::get_point(poly, end-1));
			}
		}
Exemple #6
0
		//! Convenience border point accessor.
		sequence_type operator[](std::size_t i) const
		{
			GEOMETRIX_ASSERT(i < 4);
			switch (i)
			{
			case 0:
				return m_low;
			case 1:
				return construct<sequence_type>(get<0>(m_high), get<1>(m_low));
			case 2:
				return m_high;
			case 3:
				return construct<sequence_type>(get<0>(m_low), get<1>(m_high));
			};

			throw std::out_of_range("box has 4 points");
		}
    //! Convenience border point accessor.
    point_type operator[](std::size_t i) const
    {
        GEOMETRIX_ASSERT(i < 4);
        switch (i)
        {
        case 0:
            return get_right_backward_point();
        case 1:
            return get_right_forward_point();
        case 2:
            return get_left_forward_point();
        case 3:
            return get_left_backward_point();
        };

        throw std::out_of_range("box has 4 points");
    }
    inline typename result_of::normal_at_index<Index,Vector>::type normal_at_index( const Vector& v )
    {
        BOOST_CONCEPT_ASSERT(( VectorConcept<Vector> ));
		GEOMETRIX_ASSERT(magnitude(v) != 0);
        return arithmetic_promote( get<Index>(v) ) / magnitude( v );
    }
	inline orientation_type point_polyline_orientation(const Point& p, const Polyline& pline, const NumberComparisonPolicy& cmp)
	{
		BOOST_CONCEPT_ASSERT((PointSequenceConcept<Polyline>));
		BOOST_CONCEPT_ASSERT((NumberComparisonPolicyConcept<NumberComparisonPolicy>));

		using access = point_sequence_traits<Polyline>;
		GEOMETRIX_ASSERT(access::size(pline) > 1);

		using length_t = typename select_arithmetic_type_from_sequences<Point, typename access::point_type>::type;
		using area_t = decltype(std::declval<length_t>() * std::declval<length_t>());
		using dimensionless_t = decltype(std::declval<length_t>() / std::declval<length_t>());
		using vector_t = vector<length_t, dimension_of<Point>::value>;

		auto minDistance = (std::numeric_limits<area_t>::max)();
		std::size_t segIndex;
		for (std::size_t i = 0, j = 1; j < access::size(pline); i = j++)
		{
			auto d2 = point_segment_distance_sqrd(p, access::get_point(pline, i), access::get_point(pline, j));
			if (d2 < minDistance)
			{
				minDistance = d2;
				segIndex = i;
			}
		}

		if (cmp.greater_than(minDistance, constants::zero<area_t>()))
		{
			GEOMETRIX_ASSERT(minDistance < (std::numeric_limits<area_t>::max)());
			auto pi = access::get_point(pline, segIndex);
			auto pj = access::get_point(pline, segIndex + 1);
			dimensionless_t t;
			point_segment_closest_point_and_param(p, pi, pj, t);
			if (t > constants::zero<dimensionless_t>() && t < constants::one<dimensionless_t>())
				return get_orientation(pi, pj, p, cmp);
			else if (cmp.equals(t, constants::zero<dimensionless_t>()))
			{
				//! Closest point is a vertex i.
				if (segIndex != 0)
				{
					auto ph = access::get_point(pline, segIndex - 1);
					auto o = get_orientation(ph, pi, pj, cmp);
					if (o == oriented_left)
					{
						vector_t vpi = p - pi;
						vector_t lo = pj - pi;
						vector_t hi = ph - pi;
						if (is_vector_between(lo, hi, vpi, false, cmp))
							return oriented_left;
						else
							return oriented_right;
					}
					else if (o == oriented_right)
					{
						vector_t vpi = p - pi;
						vector_t hi = pj - pi;
						vector_t lo = ph - pi;
						if (is_vector_between(lo, hi, vpi, false, cmp))
							return oriented_right;
						else
							return oriented_left;
					}
					else
						return get_orientation(pi, pj, p, cmp);
				}
				else
					return get_orientation(pi, pj, p, cmp);
			}
			else
			{
				//! pj is the closest.
				if ((segIndex + 2) < access::size(pline))
				{
					auto pk = access::get_point(pline, segIndex + 2);
					auto o = get_orientation(pi, pj, pk, cmp);
					if (o == oriented_left)
					{
						vector_t vpj = p - pj;
						vector_t lo = pk - pj;
						vector_t hi = pi - pj;
						if (is_vector_between(lo, hi, vpj, false, cmp))
							return oriented_left;
						else
							return oriented_right;
					}
					else if (o == oriented_right)
					{
						vector_t vpj = p - pj;
						vector_t hi = pk - pj;
						vector_t lo = pi - pj;
						if (is_vector_between(lo, hi, vpj, false, cmp))
							return oriented_right;
						else
							return oriented_left;
					}
					else
						return get_orientation(pi, pj, p, cmp);
				}
				else
					return get_orientation(pi, pj, p, cmp);
			}
		}

		return oriented_collinear;
	}
Exemple #10
0
        boost::uint32_t get_y_index(coordinate_type y) const 
		{
			GEOMETRIX_ASSERT( y >= m_ymin && y <= m_ymax );
			return static_cast<boost::uint32_t>((y - m_ymin) * m_cellWidthDivisor);
		}
Exemple #11
0
        boost::uint32_t get_x_index(coordinate_type x) const
		{
			GEOMETRIX_ASSERT( x >= m_xmin && x <= m_xmax );
			return static_cast<boost::uint32_t>((x - m_xmin) * m_cellWidthDivisor); 
		}