I was looking at the circular linked list (completely new to data structures) and got confused on what the starting point of circular linked list would be?
Any of the nodes in the list can be used as the starting point because the list is circular and any node can be reached (eventually) from any other.
Related
I'm working through the polygon triangulation algorithm in Computational Geometry:
Algorithms and Applications, 3rd edition, by Mark de Berg and others. The data structure used to represent the polygon is called a "doubly-connected edge list". As the book describes, "[it] contains a record for each face, edge, and vertex". Each edge is actually stored as two "half edges", representing each side of the edge. This makes it easier to walk the half edges around a face. The half edge records look like:
// Pseudocode. No particular language. The properties need to be pointers/references of some kind.
struct HalfEdge {
Vertex origin;
HalfEdge twin;
Face incidentFace;
HalfEdge next;
HalfEdge previous;
}
Now imagine I'm processing this polygon, with one face (so far) called Face1. I need to add a diagonal at the dotted line. This will create a new face (Face2). It seems like I need to walk all those HalfEdges that now surround Face2 and set their incidentFace property to point to Face2.
But the book says:
The diagonals computed for the split and merge vertices are added to the doubly-connected edge list. To access the doubly-connected edge list we use cross-pointers between the edges in the status structure and the corresponding edges in the doubly-connected edge list. Adding a diagonal can then be done in constant time with some simple pointer manipulations.
I don't see any further explanation. I'm not sure what a "cross pointer" means here. The "status structure" refers to a binary search tree of edges that is used to easily find the edge to the left of a given vertex, as the polygon is processed from top to bottom.
Can anyone explain this further? How are they able to update all the edges in constant time?
The same book (page 33) says:
Even more important is to realize that in
many applications the faces of the subdivision carry no interesting meaning
(think of the network of rivers or roads that we looked at before). If that is the case, we can completely forget about the face records, and the IncidentFace() field of half-edges. As we will see, the algorithm of the next section doesn’t need these fields (and is actually simpler to implement if we don’t need to update them).
So, you don't need to modify the incidentFace field in any half-edges after each diagonal insertion - you will be able to find vertices of all the monotone polygons using the next field of the HalfEdge record after all the necessary diagonals are inserted into the DCEL.
The most intricate job here is to set next and prev fields of newly inserted half-edges, and to modify these fields in existing half-edges. Exactly four existing half-edges need to be updated after each insertion - but it's not easy to find them.
As you already know, each DCEL vertex record contains a field, pointing to any half-edge, originating in this vertex. If you keep this field pointing to an internal half-edge or most recently inserted half-edge, then it'll be a little bit easier to find half-edges, which need updates in their next and prev fields after each insertion.
I have a collection of lines in my diagram and I also have a point. What I want is a collection of lines which will together form a polygon through a ordered traversal. I don't need implementation or anything all I want is someone to direct me towards the algorithm I can use.
Similar problem like this have been asked but won't work for me because
One of the common asked problems is that given a polygon I need to find whether the point lies inside it or not but this won't work for me because I don't have any polygons I only have a collection of lines.
the final polygon can be convex too so simply drawing rays on every side from that point and finding intersections won't work I need something more advanced.
Sorry for all the confusion : See this for clarity https://ibb.co/nzbxGF
You need to store your collection of segments inside a suitable data structure. Namely, the chosen data structure should support the concept of faces, as you're looking for a way to find the face in which a given point resides. One such data structure is the Doubly Connected Edge List.
The Doubly Connected Edge List is a data structure that holds a subdivision of the plane. In particular, it contains a record for each face, edge, and vertex of the subdivision. It also supports walking around a face counterclockwise, which allows you to know which segments bound a particular face (such as the face containing the point you're searching for).
You can use a Sweep Line Algorithm to construct the Doubly Connected Edge List in O(nlog(n)+klog(n)) where n is the number of segments and k is the complexity of the resulting subdivision (the total number of vertices, edges, and faces). You don't have to code it from scratch as this data structure and its construction algorithm have already been implemented many times (you can use CGAL's DCEL implementation for example).
With the Doubly Connected Edge List data structure you can solve your problem by applying the approach you've suggested in your post: given an input point, solve the Point in Polygon problem for each face in the Doubly Connected Edge List and return the set of segments bounding the face you've found. However, this approach, while might be good enough for somewhat simple subdivisions, is not efficient for complex ones.
A better approach is to transform the Doubly Connected Edge List into a data structure that is specialized in point location queries: The Trapezoidal Map. This data structure can be constructed in O(nlog(n)) expected time and for any query point the expected search time is O(log(n)). As with the Doubly Connected Edge List, you don't have to implement it yourself (again, you can use CGAL's Trapezoidal Map implementation).
What would be the best way to generate topological information for an object loaded from a STL file (STL stores just 3 vertices for each face). As a result I would like a winged-edge data structure or something similar.
Main issue is to find all unique point positions, so that triangles can be represent as list of point ids (indices) instead as list of coordinates. To do that some nearest neighbour data structure is used. In this case, I think best are space partition data structures.
With that you can get list of unique point positions, and list of triangles that are represented as triple of indices in the list of points. To create winged edge data structure or similar 'connectivity' structure, you have to find all different edges (pairs of points that are in some triangle) and store connectivity data that you need (in which triangles is edge used, for a point in which edges and/or triangles is used, ...)
I have a program that create graphs as shown below
The algorithm starts at the green color node and traverses the graph. Assume that a node (Linked list type node with 4 references Left, Right, Up and Down) has been added to the graph depicted by the red dot in the image. Inorder to integrate the newly created node with it neighbors I need to find the four objects and link it so the graph connectivity will be preserved.
Following is what I need to clarify
Assume that all yellow colored nodes are null and I do not keep a another data structure to map nodes what is the most efficient way to find the existence of the neighbors of the newly created node. I know the basic graph search algorithms like DFS, BFS etc and shortest path algorithms but I do not think any of these are efficient enough because the graph can have about 10000 nodes and doing graph search algorithms (starting from the green node) to find the neighbors when a new node is added seems computationally expensive to me.
If the graph search is not avoidable what is the best alternative structure. I thought of a large multi-dimensional array. However, this has memory wastage and also has the issue of not having negative indexes. Since the graph in the image can grow in any directions. My solution to this is to write a separate class that consists of a array based data structure to portray negative indexes. However, before taking this option I would like to know if I could still solve the problem without resolving to a new structure and save a lot of rework.
Thank you for any feedback and reading this question.
I'm not sure if I understand you correctly. Do you want to
Check that there is a path from (0,0) to (x1,y1)
or
Check if any of the neighbors of (x1,y1) are in the graph? (even if there is no path from (0,0) to any of this neighbors).
I assume that you are looking for a path (otherwise you won't use a linked-list), which implies that you can't store points which have no path to (0,0).
Also, you mentioned that you don't want to use any other data structure beside / instead of your 2D linked-list.
You can't avoid full graph search. BFS and DFS are the classic algorithms. I don't think that you care about the shortest path - any path would do.
Another approaches you may consider is A* (simple explanation here) or one of its variants (look here).
An alternative data structure would be a set of nodes (each node is a pair < x,y > of course). You can easily run 4 checks to see if any of its neighbors are already in the set. It would take O(n) space and O(logn) time for both check and add. If your programming language does not support pairs as nodes of a set, you can use a single integer (x*(Ymax+1) + Y) instead.
Your data structure can be made to work, but probably not efficiently. And it will be a lot of work.
With your current data structure you can use an A* search (see https://en.wikipedia.org/wiki/A*_search_algorithm for a basic description) to find a path to the point, which necessarily finds a neighbor. Then pretend that you've got a little guy at that point, put his right hand on the wall, then have him find his way clockwise around the point. When he gets back, he'll have found the rest.
What do I mean by find his way clockwise? For example suppose that you go Down from the neighbor to get to his point. Then your guy should be faced the first of Right, Up, and Left which he has a neighbor. If he can go Right, he will, then he will try the directions Down, Right, Up, and Left. (Just imagine trying to walk through the maze yourself with your right hand on the wall.)
This way lies insanity.
Here are two alternative data structures that are much easier to work with.
You can use a quadtree. See http://en.wikipedia.org/wiki/Quadtree for a description. With this inserting a node is logarithmic in time. Finding neighbors is also logarithmic. And you're only using space for the data you have, so even if your graph is very spread out this is memory efficient.
Alternately you can create a class for a type of array that takes both positive and negative indices. Then one that builds on that to be 2-d class that takes both positive and negative indices. Under the hood that class would be implemented as a regular array and an offset. So an array that can start at some number, positive or negative. If ever you try to insert a piece of data that is before the offset, you create a new offset that is below that piece by a fixed fraction of the length of the array, create a new array, and copy data from the old to the new. Now insert/finding neighbors are usually O(1) but it can be very wasteful of memory.
You can use a spatial index like a quad tree or a r-tree.
I'm trying to use a quadtree for 2D collision detection, but I'm a little stumped on how to implement it. First of all, I'd have a quadtree which contains four subtrees (one representing each quadrant), as well as a collection of objects which don't fit into a single subtree.
When checking an object for collisions in the tree, I would do something like this (thanks to QuadTree for 2D collision detection):
Check the object for collisions with any objects in the current node.
For any subtree whose space overlaps the object, recurse.
To find all collisions within a quadtree tree:
Check each object in the current node against each other object in the current node.
Check each object in the current node against each subtree.
To insert into a quadtree:
If the object fits into multiple subtrees, then add it to the current node, and return.
Otherwise, recurse into whichever subtree contains it.
To update a quadtree:
Recurse into each subtree.
If any element in the current node no longer fits completely in the current tree, move it to the parent.
If any element in the current node fits into a subtree, insert it into the subtree.
Is this alright? Can it be improved?
Your quadtree structure isn't optimal. You're right to store 4 subtrees per node, but actual objects should only be stored inside the leaves, not inner nodes. Therefore the collection holding the actual objects needs to be moved to the leaves.
Let's have a look at the implementation of the operations:
Insert an object into the quadtree:
Check if the object intersects the current node. If so, recurse. If you've reached the leaf level, insert the object into the collection.
Delete an object from the quadtree:
Execute the exact same steps as if inserting the object, but when you've reached the leaf level delete it from the collection.
Test if an object intersects any object inside the quadtree:
Execute the exact same steps as if inserting the object, but when you've reached the leaf level check for collision with all the objects in the collection.
Test for all collisions between all objects inside the quadtree:
For every object in the quadtree execute the single object collision test.
Update the quadtree:
Delete all objects from the quadtree whose position has been modified and insert them again.
This has several advantages:
By only storing objects in the leaves it is very easy to handle operations on the quadtree (fewer special cases)
The quadtree can have leaves with different depth, thus allowing you to adapt the density of the quadtree depending on the spatial region it covers. This adaption can happen at runtime, thus keeping the object/node ratio optimal.
Only disatvantage:
Objects can belong to several collections inside the quadtree. You're going to need an extra linear collection outside the quadtree to enumerate every object without duplicates.
Quad trees are not always the best data structure for collision detection. The overhead of a quadtree can potentially be unbounded (if you don't limit the depth of the tree), and in the worst case don't give any speed up at all. Instead, you might want to consider using a sparse grid, which gives better performance than a quadtree only without the extra overhead of traversing multiple tree levels.
There are also other completely different approaches which might be even better. For example, you could try implementing Zomorodian and Edelsbrunner's algorithm, as I did in the following module:
https://github.com/mikolalysenko/box-intersect
Here are also some articles which I wrote that discuss these issues in more detail:
http://0fps.net/2015/01/07/collision-detection-part-1/
http://0fps.net/2015/01/18/collision-detection-part-2/
http://0fps.net/2015/01/23/collision-detection-part-3-benchmarks/
In particular, if you look at the benchmarks in the last section you will see that of all the libraries surveyed, quadtrees tended to perform quite poorly compared to other collision detection methods like R-Trees, grids or segment trees.
I am not sure how cpu effective it is yet, but it seems to be working fine on my core duo in eclipse, still runs at over 2400 fps lol..
basically, I added one list to collidable objects to store references to quadtree node objects that I have associated the object with (via inserting into the quadtree). I also added a list to each quadtree node, that stores references to any objects deemed within the bounds of that node. So each node will only have one occurrence of each object. each node also stores a reference to its parent node, for navigation to nearby nodes if I want to check any of them after the inital node for further collision accuracy.
it's very easy to get references to all other objects in one cell:
list temp_checklist = object.cells[cell_index].objects
//('objects' being some sort of array or list of object references as described above)
hope that helps someone ;)