How to modify boost polygon? - c++

I really need to access separate points of the boost polygon, so I can add/remove/move them.
I found that polygon has outer and inner rings and I can iterate them somewhat like this
auto& polygon = experiment->mPolygons.at(experiment->selectedPolygonIndex);
auto& outerRing = boost::geometry::exterior_ring(polygon);
for(auto& point : outerRing)
{
//some stuff using point
}
But it does'nt help with modifications. I alose would like to know point's index, so I could insert a new one in the right position.
How can I do that?

Assuming you actually meant Boost Geometry (the library), you can find the description of the Polygon Concept here: https://www.boost.org/doc/libs/1_68_0/libs/geometry/doc/html/geometry/reference/concepts/concept_polygon.html
Note that it confirms that the polygon template models that concept.
You'll also note that many of the operations possible aren't directly included on that page. Instead you'll have to click through to the Ring concept that describes the constituent elements.
The concepts are geared to creating read-only views of arbitrary (user-supplied) data-structures. However, some operations are included as algorithms, like: bg::assign (which has assign_values, assign_zero, assign_points, assign_inverse among others), bg::append etc.

Related

Boost Polygon with indexed geometry

I need to make some polygon computation on 2D plan. Typically, isInside operation.
I found boost::Polygon API but my points are inside a single big array.
That's I call indexed geometry.
See http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/
So my best way is just to boost::Polygon and give to it my array + indices of points to use.
The objective is just to don't copy my million of points (because they are shared at least by two polygons).
I don't know if API allows it ( or I need to inherit my own class :-( ).
Maybe, someone know another API (inside boost or other).
Thanks
Documentation
within demo : https://www.boost.org/doc/libs/1_68_0/libs/geometry/doc/html/geometry/reference/algorithms/within/within_2.html
Boost Geometry allows for adapted user-defined data types.
Specifically, C arrays are adapted here: https://www.boost.org/doc/libs/1_68_0/boost/geometry/geometries/adapted/c_array.hpp
I have another answer up where I show how to use Boost Geometry algorithms on a direct C array of structs (in that case I type punned using tuple as the point type): How to calculate the convex hull with boost from arrays instead of setting each point separately? (the other answers show alternatives that may be easier if you can afford to copy some data).
The relevant algorithms would be:
https://www.boost.org/doc/libs/1_68_0/libs/geometry/doc/html/geometry/reference/algorithms/within.html
https://www.boost.org/doc/libs/1_68_0/libs/geometry/doc/html/geometry/reference/algorithms/disjoint.html

Rudimentary C++ Graph Implementation

I am working on a graph implementation for a C++ class I am taking. This is what I came up with so far:
struct Edge {
int weight;
Vertex *endpoints[2]; // always will have 2 endpoints, since i'm making this undirected
};
struct Vertex {
int data; // or id
list<Edge*> edges;
};
class Graph {
public:
// constructor, destructor, methods, etc.
private:
list<Vertex> vertices;
};
It's a bit rough at the moment, but I guess I'm wondering... Am I missing something basic? It seems a bit too easy at the moment, and usually that means I'm designing it wrong.
My thought is that a graph is just a list of vertices, which has a list edges, which will have a list of edges, which has two vertex end points.
Other than some functions I'll put into the graph (like: shortest distance, size, add a vertex, etc), am I missing something in the basic implementation of these structs/classes?
Sometimes you need to design stuff like this and it is not immediately apparent what the most useful implementation and data representation is (for example, is it better storing a collection of points, or a collection of edges, or both?), you'll run into this all the time.
You might find, for example, that your first constructor isn't something you'd actually want. It might be easier to have the Graph class create the Vertices rather than passing them in.
Rather than working within the class itself and playing a guessing game, take a step back and work on the client code first. For example, you'll want to create a Graph object, add some points, connect the points with edges somehow, etc.
The ordering of the calls you make from the client will come naturally, as will the parameters of the functions themselves. With this understanding of what the client will look like, you can start to implement the functions themselves, and it will be more apparent what the actual implementation should be
Comments about your implementation:
A graph is a collection of objects in which some pairs of objects are related. Therefore, your current implementation is one potential way of doing it; you model the objects and the relationship between them.
The advantages of your current implementation are primarily constant lookup time along an edge and generalizability. Lookup time: if you want to access the nth neighbor of node k, that can be done in constant time. Generalizability: this represents almost any graph someone could think of, especially if you replace the data type of weight and data with an object (or a Template).
The disadvantages of your current implementation are that it will probably be slower than ideal. Looking across an edge will be cheap, but still take two hops instead of one (node->edge->node). Furthermore, using a list of edges is going to take you O(d) time to look up a specific edge, where d is the degree of the graph. (Your reliance on pointers also require that the graph fits in the memory of one computer; you'd have trouble with Facebook's graphs or the US road network. I doubt that parallel computing is a concern of yours at this point.)
Concerns when implementing a graph:
However, your question asks whether this is the best way. That's a difficult question, as several specific qualities of a graph come in to play.
Edge Information: If the way in which vertices are related doesn't matter (i.e., there is no weight or value to an edge), there is little point in using edge objects; this will only slow you down. Instead, each vertex can just keep a list of pointers to its neighbors, or a list of the IDs of its neighbors.
Construction: As you noticed in the comments, your current implementation requires that you have a vertex available before adding an edge. That is true in general. But you may want to create vertices on the fly as you add edges; this can make the construction look cleaner, but will take more time if the vertices have non-constant lookup time. If you know all vertices before construction the graph, it may be beneficial to explicitly create them first, then the edges.
Density: If the graph is sparse (i.e., the number of edges per vertex is approximately constant), then an adjacency list is again a good method. However, if it is dense, you can often get increased performance if you use an adjacency matrix. Every vertex holds a list of all other vertices in order, and so accessing any edge is a constant time operation.
Algorithm: What problems do you plan on solving on the graph? Several famous graph algorithms have different running times based on how the graph is represented.
Addendum:
Have a look at this question for many more comments that may help you out:
Graph implementation C++

How to apply Data-Oriented Desing when an structure contains various number of elements in inner vector?

I would like to apply Data-Oriented Design (based on e.g. this article) to my simple physics engine. And I'm focused on optimizing the collision testing as it is the most expensive part of it.
I've organized the bounding spheres that may collide with player into single vector:
struct Sphere{ //I don't split sphere into parts,
//as I usually access both position and radius in my calculations
Point3D position;
float radius;
};
std::vector<BoudingSphere> spheres;
and I test collisions with them inside single function/method. Everything looks clear to me to that point.
The problem is, I also have some more general structures like:
struct Polygon{ //it may e.g. represents the area or be used for more precise tests
std::vector<Point2D> points;
};
I guess it won't be a good practise to just create std::vector<Polygon> the same way, as nested vector (points) will take a lot of place in memory (reserving it).
On the other hand, I cannot assume that there are always 2,3,4 or 10 points (it differs a lot, with the maximum of about 20, but it's usually much less).
And I do not want to switch from Polygon general structure to e.g. series of triangles (as it is faster then separated triangles in many calculations).
What should I do then? I want to go with the spirit of Data-Oriented Design and use the memory/cache efficiently with my Polygon.
Do I have to get rid of the inner vector (points)? How if so?
There can't be a definitive answer to this question as it would require knowledge about the way you access the data in terms of when is it initialized, can it be changed after the initialization stage and many others. However, if your data is relatively stable and you are accessing your polygons in a consistent manner just iterating over all polygons or polygons belonging to one particular object, one approach may be to put the points of your polygons into a separate vector and just have the polygons store the beginning and the end indices to that array.
This way, there are a couple of things that needs to be accessed during traversal. First, the indices stored in the polygons. Second, the points themselves. Both of these accesses are likely to be cache-friendly if the polygons are also laid out in a vector. Similar approach can be applied to polygon sets - just store the polygons in a vector and have a (begin, end) pair in your game objects.

Is the boost DE-9-IM struct usable

I want to use the de9im to speed up a call to point within a a polygon, where the polygon may be used many times. I know that de9im has this functionality but I can't seem to figure out how the class in boost even works (geometry/strategies/intersection_result.hpp ). Does anyone know if this class is actually functional and if so can they provide a simple example of a query for a polygon containing a point.
EDIT: I'm comparing the boost geometry library to JTS, which has a prepared geometry class, at this point I'm not 100% that use of the DE-9IM is what is allowing the pre computation but I am still wondering if boost has this functionality in it.
I'm not entirely sure what is the problem exactly.
DE9IM is a model used to describe the spatial relationship of Geometrical objects. See http://en.wikipedia.org/wiki/DE-9IM for more info.
I assume you're looking for a way how to represent Points, Polygons and how to check if one is within the other one. If this is the case then yes, Boost.Geometry of course supports that and many more. For instance to check if a Point is within a Polygon you may use:
boost::geometry::model::point<> to represent a Point
boost::geometry::model::polygon<> to represent a Polygon
boost::geometry::within() function to check the spatial relationship
More info you can find in the docs: http://www.boost.org/libs/geometry
E.g. at the bottom of this page:
http://www.boost.org/doc/libs/1_55_0/libs/geometry/doc/html/geometry/reference/algorithms/within/within_2.html
you can find an example showing how to create a Point, load Polygon from wkt string and check if one is within another one.

How to find right data structure for a searching application?

My question can be asked in two different aspects: one is from data structure perspective, and the other is from image processing perspective. Let's begin with the data structure perspective: suppose now I have a component composed of several small items as the following class shows:
class Component
{
public:
struct Point
{
float x_;
float y_;
};
Point center;
Point bottom;
Point top;
}
In the above example, the Component class is composed of member variables such as center, bottom and top (small items).
Now I have a stack of components (the number of components is between 1000 and 10000), and each component in the stack has been assigned different values, which means there are no duplicate components in the stack. Then, if one small item in the component, for example, 'center' in the illustrated class is known, we can find the unique component in the stack. After that, we can retrieve other properties in the component. Then my question is, how to build a right container data structure to make the searching easier? Now I am considering to use vector and find algorithm in STL(Pseudocode):
vector<Component> comArray;
comArray.push_back( component1);
.....
comArray.push_back(componentn);
find(comArray.begin(), comArray.end(), center);
I was wondering whether there are more efficient containers to solve this problem.
I can also explain my question from image processing perspective. In image processing, connect component analysis is a very important step for object recognition. Now for my application I can obtain all the connect components in the image, and I also find interesting objects should fulfill the following requirement: their connect component centers should be in a specific range. Therefore, given this constraint, I can eliminate many connected components and then work on the candidate ones. The key step in the above procedure is to how to search for candidate connected components if the central coordinate constraint is given. Any idea will be appreciated.
If you need to be able to get them rather fast, here's a little strange solution for you.
Note that it is a bad solution general-speaking, but it may suit you.
You could make an ordinary vector< component >. Or that can even be a simple array. Then make three maps:
map< Point, Component *>center
map< Point, Component *>bottom
map< Point, Component *>top
Fill them with all the available values of center, bottom and top as keys, and provide pointers to the corresponding Components as values (you could also use just indexes in a vector, so it would be map< Point, int >).
After that, you just use center[Key], bottom[Key] or top[Key], and get either your value (if you store pointers), or the index of your value in the array (if you store indexes).
I wouldn't use such an approach often, but it could work if the values will not change (so you can fill the index maps once), and the data amount is rather big (so searching through an unsorted vector is slow), and you will need to search often.
You probably want spatial indexing data structures.
I think you want to use a map or a hash_map to efficiently lookup your component based on a "center" value.
std::map<Component::Point, Component> lookuptable;
lookuptable[component1.center] = component1;
....
auto iterator = lookuptable.find(someCenterValue)
if (iterator != lookuptable.end())
{
componentN = iterator->second;
}
As for finding elements in your set that are within a given coordinated range. There are several ways to do this. One easy way is to just to have two sorted arrays of the component list, one sorted on the X axis and the other on the Y axis. Then to find the matching elements, you just do a binary search on either axis for the one closest to your target. Then expand scan up and down the array until you go out of range. You could also look at using a kd-tree and find all the nearest neighbors.
If you want to access them in const time and don't want to modify it. I think std::set is good choice for you code.
set<Component> comArray;
comArray.push_back( component1);
.....
comArray.push_back(componentn);
set<Component>::iterator iter = comArray.find(center)
of course, you should write operator== for class Component and nesting struct Point.