I want to calculate the Intersection area of circle and a polygon(not self intersecting). is there any good generalized algorithm.
Note:
What I have tried: At first I try to solve the problem with Ray casting algorithm, where I will find the points in the circle and then identify the area. But it seems harder for me as the situation got harder and with complex test cases.
Input Specification : center(x,y) and radius of the circle. vertex of the polygon( {x1,y1} , {x2,y2} , {x3,y3} ... ).
UPDATE: The more I think I become confused. is it really possible to calculate this ?
There are two steps. First, notice that this problem is easy for triangles - as there are no gotchas. Second, notice that you can break up any N-polygon into N triangles. This makes the situation much easier.
Any circle is described by the formula x^2 + y^2 = r^2. So you can get the area to the axis for any region of the line through integration.
I'll fill this out more tomorrow, I'm going out now.
Related
I am not sure if it is proper to ask for help on algorithm here, but could anyone give me some guide, or just tell me where I could find such a kind of guide? Thanks a lot!
The problem is like this: given a fixed number of circles, I need an algorithm to find an optimal set of positions and radius of these circles to cover a given shape, so the error area (the parts of the circles outside the given shape + the parts of the shape not covered by these circles) is minimal? Circles could overlap.
This is not a trivial problem and there is certainly no simple analytic solution. For example: even the simplest version - one circle and one simple connected area isn't necessarily easy to solve depending on the shape of the area. There will also typically be numerous false minimums.
I would suggest that simulated annealing would be a suitable technique to find a good (if not the optimal) solution. Effectively, with n circles you are exploring a wildly varying function of 3n variables (x, y, and r for each circle) and simulated annealing is a fairly efficient way of exploring such an environment.
Just wanted to know what is the best approach (in terms of speed and accuracy) to determine the points of intersection on N spheres (it was asked for two spheres here); wanted to know what would be the best language to do this. More detailed explanation about what I want to do is here.
As near as I can tell, you are asking for the intersection loci of each pair of N 3D spheres.
Counting symmetry, there are N * (N-1) / 2 pairs.
So take each pair.
If the distance between centers is greater than the sum of their radii, there is no intersection.
(Edit: Or, as #Ben points out, if the distance is less than the difference of radii, there is also no intersection.)
If it is equal, the intersection is a single point, easily found on the line segment between centers.
If it is less, the locus is a circle, not a point.
To find the center of that circle and its radius, you're going to need to take a plane slice through the two spheres.
That reduces the problem to finding the intersection of two circles.
For that you need the Law of Cosines.
Elaborated: Look at that Wikipedia diagram. a and b are the radii of the two spheres, and c is the distance between centers.
Use the second-to-last equation and solve for cos(alpha).
From that you can easily get sin(alpha).
Then b sin(alpha) is the radius of the circle,
and b cos(alpha) is the distance to its center.
(Note - this doesn't call any trig functions, only sqrt.)
Once you know the center and radius of the circle of intersection, the circle itself is just in a plane normal to the line segment connecting the sphere centers.
Beyond that, I'm not really sure what you want.
If i get you right, you want all intersections of at least two spheres from a group of N spheres, right?
If so, this is acually not an easy problem for high performance computing, at least not if you need an accurate solution.
This problem is also solved when calculating the "Reduced Surface" of molecules:
http://www.ncbi.nlm.nih.gov/pubmed/8906967
There are several publications on how to efficiently calculate these points and circles, but it is not an easy task.
I believe there was a publication to calculating these values with CUDA, but I don't remember the details. Google (Scholar) should be able to help you in this direction.
However, depending on what you want to achieve, there can be easier solutions.
So, perhaps you could detail your question?
I found some solutions, but they're too messy.
Yes. The Chebyshev center, x*, of a set C is the center of the largest ball that lies inside C. [Boyd, p. 416] When C is a convex set, then this problem is a convex optimization problem.
Better yet, when C is a polyhedron, then this problem becomes a linear program.
Suppose the m-sided polyhedron C is defined by a set of linear inequalities: ai^T x <= bi, for i in {1, 2, ..., m}. Then the problem becomes
maximize R
such that ai^T x + R||a|| <= bi, i in {1, 2, ..., m}
R >= 0
where the variables of minimization are R and x, and ||a|| is the Euclidean norm of a.
Perhaps these "too messy" solutions are what you actually looking for, and there are no simplier ones?
I can suggest a simple, but potentially imprecise solution, which uses numerical analysis. Assume you have a resilient ball, and you inflate it, starting from radius zero. If its center is not in the center you're looking for, then it will move, because the walls would "push" it in the proper direction, until it reaches the point, from where he can't move anywhere else. I guess, for a convex polygon, the ball will eventually move to the point where it has maximum radius.
You can write a program that emulates the process of circle inflation. Start with an arbitrary point, and "inflate" the circle until it reaches a wall. If you keep inflating it, it will move in one of the directions that don't make it any closer to the walls it already encounters. You can determine the possible ways where it could move by drawing the lines that are parallel to the walls through the center you're currently at.
In this example, the ball would move in one of the directions marked with green:
(source: coldattic.info)
Then, move your ball slightly in one of these directions (a good choice might be moving along the bisection of the angle), and repeat the step. If the new radius would be less than the one you have, retreat and decrease the pace you move it. When you'll have to make your pace less than a value of, say, 1 inch, then you've found the centre with precision of 1 in. (If you're going to draw it on a screen, precision of 0.5 pixel would be good enough, I guess).
If an imprecise solution is enough for you, this is simple enough, I guess.
Summary: It is not trivial. So it is very unlikely that it will not get messy. But there are some lecture slides which you may find useful.
Source: http://www.eggheadcafe.com/software/aspnet/30304481/finding-the-maximum-inscribed-circle-in-c.aspx
Your problem is not trivial, and there
is no C# code that does this straight
out of the box. You will have to write
your own. I found the problem
intriguing, and did some research, so
here are a few clues that may help.
First, here's an answer in "plain
English" from mathforum.org:
Link
The answer references Voronoi Diagrams
as a methodology for making the
process more efficient. In researching
Voronoi diagrams, in conjunction with
the "maximum empty circle" problem
(same problem, different name), I came
across this informative paper:
http://www.cosy.sbg.ac.at/~held/teaching/compgeo/slides/vd_slides.pdf
It was written by Martin Held, a
Computational Geometry professor at
the University of Salzberg in Austria.
Further investigation of Dr. Held's
writings yielded a couple of good
articles:
http://www.cosy.sbg.ac.at/~held/projects/vroni/vroni.html
http://www.cosy.sbg.ac.at/~held/projects/triang/triang.html
Further research into Vornoi Diagrams
yielded the following site:
http://www.voronoi.com/
This site has lots of information,
code in various languages, and links
to other resources.
Finally, here is the URL to the
Mathematics and Computational Sciences
Division of the National Institute of
Standards and Technology (U.S.), a
wealth of information and links
regarding mathematics of all sorts:
http://math.nist.gov/mcsd/
-- HTH,
Kevin Spencer Microsoft MVP
The largest inscribed circle (I'm assuming it's unique) will intersect some of the faces tangentially, and may fail to intersect others. Let's call a face "relevant" if the largest inscribed circle intersects it, and "irrelevant" otherwise.
If your convex polygon is in fact a triangle, then the problem can be solved by calculating the triangle's incenter, by intersecting angle bisectors. This may seem a trivial case, but even when
your convex polygon is complicated, the inscribed circle will always be tangent to at least three faces (proof? seems geometrically obvious), and so its center can be calculated as the incenter of three relevant faces (extended outwards to make a triangle which circumscribes the original polygon).
Here we assume that no two such faces are parallel. If two are parallel, we have to interpret the "angle bisector" of two parallel lines to mean that third parallel line between them.
This immediately suggests a rather terrible algorithm: Consider all n-choose-3 subsets of faces, find the incenters of all triangles as above, and test each circle for containment in the original polygon. Maximize among those that are legal. But this is cubic in n and we can do much better.
But it's possible instead to identify faces that are irrelevant upfront: If a face is tangent
to some inscribed circle, then there is a region of points bounded by that face and by the two angle bisectors at its endpoints, wherein the circle's center must lie. If even the circle whose center lies at the farthest tip of that triangular region is "legal" (entirely contained in the polygon), then the face itself is irrelevant, and can be removed. The two faces touching it should be extended beyond it so that they meet.
By iteratively removing faces which are irrelevant in this sense, you should be able to reduce the
polygon to a triangle, or perhaps a trapezoid, at which point the problem will be easily solved, and its solution will still lie within the original polygon.
Given n circles with radii r1 ... rn, position them in such a way that no circles are overlapping and the bounding circle is of "small" radius.
The program takes a list [r1, r2, ... rn] as input and outputs the centers of the circles.
I ask for "small" because "minimum" radius converts it into a much more difficult problem (minimum version has already been proved to be NP hard/complete - see footnote near end of question). We don't need the minimum. If the shape made by the circles seems to be fairly circular, that is good enough.
You can assume that Rmax/Rmin < 20 if it helps.
A low priority concern - the program should be able to handle 2000+ circles. As a start, even 100-200 circles should be fine.
You might have guessed that the circles need not be packed together tightly or even touching each other.
The aim is to come up with a visually pleasing arrangement of the given circles which can fit inside a larger circle and not leave too much empty space. (like the circles in a color blindness test picture).
You can use the Python code below as a starting point (you would need numpy and matplotlib for this code - "sudo apt-get install numpy matplotlib" on linux)...
import pylab
from matplotlib.patches import Circle
from random import gauss, randint
from colorsys import hsv_to_rgb
def plotCircles(circles):
# input is list of circles
# each circle is a tuple of the form (x, y, r)
ax = pylab.figure()
bx = pylab.gca()
rs = [x[2] for x in circles]
maxr = max(rs)
minr = min(rs)
hue = lambda inc: pow(float(inc - minr)/(1.02*(maxr - minr)), 3)
for circle in circles:
circ = Circle((circle[0], circle[1]), circle[2])
color = hsv_to_rgb(hue(circle[2]), 1, 1)
circ.set_color(color)
circ.set_edgecolor(color)
bx.add_patch(circ)
pylab.axis('scaled')
pylab.show()
def positionCircles(rn):
# You need rewrite this function
# As of now, this is a dummy function
# which positions the circles randomly
maxr = int(max(rn)/2)
numc = len(rn)
scale = int(pow(numc, 0.5))
maxr = scale*maxr
circles = [(randint(-maxr, maxr), randint(-maxr, maxr), r)
for r in rn]
return circles
if __name__ == '__main__':
minrad, maxrad = (3, 5)
numCircles = 400
rn = [((maxrad-minrad)*gauss(0,1) + minrad) for x in range(numCircles)]
circles = positionCircles(rn)
plotCircles(circles)
Added info : The circle packing algorithm commonly referred to in google search results is not applicable to this problem.
The problem statement of the other "Circle packing algorithm" is thus : Given a complex K ( graphs in this context are called simplicial complexes, or complex in short) and appropriate boundary conditions, compute the radii of the corresponding circle packing for K....
It basically starts off from a graph stating which circles are touching each other (vertices of the graph denote circles, and the edges denote touch/tangential relation between circles). One has to find the circle radii and positions so as to satisfy the touching relationship denoted by the graph.
The other problem does have an interesting observation (independent of this problem) :
Circle Packing Theorem - Every circle packing has a corresponding planar graph (this is the easy/obvious part), and every planar graph has a corresponding circle packing (the not so obvious part). The graphs and packings are duals of each other and are unique.
We do not have a planar graph or tangential relationship to start from in our problem.
This paper - Robert J. Fowler, Mike Paterson, Steven L. Tanimoto: Optimal Packing and Covering in the Plane are NP-Complete - proves that the minimum version of this problem is NP-complete. However, the paper is not available online (at least not easily).
Not a solution, just a brainstorming idea: IIRC one common way to get approximate solutions to the TSP is to start with a random configuration, and then applying local operations (e.g. "swapping" two edges in the path) to try and get shorter and shorter paths. (Wikipedia link)
I think something similar would be possible here:
Start with random center positions
"Optimize" these positions, so there are no overlapping circles and so the circles are as close as possible, by increasing the distance between overlapping circles and decreasing the distance between other circles, until they're tightly packed. This could be done by some kind of energy minimization, or there might be a more efficient greedy solution.
Apply an iterative improvement operator to the center positons
Goto 2, break after a maximum number of iterations or if the last iteration didn't find any improvement
The interesting question is: what kind of "iterative improvement operator" could you use in step 3? We can assume that the positions at that stage are locally optimal, but they might be improved by rearranging a large fraction of the circles. My suggestion would be to arbitrarily choose a line through the circles. Then take all the circles "left" of the line and mirror them at some axis perpendicular to that line:
You would probably try multiple lines and pick the one that leads to the most compact solution.
The idea is, if some of the circles are already at or close to their optimal configuration, chances are good this operation won't disturb them.
Other possible operations I could think of:
Take one of the circles with the highest distance from the center (one touching the boundary circle), and randomly move it somewhere else:
Choose a set of cirlces that are close to each other (e.g. if their centers lie in an randomly chosen circle) and rotate them by a random angle.
Another option (although a bit more complex) would be to measure the area between the circles, when they're tightly packed:
Then you could pick one of the circles adjacent to the largest between-circle-area (the red area, in the image) and swap it with another circle, or move it somewhere to the boundary.
(Response to comment:) Note that each of these "improvements" is almost guaranteed to create overlaps and/or unneccessary space between circles. But in the next iteration, step 2 will move the circles so they are tightly packed and non-overlapping again. This way, I can have one step for local optimizations (without caring about global ones), and one for global optimizations (which might create locally suboptimal solutions). This is far easier than having one complex step that does both.
I have a pretty naive one pass (over the radii) solution that produces alright results, although there is definitely room for improvement. I do have some ideas in that direction but figure I might as well share what I have in case anybody else wants to hack on it too.
It looks like they intersect at the center, but they don't. I decorated the placement function with a nested loop that checks every circle against every other circle (twice) and raises an AssertionError if there is an intersection.
Also, I can get the edge close to perfect by simply reverse sorting the list but I don't think the center looks good that way. It's (pretty much the only thing ;) discussed in the comments to the code.
The idea is to only look at discrete points that a circle might live at and iterate over them using the following generator:
def base_points(radial_res, angular_res):
circle_angle = 2 * math.pi
r = 0
while 1:
theta = 0
while theta <= circle_angle:
yield (r * math.cos(theta), r * math.sin(theta))
r_ = math.sqrt(r) if r > 1 else 1
theta += angular_res/r_
r += radial_res
This just starts at the origin and traces out points along concentric circles around it. We process the radii by sorting them according to some parameters to keep the large circles near the center (beginning of list) but enough small ones near the beginning to fill in spaces. We then iterate over the radii. within the main loop, we first loop over points that we have already looked at and saved away. If none of those are suitable, we start pulling new points out of the generator and saving them (in order) until we find a suitable spot. We then place the circle and go through our list of saved points pulling out all of the ones that fall within the new circle. We then repeat. on the next radius.
I'll put some ideas I have into play and make it mo`bettah. This might serve as a good first step for a physics based idea because you get to start with no overlaps. Of course it might already be tight enough so that you wouldn't have much room.
Also, I've never played with numpy or matplotlib so I write just vanilla python. There might be something in there that will make it run much faster, I'll have to look.
Can you treat the circles as charged particles in a charged cavity and look for a stable solution? That is, circles repel one another according to proximity, but are attracted towards the origin. A few steps of simulation might get you a decent answer.
Sounds like a Circle Packing problem, here is some information:
Circle Packing Wolfram MathWorld
Circle Packing Algorithms Google Scholar
CirclePack software
http://en.wikipedia.org/wiki/Apollonian_gasket
This seems somewhat relevant to what you are trying to do, and may provide some potential constraints for you.
I have problem of packing 2 arbitrary polygons. I.e. we have 2 arbitrary polygons. We are to find such placement of this polygons (we could make rotations and movements), when rectangle, which circumscribes this polygons has minimal area.
I know, that this is a NP-complete problem. I want to choose an efficient algorithm for solving this problem. I' looking for No-Fit-Polygon approach. But I could't find anywhere the simple and clear algorithm for finding the NFP of two arbitrary polygons.
The parameter space does not seem too big and testing it is not too bad either. If you fix one polygon, the other ploygon can be shifted along x-axis by X, and shifted along y-axis by Y and rotated by r.
The interesting region for X and Y can be determined by finding some bounding box for for the polygons. r of course is between and 360 degrees.
So how about you tried a set of a set of equally spaced intervals in the interesting range for X,Y and r. Perhaps, once you found the interesting points in these dimensions, you can do more finer grained search.
If its NP-complete then you need heuristics, not algorithms. I'd try putting each possible pair of sides together and then sliding one against the other to minimise area, constrained by possible overlap if they are concave of course.
There is an implementation of a robust and comprehensive no-fit polygon generation in a C++ library using an orbiting approach: https://github.com/kallaballa/libnfporb
(I am the author of libnfporb)