I have a 2-dimensional array of bool like this
The shape won't have any holes -- even if it has -- I'll ignore them. Now I want to find the Polygon embracing my shape:
Is there any algorithm ready to use for this case? I couldn't find any, but I'm not sure whether I know the correct search-term for this task.
You can use a delaunay triangulation and then remove the longest edges. I use the average of all edges multiply with a constant.
After thinking about more a little I found it out and there is a O(n)-way to do it: Search row-wise for the first coordinate that contains at least one adjacent field set true. From there you can definitly take the first step to the right. From now on just walk around the field deciding what direction to walk next based on the four adjacent fields.
Related
I would like to fill a plane with randomly placed points, check whether any of them overlap (and if they do, move one of them to empty place) and then calculate the average distance between them. Later I plan on extending that to 3D so that it is kind of having particles in a box.
I know there must be better ways of doing it but here's what I came up with. For placing random points in a plane:
int pos[NUMBER][2]; /* Creates an array of NUMBER amount of points with x and y coordinate */
int a, b;
srand( time(NULL) );
for(a=0;a<NUMBER;a++)
for(b=0;b<2;b++)
pos[a][b]=rand()%11; /* Using modulus is random enough for now */
The next stage is finding points that over lap:
for(a=0;a<NUMBER-1;a++)
for(b=a+1;b<NUMBER;b++)
if( pos[a][0] == pos[b][0] && pos[a][1] == pos[b][1])
printf("These points overlap:\t", pos[a][0], pos[a][1]);
Now when I identify which points overlap I have to move one of them, but when I do the point in new position might overlap with one of the earlier ones. Is there any accepted way of solving this problem? One way is infinite while(true) loop with breaking condition but that seems very inefficient especially when system gets dense.
Thank you!
Here's a sketch of a solution that I think could work:
Your point generation algorithm is good, can be left as is.
The correct time to check for overlap is already when the point is generated. We simply generate new points until we generate one that doesn't overlap with any previous.
To quickly find overlap, use a hash table such as the one from '''glib'''. The key could be two int32_t packed into a int64_t union:
typedef union _Point {
struct {
int32_t x;
int32_t y;
};
int64_t hashkey;
} Point;
Use the "iterate over all keys" functionality of your hash table to build the output array.
I haven't been able to test this but it should work. This assumes that the plane is large in relation to the number of points, so that overlaps are less likely. If the opposite is true, you can invert the logic: start with a full plane and add holes randomly.
Average complexity of this algorithm is O(n).
As you hinted that it should work for high densities as well, the best course of action is to create a 2D array of booleans (or bit vectors if you want to save space), where all elements are set to false initially. Then you loop NUMBER times, generating a random coordinate, and check whether the value in the array is true or not. If true, you generate another random coordinate. If false, you add the coordinate to the list, and set the corresponding element in the array to true.
The above assumes you want exactly NUMBER points, and a completely uniform chance of placing them. If either of those constraints are not necessary, there are other algorithms possible that use much less memory.
One solution is to place points at random, see if they overlap, and re-try on overlap. To avoid testing every point, you need to set up an index by space - if you have a 100*100 plane and a cut-off of 3-4, you could use 10*10 grid squares. Then you have to search four grid squares to check you don't have a hit.
But there are other ways of doing it. Uniformly placing points on a gird will create a Poisson distribution. So for each point, you can create a random number with the Poisson distribution. What happens when you get 2 or more? This method forces you to answer that question. Maybe you artificially clamp to one, maybe you move into the neighbouring slot. This method won't create exactly N points, so if you must have N, you can put in a fudge (randomly add/remove the last few points).
In an ordered array, is it generally faster to find out an item is not in the array than to find out it is?
Our teacher asked this question, mostly we said no but he said the answer is yes, it is faster. I really got no clue whatsoever how come even that is possible. After all, to find out that the item is not in the array we must make the most comparisons but if it is in the array we will possibly find it before that.
Can anybody explain? Thanks in advance.
Consider the following construction: Let's define a target area inside the array which contains the places where the element in question could be. When the search algorithm starts, the target area is the whole array because we have not looked at anything in the array yet.
Now suppose you do a binary search (which would be most appropriate for ordered arrays). You would look at the element in the middle of the array. If that element is smaller than the element you're looking for, you know that the element you're looking for must be on its right. Therefore the target area has been reduced to the right half of the array. Same in the opposite case: If the element you looked at was bigger, then the new target area is the left half of the array.
As you see, every step of the search algorithm will reduce the target area in some way, so that you get closer and closer to your answer. That holds true for each search algorithm. For example, if you were to iterate linearly through the elements, you would be reducing the target area by one element in each step.
Regardless of whether you're checking for inclusion (whether the item is in the array) or exclusion (whether it's not in the array), your algorithm stops at one of two situations:
While trying to narrow down the search area, you happen to pick an element from the array that is just the item that you were looking for. At this point, the inclusion test would return true, or the exclusion test would return false.
The target area is exhausted (i.e., reduced to an empty set). In this case, inclusion yields false, exclusion yields true.
From this reasoning follows that the inclusion and exclusion test are entirely symmetrical, therefore I agree with your "no". But please, do ask your teacher to explain his reasoning and post it here.
I need to sort a point array (a point is a struct with two float types - one for x and one for y) in a special fashion.
The points have to be sorted so when they are traversed, they form a zig-zag pattern starting at the top leftmost point, moving to the top rightmost point, then down to the second leftmost point, to the second rightmost point and so on.
I need this to be able to convert arbitrary polygons to triangle strip arrays which I can then draw using GLes. What would be the most efficient way of sorting those points, by either using pointers (ie. passing and rearranging the pointers to the point structures) or by copying and moving the data in the structures directly?
I'd use qsort() with a custom compare() function that as #stefan noted, sorts descending by y then alternates (max/min) for x.
I would highly recommend you use Delaunay Triangulation. OpenCV (it's available in C) has a nice implementation.
You seem to presenting us with an already reduced version of your original problem, believing that you are on the right path to the solution. I might be wrong, but it doesn't look like you are.
It seems (judging by your other questions) that you are ultimately looking for a triangulation. And, quite possibly, a triangulation of a polygon or polygons (as opposed to a set of independent points). If so, I'd suggest you take a look at some basic triangulation algorithms, like the one based on monotone decomposition. The problem you present here actually looks like a [possibly misguided] attempt to do something similar to monotone decomposition.
I don't think you've given a well-defined order. For example, what order should the points be connected if they look like this:
*
*
*
*
*
*
I would recommend moving data from the structures directly.
The size of the point struct is only 8 to 16 bytes (16bytes if float is 8bytes). If you sort the array through pointers you are copying almost the same amount of data (Or same amount of data if float is 4bytes and 8bytes pointer on 64bit system).
I would recommend sorting through pointer if the struct is large.
It seems you are trying to reinvent some kind of monotone polygonal chain. Some polygon triangulation methods are in short described in wiki and here with links to code
You should first find the median(middle value) of the points (based on the horizontal values). This will split the set of points into left and right. Next sort the 2 sets based on the vertical value. You can then just iterate from the top from each set: take top element from left set, then top element from the right.. and so on.
To find the median there is a short algorithm based on quick-sort. But faster than quick-sort. Just recurse on the part where the median is (not on both like in quick-sort).
You should be able to do it the other way around: first sort by the vertical value and then split by the horizontal (maybe this is better when you have an odd number of points).
Is there any known algorithm how to effectively generate any random multiset permutations with additional restrictions.
Example:
I have a multiset of items, for example: {1,1,1,2,2,3,3,3}, and a restricting set of sets, for example {{3},{1,2},{1,2,3},{1,2,3},{1,2,3},{1,2,3},{2,3},{2,3}}. I am looking for permutations of items, but the first element must be 3, and the second must be 1 or 2, etc.
One such permutation that fits restrictions is: {3,1,1,1,2,2,3,3}
Yes, there is. I asked in this German forum and got the following answer: The problem can be reduced to finding a maximum matching on a bipartite graph.
In order to do this, introduce vertices for all elements in the multiset. These vertices form the one side of the bipartite graph. Then, introduce vertices fo each restriction set. These vertices form the other side of the bipartite graph. Now introduce edges from each restriction set to those vertices on the first side, such that the vertex on the first side is "hit" if and only if it represents an element that is contained in the connected set.
The bipartite graph for your example would look like this:
Now the matching chooses edges in a way that no two adjacent edges are chosen. E.g. the first "1" is chosen for the second restriction "{1,2}", then it can not be used for any other restriction any more, since the use of another edge from this vertex would not result in a matching any more.
Feel free to ask in case you got another question on this.
I am working on a project which will be using large datasets (both 2D and 3D) which I will be turning into triangles, or tetrahedra, in order to render them.
I will also be performing calculations on these tris/tets. Which tris/tets to use for each calculation depend on the greatest and smallest values of their vertices.
So I need to sort the tris/tets in order of their greatest valued vertex.
--
I have tried quicksort, and binary insertion sort. Quicksort so far offers the quickest solution but it is still quite slow due to the size of the data sets.
I was thinking along the lines of a bucket/map sort when creating the tris/tets in the first place; a bucket for each of the greatest valued vertices encountered, adding pointers to the triangles who all have that value as the value of their greatest valued vertex.
This approach should be linear in time, but requires more memory obviously. This is not an issue, but my programming language of choice is c. And I'm not entirely sure how I would go about coding such a thing up.
So my question to you is, how would you go about getting the triangles/tets in such a way that you could iterate through them, from the triangle whos vertex with the greatest value of its 3 vertices is the greatest valued vertex in the entire data set, all the way down to the triangle with the the smallest greatest vertex value? :)
Can't you just store them in a binary search tree as you generate them? That would keep them in order and easily searchable (O(log(n)) for both insertion and lookup)
You could use priority queue based on a heap data structure. This should also get you O(log(n)) for insertion and extraction.