Closest distance to border of shape - algorithm

I have a shape (in black below) and a point inside the shape (red below). What's the algorithm to find the closest distance between my red point and the border of the shape (which is the green point on the graph) ?
The shape border is not a series of lines but a randomly drawn shape.
Thanks.

So your shape is defined as bitmap and you can access the pixels.
You could scan ever growing squares around your point for border pixels. First, check the pixel itself. Then check a square of width 2 that covers the point's eight adjacent pixels. Next, width 4 for the next 16 pixels and so on. When you find a border pixel, record its distance and check against the minimum distance found. You can stop searching when half the width of the square is greater than the current minimum distance.
An alternative is to draw Bresenham circles of growing radius around the point. The method is similar to the square method, but you can stop immediately when you have a hit, because all points are supposed to have the same distance to your point. The drawback is that this method is somewhat inaccurate, because the circle is only an approximation. You will also miss some pixels along the disgonals, because Bresenham circles have artefacts.
(Both methods are still quite brute-force and in the worst case of a fully black bitmap will visit every node.)
You need a criterion for a pixel on the border. Your shape is antialiassed, so that pixels on the border are smoothed by making them a shade of grey. If your criterion is a pixel that isn't black, you will chose a point a bit inside the shape. If you cose pure white, you'll land a bit outside. Perhaps it's best to chose a pixel with a grey value greater than 0.5 as border.
If you have to find the closest border point to many points for the same shape, you can preprocess the data and use other methods of [nearest-neighbour serach].

As always, it depends on the data, in this case, what your shapes are like and any useful information about your starting point (will it often be close to a border, will it often be near the center of mass, etc).
If they are similar to what you show, I'd probably test the border points individually against the start. Now the problem is how you find the border without having to edge detect the entire shape.
The problem is it appears you can have sharply concave borders (think of a circle with a tiny spike-like sliver jutting into it). In this case you just need to edge detect the shape and test every point.
I think these will work, but don't hold me to it. Computational geometry seems to be very well understood, so you can probably find a pro at this somewhere:
Method One
If the shape is well behaved or you don't mind being wrong try this:
1- Draw 4 lines (diving the shape into four quandrants). And check the distance to each border. What i mean by draw is keep going north until you hit a white pixel, then go south, west, and east.
2- Take the two lines you have drawn so far that have the closest intersection points, bisect the angle they create and add the new line to your set.
3- keep repeating step two until are you to a tolerance you can be happy with.
Actually you can stop before this and on a small enough interval just trace the border between two close points checking each point between them to refine the final answer.
Method Two (this wil work with the poorly behaved shapes and plays well with anti-aliasing):
1- draw a line in any direction until he hit the border (black to white). This will be your starting distance.
2- draw a circle at this distance noting everytime you go from black to white or white to black. These are your intersection points.
As long as you have more than two points, divide the radius in half and try again.
If you have no points increase your radius by 50% and try again (basically binary search until you get to two points - if you get one, you got lucky and found your answer).
3- your closet point lies in the region between your two points. Run along the border checking each one.
If you want to, to reduce the cost of step 3 you can keep doing step 2 until you get a small enough range to brute force in step 3.
Also to prevent a very unlucky start, draw four initial lines (also east, south, and west) and start with the smallest distance. Those are easy to draw and greatly reduce your chance of picking the exact longest distance and accidentally thinking that single pixel is the answer.
Edit: one last optimization: because of the symmetry, you only need to calculate the circle points (those points that make up the border of the circle) for the first quadrant, then mirror them. Should greatly cut down on computation time.

If you define the distance in terms of 'the minimum number of steps that need to be taken to reach from the start pixel to any pixel on the margin', then this problem can be solved using any shortest path search algorithm like bread first search or even better if you use A* search algorithm.

Related

Find the corner points of a set of pixels that make up a quadrilateral boundary

I have a situation where I have a set of pixels that make up the border of a quadrilateral (very close to square). I'm trying to determine the location of the corners as best as possible and have been struggling for a while now. My first thought was to determine the straight lines of the border and then calculate the corner points, but I don't have access to OpenCV or other image processing libraries, unfortunately.
Below are three cases where the black outline is the image boundary and the red outline is the quadrilateral boundary. I have a list of all of the pixels that make up the red boundary and the red boundary thickness may vary.
My initial thought was that I could just find the pixel that is closest to each of the four image boundaries, however this won't quite work for the first case where the inner quadrilateral isn't tilted.
Any thoughts on how to tackle this problem would be great. I'm coding in dart, but am looking for a psuedocode answer that I can implement myself.
(I have seen this post, which is similar to my problem, but I think there should be a simpler solution for my problem since I have access to all of the boundary points of the quadrilateral)
Having a list of all rectangle boundary pixels, you can use simple methods like this:
Calculate gravity center of rectangle (just sum X- and Y- coordinates of pixels and divide by their number) - it is diagonal intersection.
Find the farthest pixels - they are corners.
In case of bad quality of data set (empty places, excessive pixels) center calculation might be inexact. So you can apply Hough transform to extract sides (as lines) and calculate their intersections.

Testing whether area around a polygon is obstacle free

I have a set of arbitrary rotated filled rectangles plotted on a Cartesian grid (2D integer array, each cell is either 0 - empty space or 1 - rectangle pixel) and would like to test whether a particular rectangle has any obstacles around it given that the center of rectangle is known along with the coordinates of its four edges.
For example, let's say we want to test if rectangle is obstacle free 5 units from either of its edges.
Rectangles marked with green dot are ok, while the unmarked are clearly collide.
It seems trivial for non rotated rectangles however, I am having a hard time coming up with algorithm which can handle rotated rectangles.
Simply looping starting from the center till we hit empty space and then checking for obstacles in the empty space doesn't seem to work if rectangles are touching each other.
Since you seem to be operating with an image-oriented mindset, you can use image processing.
Apply a radius-2.5 dilation filter to your image.
Treat the image as a graph where there is an edge between two pixels if they both have a red value above some threshold.
Any rectangles that have a path between them are at most 5 apart. (Although, note that this will give you the transitive closure of the "too close" relationship.)

Recreate image using only overlapping squares

I'm trying to take a source image, and recreate it on a transparent canvas using only overlapping mono-colored squares. The goal is to use as few squares as possible.
In other words, I'm taking a blank transparent image, and drawing squares of various colors until I recreate the source image, with the goal being to use as few squares as possible.
For example:
Here is a source image. It has two colors: red and green. I want to use only squares, that may overlap, to recreate the source image.
The ideal solution would be a large red square, and then two green squares drawn on top - that is what I want my algorithm to find, with any source image - the position, size, color and order of each square.
My target image that I intend to process is this:
(8x enlargement)
It has 1411 non-transparent pixels (worst case), and with a brute force solution that does not use overlapping squares, I've recreated the image using 1246 squares.
My current solution is a brute force method along the lines of:
Create a list of all colors used in the source image. Each item is a "layer". A layer has a color and a 2D array representing pixels. The order is important, but I don't know what order the layers need to be in, so its arbitrary initially.
For each layer in the list, initialize the 2D array. Each element corresponds to a pixel in the source image. Pixels that are the same color as the layer's chosen color is marked as '1'. Pixels that are in a layer ABOVE the current layer are marked as "don't care". All other pixels are marked as '0'.
Use some algorithm to process each layer, using the smallest number of squares to reach every pixel marked '1', without touching any pixels marked '0'.
Rearrange the order of layers and go back to Step 2. Do this for every possible combination of layers, then check to see which ordering uses the least number of squares in total.
Someone has perhaps a better explanation in a response; but brute force testing every permutation is not viable, because my target image has 31 colors (resulting in 31! permutations).
As for why I'm doing this? I'm trying to create an image in a game (Starbound), where I can only use squares. The lazy solution is to use a square for each pixel, but that's just too many squares.
Just a suggestion for a possible solution. I haven't tried it.
It's a greedy approach.
For every pixel, compute the largest uniform square that contains it.
Then choose the largest of all squares and mark all pixels it covers as "covered".
Then among all unmarked pixels, choose the largest covering square, and so on until no unmarked pixel remains.
Ties do no matter, just take any largest square and mark its pixels.
UPDATE: overlaps offer opportunities for reduction in the number of squares.
Consider all possible permutations of the filling order of the shapes. The shapes drawn first, on the bottom layers, can be (partly) hidden by some others. Process the shapes starting from the top layer. When you process a shape to associate every pixel with the largest uniform square that contains it, treat all covered pixels as don't care.
In the given example, fill the green squares first; then when filling the red square, the green pixels can be considered red or not, depending on convenience.
If you cannot try all permutations, then try them at random. Heuristic approaches such as genetic algorithms or simulated annealing could help. Nothing straightforward here.
It would be hard to guarantee an optimal solution. The brute force search would be huge. This calls for a heuristic.
Start at the edges. Walking the outside edge, find the most frequent color. Draw squares
to fill the background.
Iterate, working inwards drawing smaller and smaller squares which cover the most
pixels which are the wrong color. Ending with single-pixel squares.
Working inwards means to reduce the size of the bounding box, outside
of which all pixels are the correct color. At each step, the upper limit on the size of a square would be fitting in the bounding box. Choose the squares which give the best score.
Score is based on old vs new color being wrong or right, so there are 4 possible values for each pixel. One example function for per-pixel score would be:
wrong -> wrong: 0
wrong -> right: 1
right -> right: 1
right -> wrong: -2
I think that if you always reduce the number of wrong squares on the edge of the bounding box and never increase the size of the square, then the algorithm must halt with a solution without needing to backtrack. A backtracking solution could probably do better.
An "erosion-based" heuristic.
Consider all outline pixels, i.e. having at least a neighbor outside the shape.
Among these pixels, choose a color (the most frequent one ?).
For all outline pixels of this color, compute the largest square that does not exceed the shape.
Fill these squares, from larger to smaller, until the complete outline is covered.
Remove the correctly filled pixels and restart the procedure on the eroded shape.
In the case of the red square, all outline pixels will be covered by the red square itself, and the first filling will "consume" the whole area.
Then, removing the pixels covered in red, the two green square will remain.
All green outline pixels will now be covered by the two green squares, and the two first fillings will "consume" all green area.

minimal bounding box of a clipped point cloud

I am trying to find the minimal bounding box of a 2d point cloud, where only a part of the point cloud is visible.
Given a point cloud with a rough rectangular shape, clipped so that only one corner is visible:
The point cloud is clipped at the green border. I know the position of the border in the image, and I know that there will always be exactly one corner of the rectangular shape visible within this border. I also know the size of the rectangular shape.
Now I want to find the minimal bounding box that contains all the points of this shape, even those not visible on-screen. Since I know the dimensions of the box, finding the two sides visible is enough to determine the other two.
(there are actually two possible solutions, since width and height of the shape can be swapped, but let's ignore that for the moment)
I want to find the red box.
I do not need an exact solution, or a fast one. My current attempt uses a simple brute force algorithm that rotates the point cloud in 1° steps and finds the axis-aligned bounding box.
I just need a criterion that tells me which rotation is the best one for this case. Minimal-Area is the usual criterion for a minimal bounding box, but that obviously only works if all points are visible.
There is probably some optimal algorithm involving convex hulls, but I'd rather keep the solution as simple as possible
All you really need is the positions of the corners of the intersection between your red and green rectangle. Assuming the points are a decent approximation of the border, this should be a reasonably reliable method to get those:
Pick the two points A and B most distant from eachother. Those are two corners of the area of intersection.
Find the points C and D with the greatest perpendicular distance from the line AB (example) on either side. Those are another two corners of the area intersection.
A, B, C & D are some combination of corners of the red rectangle and intersections between the green and the red rectangles. To work out which are which, just check which are within some small tolerance of the green rectangle's border. And with that, you've got enough information to easily work out the position of the red rectangle.

Laying out circles in a rect

I'm trying to workout how to efficiently calculate the layout of a dynamic/random view.
The view will contain a number of circles. Each circle has a predetermined size. These sizes are all between a given maximum and minimum size.
I'm trying to find an efficient way of laying out the circles within a rect with a couple of conditions.
The circles mustn't overlap with the edge of the rect and the circles must have a minimum "spacing" between them.
The first method I came up with is to randomly generate coordinate pairs and place the biggest circle. Then randomly generate more coordinate pairs until a suitable one is generated for the next circle. And the next, and the next, and so on until all are drawn.
The problems with this are that it could potentially take a long time to complete. Each subsequent circle will take longer to place as there are fewer places that it can go.
Another problem is that it could be impossible to layout the view.
I'm sure there must be more efficient ways of doing this but I'm not sure where to begin.
The Formula must deal between the smallest possible square they need or from a other point of view, with an arrangement with the smallest possible density between the edgepoints. But your problem could be solved by sorting the circles by size and then start with the largest and arrange them step by step to the smallest because the larger are more bulky and the smaller fit easier in small corners by there nature.
Build triangles of circles, where 3 circles have a discribing space they use together. This triangle has 3 corners right? :) so messure/calc the angle of that corners and the corner with the nearest 90degree angle should be placed in a square corner, better to say the three circles should be places mirrored so that the circle with the fittest 90degree corner behind is the one who goes in the corner. If a 4th circle fits into the rest of this triangle, wonderful, if not you place exact this circle in it which is taken minimum outerspace of that triangle. because its not said that the next smaller circle is the one who fit's perfect, which also means you have a stack of not placed circles until one is found who fits better. after you find one you go upwards your circle-stack again and try to fit the next of it in one of the corners or you try to build the next triangle. and here you see how complex this is, damn! http://en.wikipedia.org/wiki/Malfatti_circles
But anyway, the more one of this triangles corners is 90° the less space it would take with this 3 circles in it.
An other concept could be to think about larger circles like space who leftover a triangle in one of its corners in relation to the rectangle. This triangle has a maximum space availible for a smaller circle. If there is no perfectly fitting circle your taken square-space grows up. So as far as i think about to handle this problem with imagined triangles to compare with fitting circles in it or taking triangle ranges from the square is the solutions base.

Resources