예제 #1
0
bool hit_test(PathType & path, double x, double y, double tol)
{
    bool inside=false;
    double x0 = 0;
    double y0 = 0;
    double x1 = 0;
    double y1 = 0;
    path.rewind(0);
    unsigned command = path.vertex(&x0, &y0);
    if (command == SEG_END) return false;
    unsigned count = 0;
    while (SEG_END != (command = path.vertex(&x1, &y1)))
    {
        ++count;
        if (command == SEG_MOVETO)
        {
            x0 = x1;
            y0 = y1;
            continue;
        }
        if ((((y1 <= y) && (y < y0)) ||
             ((y0 <= y) && (y < y1))) &&
            (x < (x0 - x1) * (y - y1)/ (y0 - y1) + x1))
            inside=!inside;

        x0 = x1;
        y0 = y1;
    }

    if (count == 0) // one vertex
    {
        return distance(x, y, x0, y0) <= std::fabs(tol);
    }
    return inside;
}
예제 #2
0
bool middle_point(PathType & path, double & x, double & y)
{
    double x0 = 0;
    double y0 = 0;
    double x1 = 0;
    double y1 = 0;
    double mid_length = 0.5 * path_length(path);
    path.rewind(0);
    unsigned command = path.vertex(&x0,&y0);
    if (command == SEG_END) return false;
    double dist = 0.0;
    while (SEG_END != (command = path.vertex(&x1, &y1)))
    {
        double seg_length = distance(x0, y0, x1, y1);

        if ( dist + seg_length >= mid_length)
        {
            double r = (mid_length - dist)/seg_length;
            x = x0 + (x1 - x0) * r;
            y = y0 + (y1 - y0) * r;
            break;
        }
        dist += seg_length;
        x0 = x1;
        y0 = y1;
    }
    return true;
}
예제 #3
0
bool hit_test(PathType & path, double x, double y, double tol)
{
    bool inside=false;
    double x0 = 0;
    double y0 = 0;
    double x1 = 0;
    double y1 = 0;
    path.rewind(0);
    unsigned command = path.vertex(&x0, &y0);
    if (command == SEG_END)
    {
        return false;
    }
    unsigned count = 0;
    mapnik::geometry_type::types geom_type = static_cast<mapnik::geometry_type::types>(path.type());
    while (SEG_END != (command = path.vertex(&x1, &y1)))
    {
        if (command == SEG_CLOSE)
        {
            continue;
        }
        ++count;
        if (command == SEG_MOVETO)
        {
            x0 = x1;
            y0 = y1;
            continue;
        }
        switch(geom_type)
        {
        case mapnik::geometry_type::types::Polygon:
        {
            if ((((y1 <= y) && (y < y0)) ||
                 ((y0 <= y) && (y < y1))) &&
                (x < (x0 - x1) * (y - y1)/ (y0 - y1) + x1))
                inside=!inside;
            break;
        }
        case mapnik::geometry_type::types::LineString:
        {
            double distance = point_to_segment_distance(x,y,x0,y0,x1,y1);
            if (distance < tol)
                return true;
            break;
        }
        default:
            break;
        }
        x0 = x1;
        y0 = y1;
    }

    // TODO - handle multi-point?
    if (count == 0) // one vertex
    {
        return distance(x, y, x0, y0) <= tol;
    }
    return inside;
}
예제 #4
0
bool centroid(PathType & path, double & x, double & y)
{
    double x0 = 0.0;
    double y0 = 0.0;
    double x1 = 0.0;
    double y1 = 0.0;
    double start_x;
    double start_y;

    path.rewind(0);
    unsigned command = path.vertex(&x0, &y0);
    if (command == SEG_END) return false;

    start_x = x0;
    start_y = y0;

    double atmp = 0.0;
    double xtmp = 0.0;
    double ytmp = 0.0;
    unsigned count = 1;
    while (SEG_END != (command = path.vertex(&x1, &y1)))
    {
        if (command == SEG_CLOSE) continue;
        double dx0 = x0 - start_x;
        double dy0 = y0 - start_y;
        double dx1 = x1 - start_x;
        double dy1 = y1 - start_y;

        double ai = dx0 * dy1 - dx1 * dy0;
        atmp += ai;
        xtmp += (dx1 + dx0) * ai;
        ytmp += (dy1 + dy0) * ai;
        x0 = x1;
        y0 = y1;
        ++count;
    }

    if (count <= 2) {
        x = (start_x + x0) * 0.5;
        y = (start_y + y0) * 0.5;
        return true;
    }

    if (atmp != 0)
    {
        x = (xtmp/(3*atmp)) + start_x;
        y = (ytmp/(3*atmp)) + start_y;
    }
    else
    {
        x = x0;
        y = y0;
    }
    return true;
}
예제 #5
0
void set_join_caps(Stroke const& stroke_, PathType & stroke)
{
    line_join_e join=stroke_.get_line_join();
    switch (join)
    {
    case MITER_JOIN:
        stroke.generator().line_join(agg::miter_join);
        break;
    case MITER_REVERT_JOIN:
        stroke.generator().line_join(agg::miter_join);
        break;
    case ROUND_JOIN:
        stroke.generator().line_join(agg::round_join);
        break;
    default:
        stroke.generator().line_join(agg::bevel_join);
    }

    line_cap_e cap=stroke_.get_line_cap();
    switch (cap)
    {
    case BUTT_CAP:
        stroke.generator().line_cap(agg::butt_cap);
        break;
    case SQUARE_CAP:
        stroke.generator().line_cap(agg::square_cap);
        break;
    default:
        stroke.generator().line_cap(agg::round_cap);
    }
}
예제 #6
0
파일: stick.cpp 프로젝트: dizuo/xrender
//==========================
//	NW	N			N	NE
//	  \	|			|  /
//		a-----------b
//	  /	|			|  \
//	SW	S			S	SE
//==========================
int Stick::extrudeLines(const PathType& path, float width)
{
	if (path.size() < 2)
	{
		return EXTRUDE_FAIL;
	}
	
	int pointSize = path.size();
	int lineSize = pointSize - 1;

	_indexList.resize( lineSize*IDEX_FACTOR );

	for (int idx=0; idx < lineSize; idx++)
	{
		const VecType& a = path[idx];
		const VecType& b = path[idx+1];

		VecType e = (b-a);
		e.normalize();
		e *= width;

		VecType N = VecType(-e.y(), e.x(), 0);
		VecType S = -N;
		VecType NE = N + e;
		VecType NW = N - e;

		VecType SW = -NE;
		VecType SE = -NW;

		_vertexList.push_back( Vertex(a + SW) );
		_vertexList.push_back( Vertex(a + NW) );
		_vertexList.push_back( Vertex(a + S) );
		_vertexList.push_back( Vertex(a + N) );

		_vertexList.push_back( Vertex(b + S) );
		_vertexList.push_back( Vertex(b + N) );
		_vertexList.push_back( Vertex(b + SE) );
		_vertexList.push_back( Vertex(b + NE) );
	}

	_generateTriangleTexCoord();
	_generateTriangesIndices();

	return EXTRUDE_SUCCESS;	
}
예제 #7
0
void set_join_caps(Symbolizer const& sym, PathType & stroke, Feature const& feature, attributes const& vars)
{
    line_join_enum join = get<line_join_enum>(sym, keys::stroke_linejoin, feature, vars, MITER_JOIN);
    switch (join)
    {
    case MITER_JOIN:
        stroke.generator().line_join(agg::miter_join);
        break;
    case MITER_REVERT_JOIN:
        stroke.generator().line_join(agg::miter_join);
        break;
    case ROUND_JOIN:
        stroke.generator().line_join(agg::round_join);
        break;
    default:
        stroke.generator().line_join(agg::bevel_join);
    }

    line_cap_enum cap = get<line_cap_enum>(sym, keys::stroke_linecap, feature, vars, BUTT_CAP);

    switch (cap)
    {
    case BUTT_CAP:
        stroke.generator().line_cap(agg::butt_cap);
        break;
    case SQUARE_CAP:
        stroke.generator().line_cap(agg::square_cap);
        break;
    default:
        stroke.generator().line_cap(agg::round_cap);
    }
}
예제 #8
0
double path_length(PathType & path)
{
    double x0 = 0;
    double y0 = 0;
    double x1 = 0;
    double y1 = 0;
    path.rewind(0);
    unsigned command = path.vertex(&x0,&y0);
    if (command == SEG_END) return 0;
    double length = 0;
    while (SEG_END != (command = path.vertex(&x1, &y1)))
    {
        length += distance(x0,y0,x1,y1);
        x0 = x1;
        y0 = y1;
    }
    return length;
}
예제 #9
0
bool hit_test_first(PathType & path, double x, double y)
{
    bool inside=false;
    double x0 = 0;
    double y0 = 0;
    double x1 = 0;
    double y1 = 0;
    path.rewind(0);
    unsigned command = path.vertex(&x0, &y0);
    if (command == SEG_END)
    {
        return false;
    }
    unsigned count = 0;
    while (SEG_END != (command = path.vertex(&x1, &y1)))
    {
        if (command == SEG_CLOSE)
        {
            break;
        }
        ++count;
        if (command == SEG_MOVETO)
        {
            x0 = x1;
            y0 = y1;
            continue;
        }

        if ((((y1 <= y) && (y < y0)) ||
             ((y0 <= y) && (y < y1))) &&
            (x < (x0 - x1) * (y - y1)/ (y0 - y1) + x1))
            inside=!inside;

        x0 = x1;
        y0 = y1;
    }
    return inside;
}
예제 #10
0
bool interior_position(PathType & path, double & x, double & y)
{
    // start with the centroid
    if (!label::centroid(path, x,y))
        return false;

    // if we are not a polygon, or the default is within the polygon we are done
    if (hit_test(path,x,y,0.001))
        return true;

    // otherwise we find a horizontal line across the polygon and then return the
    // center of the widest intersection between the polygon and the line.

    std::vector<double> intersections; // only need to store the X as we know the y

    double x0 = 0;
    double y0 = 0;
    path.rewind(0);
    unsigned command = path.vertex(&x0, &y0);
    double x1 = 0;
    double y1 = 0;
    while (SEG_END != (command = path.vertex(&x1, &y1)))
    {
        if (command != SEG_MOVETO)
        {
            // if the segments overlap
            if (y0==y1)
            {
                if (y0==y)
                {
                    double xi = (x0+x1)/2.0;
                    intersections.push_back(xi);
                }
            }
            // if the path segment crosses the bisector
            else if ((y0 <= y && y1 >= y) ||
                     (y0 >= y && y1 <= y))
            {
                // then calculate the intersection
                double xi = x0;
                if (x0 != x1)
                {
                    double m = (y1-y0)/(x1-x0);
                    double c = y0 - m*x0;
                    xi = (y-c)/m;
                }

                intersections.push_back(xi);
            }
        }
        x0 = x1;
        y0 = y1;
    }
    // no intersections we just return the default
    if (intersections.empty())
        return true;
    x0=intersections[0];
    double max_width = 0;
    for (unsigned ii = 1; ii < intersections.size(); ++ii)
    {
        double xi=intersections[ii];
        double xc=(x0+xi)/2.0;
        double width = std::fabs(xi-x0);
        if (width > max_width && hit_test(path,xc,y,0))
        {
            x=xc;
            max_width = width;
            break;
        }
    }
    return true;
}
예제 #11
0
/**
 * @brief Search the graph for a minimun path between originVertex and targetVertex. Returns the path
 *
 * @param originVertex ...
 * @param targetVertex ...
 * @param vertexPath std::vector of Vertex with the path
 * @return bool
 */
bool PlannerPRM::searchGraph(const Vertex &originVertex, const Vertex &targetVertex, std::vector<Vertex> &vertexPath)
{
	
	qDebug() << __FUNCTION__ << "Searching the graph between " << graph[originVertex].pose << "and " << graph[targetVertex].pose;
	
	// Create things for Dijkstra
	std::vector<Vertex> predecessors(boost::num_vertices(graph)); // To store parents
	std::vector<float> distances(boost::num_vertices(graph));     // To store distances

	//Create a vertex_index property map, since VertexList is listS
	typedef std::map<Vertex, size_t>IndexMap;
	IndexMap indexMap;
	boost::associative_property_map<IndexMap> propmapIndex(indexMap);
	
  //indexing the vertices
	int i=0;
	BGL_FORALL_VERTICES(v, graph, Graph)
		boost::put(propmapIndex, v, i++);

	auto predecessorMap = boost::make_iterator_property_map(&predecessors[0], propmapIndex);
	auto distanceMap = boost::make_iterator_property_map(&distances[0], propmapIndex);

	boost::dijkstra_shortest_paths(graph, originVertex, boost::weight_map(boost::get(&EdgePayload::dist, graph))
															.vertex_index_map(propmapIndex)
															.predecessor_map(predecessorMap)
 															.distance_map(distanceMap));

	//////////////////////////
	// Extract a shortest path
	//////////////////////////
	PathType path;
	Vertex v = targetVertex;

	//////////////////////////
	// Start by setting 'u' to the destintaion node's predecessor   |||// Keep tracking the path until we get to the source
	/////////////////////////
	for( Vertex u = predecessorMap[v]; u != v; v = u, u = predecessorMap[v]) // Set the current vertex to the current predecessor, and the predecessor to one level up
	{
		std::pair<Graph::edge_descriptor, bool> edgePair = boost::edge(u, v, graph);
		Graph::edge_descriptor edge = edgePair.first;
		path.push_back( edge );
	}

 	qDebug() << __FUNCTION__ << " Path found with length: " << path.size() << "steps and length " << 	distanceMap[targetVertex];
;
	Vertex lastVertex;
	if(path.size() > 0)
	{
		vertexPath.clear();
		for(PathType::reverse_iterator pathIterator = path.rbegin(); pathIterator != path.rend(); ++pathIterator)
		{
			vertexPath.push_back(boost::source(*pathIterator, graph));
			lastVertex = boost::target(*pathIterator, graph);
		}
		vertexPath.push_back(lastVertex);
		return true;
	}
	else
	{
		qDebug() << "Path no found between nodes";
		return false;
	}
}
예제 #12
0
bool interior_position(PathType & path, double & x, double & y)
{
    // start with the centroid
    if (!label::centroid(path, x,y))
        return false;

    // otherwise we find a horizontal line across the polygon and then return the
    // center of the widest intersection between the polygon and the line.

    std::vector<double> intersections; // only need to store the X as we know the y

    double x0 = 0;
    double y0 = 0;
    path.rewind(0);
    unsigned command = path.vertex(&x0, &y0);
    double x1 = 0;
    double y1 = 0;
    while (SEG_END != (command = path.vertex(&x1, &y1)))
    {
        if (command == SEG_CLOSE)
            continue;
        if (command != SEG_MOVETO)
        {
            // if the segments overlap
            if (y0==y1)
            {
                if (y0==y)
                {
                    double xi = (x0+x1)/2.0;
                    intersections.push_back(xi);
                }
            }
            // if the path segment crosses the bisector
            else if ((y0 <= y && y1 >= y) ||
                     (y0 >= y && y1 <= y))
            {
                // then calculate the intersection
                double xi = x0;
                if (x0 != x1)
                {
                    double m = (y1-y0)/(x1-x0);
                    double c = y0 - m*x0;
                    xi = (y-c)/m;
                }

                intersections.push_back(xi);
            }
        }
        x0 = x1;
        y0 = y1;
    }
    // no intersections we just return the default
    if (intersections.empty())
        return true;
    std::sort(intersections.begin(), intersections.end());
    double max_width = 0;
    for (unsigned ii = 1; ii < intersections.size(); ii += 2)
    {
        double xlow = intersections[ii-1];
        double xhigh = intersections[ii];
        double width = xhigh - xlow;
        if (width > max_width)
        {
            x = (xlow + xhigh) / 2.0;
            max_width = width;
        }
    }
    return true;
}
예제 #13
0
            PathType getPath(const GraphAdapterType& graphAdapter, const NodeAdapterType& start, const std::function<bool(const NodeAdapterType&)>& endCondition) const {
                PathType resultPath;

                struct NodePositionComparator {
                    bool operator() (const NodeAdapterType& lhs, const NodeAdapterType& rhs) {
                        return lhs.position < rhs.position;
                    }
                };

                std::set<NodeAdapterType> open = { start };
                std::set<NodeAdapterType, NodePositionComparator> closed;
                std::map<NodeAdapterType, NodeAdapterType, NodePositionComparator> came_from;
                typename std::set<NodeAdapterType>::iterator current;

                while(open.empty() == false) {
                    current = open.begin();

                    if(endCondition(*current) == true) {
                        // Goal found, recreating path from 'goal' node to 'start' node
                        resultPath.push_front(current->position);
                        auto pathCurrent = came_from.find(*current);
                        if(pathCurrent != came_from.end()) {
                            while(pathCurrent->second.position != start.position) {
                                resultPath.push_front(pathCurrent->second.position);
                                pathCurrent = came_from.find(pathCurrent->second);
                            }
                        }

                        return resultPath;
                    }

                    closed.insert(*current);

                    std::vector<NodeAdapterType> neighbours = graphAdapter.getNeighboursOf(*current);
                    for(NodeAdapterType& neighbour : neighbours) {
                        if(graphAdapter.isAvailable(neighbour.position)) {
                            typename std::set<NodeAdapterType>::iterator cIter, oIter;

                            cIter = closed.find(neighbour);
                            if(cIter != closed.end()) {
                                continue;
                            }

                            neighbour.g(current->g() + 1);
                            neighbour.h(graphAdapter.getHeuristicCostLeft(neighbour, neighbour));

                            oIter = open.find(neighbour);
                            if(oIter == open.end() || neighbour.g() < oIter->g()) {
                                if(oIter != open.end()) {
                                    open.erase(oIter);
                                }

                                auto cameFromIter = came_from.find(neighbour);
                                if(cameFromIter != came_from.end()) {
                                    if(cameFromIter->second.g() > neighbour.g()) {
                                        came_from.erase(cameFromIter);
                                    }
                                }
                                came_from.emplace(std::pair<NodeAdapterType, NodeAdapterType>(neighbour, *current));

                                open.insert(neighbour);
                            }
                        }
                    }

                    open.erase(current);
                }

                // If algorithm comes here, no path was found, and return value of this method will be empty vector

                return resultPath;
            }