In quickhull algo, there's need to build a cone upon set of edges.
An edge is thought as subsimplex with one vertex removed.
It is required, that adding a vertex to an edge will form a simplex, as if that vertex was just replaced.
For instance, when storing simplices as lists of vrtices, for triangle defined with vertexen {p0,p1,p2} edges are: {p1,p2},{p2,p0},{p0,p1} - in this index order.
Now, when adding new vertex p at the end of edge vertex list, new triangles are: {p1,p2,p},{p2,p0,p},{p0,p1,p} They have the same orientation as if original triangle was slanted.
For triangle, edge opposite to p1 has reversed order of remaining vertices.
For tetrahedron, it is for p0 and p2.
What is proper way of storing edges, or proper way to find out when to reverse vertices order?
Okay.
In general, storing vertex set is just not enough to represent a simplex, if its orientation matters. The same set can represent equivalent simplices with different sign of volume. A list can preserve orientation, but it's not trivial to derive it just from order. Thus, neither sets nor lists alone are not good solution (to represent both simplex and their edges).
It is probably best to use a list or tuple of vertices to represent a simplex; the question is how to decide the order of the vertices. (as I am not entirely certain of the exact requirements of an arbitrary-dimentional quickhull, I will speak generally below...)
If you are replacing each vertex v[i] in turn with a new point p, the simplest consistent thing to do is to substitute it for the point it replaces. Thus, for triangle {v0,v1,v2}, you will get new triangles {p,v1,v2}, {v0,p,v1}, and {v0,v1,p}.
If you want to reorder the vertices (e.g., so that p is at the end), then you should remember that swapping any two vertices will reverse the orientation of the simplex. So, to maintain the orientation, you must do an even number of swaps.
In the above example, swapping p with the final vertex will reverse the orientation, unless p is already the final vertex. You can fix this by swapping the first two vertices in that case. (note that this is a unique solution only for 3-vertex simplices -- it is not applicable for 2-simplices, and one of multiple solutions for N>3-simplices).
You could also look at this as a matter of rotating the vertex list of the original 3-simplex. Unfortunately, this only works for odd-vertex simplices. For a vertex list of size N, rotation involves N-1 swaps, so for a simplex with an even number of vertices, a rotation will change the orientation.
And edge of a simplex does not have an orientation by itself.
Only N-simplex in N-dimentions has defined orientation.
It is determined by cross-product of N vectors pi-p0 (signed volume).
For lower dimentional simlices in higher dimentional space such cross-product cannot be built.
For this patricular task (building new simplices with edges of another) an edge can be represented by an (ordered) list of vertices and an index where to add new point to make it on the same side as was removed vertex.
Considering cycling order of list (not sure it is universally valid), it could be rotated so that index is either 0 or 1.
Related
I'm solving extended version of knight tour problem, in which program has to return maximum number of cells through which knight can come back to initial position without overlapping its path.
I'm using backtracking approach but got stuck in detecting overlapping.
A graph is defined as a set of vertices plus a set of edges, where an edge is a pair of distinct vertices.
In particular, there is no notion of two edges "intersecting" in the way that you mean, because that's a consequence of how you've chosen to draw the graph — where you've drawn the vertices on the plane — rather than a property of the graph itself. (There is a concept of a "planar graph", meaning a graph that can be embedded in the plane with no edges intersecting; but your graph is a planar graph in that sense, so it's not really what you want.)
So to determine if two line segments intersect, we're outside the area of graph theory. Fortunately, there are some pretty straightforward ways to do this; I see that How can I check if two segments intersect? lists several. The approach that came first to my mind (and is used by a few of the highest-voted answers there) is to observe that line segments AB and CD intersect if and only if ∠CAB and ∠BAD have the same sense (clockwise vs. counterclockwise; this means that C and D are on opposite sites of AB) and ∠ACD and ∠DCB have the same sense (this means that A and B are on opposite sides of CD). You can determine this by taking the cross-products of the various segments CA, AB, etc., and comparing signs (positive vs. negative). If your coordinates are all integers, then this just requires a bit of integer arithmetic.
If this problem is restricted to knight moves, then we can consider that the number of ways that knight moves can intersect is limited (at most 9, not considering direction). For instance, if we have (on a standard chessboard) the move d3-e5, then the only knight moves that intersect are: e2-e4, c3-e4, e3-c4, e3-d5, f3-d4, d4-f5, e4-c5, e4-d6, and f4-d5 -- again, without considering direction. Near the edge of the board there would of course be fewer of those.
This means that you can spend constant time per move to mark those potentially crossing edges as no longer available, and continue the search only along available edges. To allow backtracking, you save on the (recursion) stack which edges you made unavailable at which move.
I am working with several convex polygons that overlap each other and I need to combine them back together to form one single polygon that may be convex or concave.
The problem is always as follows:
1) The polygons that I need to merge together are always convex.
2) The vertices of each polygon are defined in clockwise order.
3) The polygons are never in any specific order.
4) The final polygon can only be simple convex or concave polygon, i.e. no self-intersection, no duplicate vertices or holes in the shape.
Here is an example of the kind of polygons that I am working with.
![overlapping convex polygons]"image removed")
My current approach is to start from the first polygon and vertex by vertex I loop through all vertices of all of the polygons to find overlap. If there is no overlap, I store the vertex for the final outline and continue.
Upon finding overlapping vertices, I determine which polygon to continue to by measuring the angles of the possible paths and by choosing the one that leads towards the outside of the shape.
This method works until I encounter polygons that do not have vertices overlapping each other, but instead one polygon's vertex is overlapping another polygon's side, as is the case with the rectangle in the image.
I am currently planning on solving these situations by running line intersect checks for all shapes that I have not yet processed, but I am convinced that this cannot be the easiest or the best method in terms of performance.
Does someone know how I should approach this problem in a more efficient manner and/or universal manner?
I solved this issue and I'm posting the answer here in case someone else runs into this issue as well.
My first step was to implement a pre-processing loop based on trincot's suggestions.
I calculated the minimum and maximum x and y bounds for each individual shape.
I used these values to determine all overlapping shapes and I stored a simple array for each shape that I could later use to only look at shapes that can overlap each other.
Then, for the actual loop that determines the outline of the final polygon:
I start from the first shape and simply compare its vertices to those of the nearby shapes. If there is at least one vertex that isn't shared by another vertex, it must be on the outer edge and the loop starts from there. If there are only overlapping vertices, then I add the first shape to a table for all checked shapes and repeat this process with another shape until I find a vertex that is on the outer edge.
Once the starting vertex is found, the main loop will check the vertices of the starting shape one by one and measure how far from the given vertex is from every nearby shapes' edges. If the distance is zero, then the vertex either overlaps with another shape's vertex or the vertex lies on the side of another shape.
Upon finding the aforementioned type of vertex, I add the previous shape's number to the table of checked shapes so that it isn't checked again. Then, I check if there are other shapes that share this particular vertex. If there are, then I determine the outermost shape and continue from there, starting back from step 2.
Once all shapes have been checked, I check that all non-overlapping vertices from the starting shape were indeed added to the outline. If they weren't, I add them at the end.
There may be computationally faster methods, but I found this one to be simple to write, that it meets all of my requirements and it is fast enough for my needs.
Given a vertex, you could speed up the search of an "overlapping" vertex or edge as follows:
Finding vertices
Assuming that the coordinates are exact, in the sense that if two vertices overlap, they have exactly the same x and y coordinates, without any "error" of imprecision, then it would be good to first create a hash by x-coordinate, and then for each x-entry you would have a hash by y-coordinate. The value of that inner hash would be a list of polygons that have that vertex.
That structure can be built in O(n) time, and will allow you to find a matching vertex in constant time.
Only if that gives no match, you would go to the next algorithm:
Finding edges
In a pre-processing step (only once), create a segment tree for these polygons where a "segment" corresponds to a min/max x-coordinate range for a particular polygon.
Given a vertex, use the segment tree to find the polygons that are in the right x-coordinate range, i.e. where the x-coordinate of the vertex is within the min/max range of x-coordinates of the polygon.
Iterate those polygons, and eliminate those that do not have an y-coordinate range that has the y-coordinate of the vertex.
If no polygons remain, the vertex does not participate in any edge of another polygon.
You cannot get more than one polygon here, since that would mean another polygon shares the vertex, which is a case already covered by the hash-based algorithm.
If you get just one polygon, then continue your search by going through the edges of that polygon to find a match -- which is what you already planned on doing (line intersect check), but now you would only need to do it for one polygon.
You could speed that line intersect check up a little bit by first filtering the edges to those that have the right x-range. For convex polygons you would end up with at most two edges. At most one of those two will have the right y-range. If you get such an edge, check whether the vertex is really on that edge.
At the entrance, two polygons are given (the coordinates of the vertices of these polygons are listed in the order of their traversal; however, the traversal order for different polygon angles can be chosen different). Can one polygon be transformed into another using only parallel translation and proportional scaling?
I have following idea
So, find some common peak for two polygons and make the transfer of one polygon so that these vertices lie on one point then Scaling so that the neighboring point matches the corresponding point of another polygon, but I think it's wrong , at least I can't write it in code
Is there some special formula or theorem for this problem?
I would solve it like this.
Find the necessary parallel transport.
Find the necessary scaling.
See if they are the same polygon now.
So to start take the vertex that it farthest to the left, and if there is a tie, the one that is farthest down. Find that for both polygons. Use parallel transport to put that vertex at the origin for both.
Now take the vertex that is farthest to the right, and if there is a tie, the one that is farthest up. Find that for both polygons. If it is not at the same slope, then they are different. If it is, then scale one so that the points match.
Now see if all of the points match. If not, they are different. Otherwise the answer is yes.
Compute the axis-aligned bounding boxes of the two polygons.
If the aspect ratios do not match, the answer is negative. Otherwise the ratio of corresponding sides is your scaling factor. The translation is obtained by linking the top left corners and the transformation equations are
X = s.(x - xtl) + Xtl
Y = s.(y - ytl) + Ytl
where s is the scaling factor and (xtl, ytl), (Xtl, Ytl) are the corners.
Now choose a vertex of the first polygon, predict the coordinates in the other and find the matching vertex. If you can't, the answer is negative. Otherwise, you can compare the remaining vertices*.
*I assume that the polygons do not have overlapping vertices. If they can have arbitrary self-overlaps, I guess that you have to try matching all vertices, with all cyclic permutations.
Consider this question relative to graph theory:
Let G a complete (every vertex is connected to all the other vertices) non-directed graph of size N x N. Two "salesmen" travel this way: the first always visits the nearest non visited vertex, the second the farthest, until they have both visited all the vertices. We must generate a matrix of distances and the starting points for the two salesmen (they can be different) such that:
All the distances are unique Edit: positive integers
The distance from a vertex to itself is always 0.
The difference between the total distance covered by the two salesmen must be a specific number, D.
The distance from A to B is equal to the distance from B to A
What efficient algorithms cn be useful to help me? I can only think of backtracking, but I don't see any way to reduce the work to be done by the program.
Geometry is helpful.
Using the distances of points on a circle seems like it would work. Seems like you could determine adjust D by making the circle radius larger or smaller.
Alternatively really any 2D shape, where the distances are all different could probably used as well. In this case you should scale up or down the shape to obtain the correct D.
Edit: Now that I think about it, the simplest solution may be to simply pick N random 2D points, say 32 bit integer coordinates to lower the chances of any distances being too close to equal. If two distances are too close, just pick a different point for one of them until it's valid.
Ideally, you'd then just need to work out a formula to determine the relationship between D and the scaling factor, which I'm not sure of offhand. If nothing else, you could also just use binary search or interpolation search or something to search for scaling factor to obtain the required D, but that's a slower method.
Say I have a polygon. It can be a convex one or not, it doesn't matter, but it doesn't have holes. It also has "inner" vertices and edges, meaning that it is partitioned.
Is there any kind of popular/known algorithm or standard procedures for when I want to check if a point is inside that kind of polygon?
I'm asking because Winding Number and Ray Casting aren't accurate in this case
Thanks in advance
You need to clarify what you mean by 'inner vertices and edges'. Let's take a very general case and hope that you find relevance.
The ray casting (point in polygon) algorithm shoots off a ray counting the intersections with the sides of the POLYGON (Odd intersections = inside, Even = outside).
Hence it accurately gives the correct result regardless of whether you start from inside the disjoint trapezoidal hole or the triangular hole (inner edges?) or even if a part of the polygon is completely seperated and/or self intersecting.
However, in what order do you feed the vertices of the polygon such that all the points are evaluated correctly?
Though this is code specific, if you're using an implementation that is counting every intersection with the sides of the polygon then this approach will work -
- Break the master polygon into polygonal components. eg - trapezoidal hole is a polygonal component.
- Start with (0,0) vertex (doesn't matter whether (0,0) actually lies wrt your polygon) followed by the first component' vertices, repeating its first vertex after the last vertex.
- Include another (0,0) vertex.
- Include the next component , repeating its first vertex after the last vertex.
- Repeat the above two steps for each component.
- End with a final (0,0) vertex.
2 component eg- Let the vertices of the two components be (1x,1y), (2x,2y), (3x,3y) and (Ax,Ay), (Bx,By), (Cx,Cy). Where (Ax,Ay), (Bx,By), (Cx,Cy) could be anything from a disjoint triangular hole, intersecting triangle or separated triangle.
Hence , the vertices of a singular continous polygon which is mathematically equivalent to the 2 components is -
(0,0),(1x,1y),(2x,2y),(3x,3y),(1x,1y),(0,0),(Ax,Ay),(Bx,By),(Cx,Cy),(Ax,Ay),(0,0)
To understand how it works, try drawing this mathematically equivalent polygon on a scratch pad.-
1. Mark all the vertices but don't join them yet.
2. Mark the repeated vertices separately also. Do this by marking them close to the original points, but not on them. (at a distance e, where e->0 (tends to/approaches) ) (to help visualize)
3. Now join all the vertices in the right order (as in the example above)
You will notice that this forms a continuous polygon and only becomes disjoint at the e=0 limit.
You can now send this mathematically equivalent polygon to your ray casting function (and maybe even winding number function?) without any issues.