Interview: draw shapes (circles & squares) until area is less than X - algorithm

I was recently asked this question at an interview and I wasn't able to solve it. I wanted to post it here and see if anyone can give me some ideas on how to approach on solving such problems.
Question: Given positive X axis and Y axis...
Start by drawing a square of width=A (say A=1000)
Next draw a circle of maximum possible radius inside the square such that the circle touches all 4 sides of the square.
Next draw a square inside this circle such that all 4 vertices of the square are touching the circle.
Keep repeating the above process and keep drawing circles and squares alternatively until the area of the shape just drawn is < B (say B=10).
Write the pseudocode/logic to achive this.
Here is a sample diagram showing what the interviewer asked (excuse the mishapen portion).

You have 2 cases:
You're given width of a square the circle's area would then be
A = (width^2)*pi/4
You're given radius of a circle the square's area would then be
A = 2*(R^2)
In python:
R=0
width=1000
result=1000000
B=10
square=True
while result > B:
if square:
R=width/2
result=math.pi*(R*R)
else:
width=R*math.sqrt(2)
result=2*R*R
square = not square
print(result)

This is quite a simple math problem. The basic idea is to always calculate the surface by knowing the square's side and the circle's diameter (or radius). The formulas are:
P = a^2 for the square
P = (D^2)/4 for the circle where D is the diameter (not radius).
The side of the first square is a, then this means that the diameter of the next circle is also a, which in turn means that the diagonal of the next square is a. You can use Pythagorean theorem to calculate the side of the square and you repeat this until you reach the surface which is less than the one required.
I've not written a single line of code because the language is not specified and I think you can manage that with my idea. And on those interviews, they usually just want to see your line of thinking.

Related

Equidistant Points in Wrapping Rectangle

I am having trouble figuring out the math for a problem I am having.
I have an n by m rectangle and need to place k points in it such that points are, as close as possible, completely equidistant from each other.
Normally this is pretty easy, I construct the regular polygon with k points on it, center it in the center of my rectangle, stretch it to fit and voila, its vertices are my output points.
The catch is that when calculating distances on this rectangle, you can wrap. As such the point (0,0) is just 1 pixel away from the point (n-1,m-1) (using 0-indexed coordinates).
I've been messing around a bit on paper and getting nowhere fast with this. Does anybody have any idea how to calculate this?
tl;dr:
Inputs: n - width of rectangle, m - height of rectangle, k - number of points
Outputs: k pairs of (x,y) coordinates
Constraints: the output coordinates are equidistant from one another under wrapping coordinate systems.
Any advice on where I could look for such a geometry problem?

Parabola fitting with two given points and a cost function

Suppose that there is a parabola Y = aX^2 + bX + c, and it might be rotated as follow:
X = x.sin(phi) + y.cos(phi)
Y = x.cos(phi) - y.sin(phi)
phi = rotation angle
We wish to fit it on a border (e.g. inner border of an eyelid, figure below). The problem is that how we can change the parabola in each iteration such that it minimizes a cost function. We know that the parabola can be in different rotation and its origin may vary in the search region. Note that the there are two given points which the fitted parabola should passes through them (e.g. the white squares in fig below). So, In each iteration we can compute a, b and c by the two given points and the origin point (three equations and three variables).
The question is how we can reach the goal in minimum iteration (not to test all the possibilities, i.e. all angles and all positions in the search region).
Any idea will be appreciated.
#woodchips: I think this is a programming problem, and he asked a solution for the implementation.I definitely disagree with you.
A possible solution would be to first search along the vertical line which is orthogonal to the line between the two given points. And also you can vary the angle in this interval. As the nature of your problem (the border of eyelid), you can limit the angle variation between -pi/4 and pi/4. After you find the minimum cost for a position in this vertical line, you can search along the horizontal line and do similar tasks.
Why not use regression to fit a parabola to several points in the target shape? Then you could use which ever algorithm you wanted to get an approximate solution. Newton's method converges pretty fast. The optimization here is on the coefficients in the approximate parabolas.

How to find collision center of two rectangles? Rects can be rotated

I've just implemented collision detection using SAT and this article as reference to my implementation. The detection is working as expected but I need to know where both rectangles are colliding.
I need to find the center of the intersection, the black point on the image above (but I don't have the intersection area neither). I've found some articles about this but they all involve avoiding the overlap or some kind of velocity, I don't need this.
The information I've about the rectangles are the four points that represents them, the upper right, upper left, lower right and lower left coordinates. I'm trying to find an algorithm that can give me the intersection of these points.
I just need to put a image on top of it. Like two cars crashed so I put an image on top of the collision center. Any ideas?
There is another way of doing this: finding the center of mass of the collision area by sampling points.
Create the following function:
bool IsPointInsideRectangle(Rectangle r, Point p);
Define a search rectangle as:
TopLeft = (MIN(x), MAX(y))
TopRight = (MAX(x), MAX(y))
LowerLeft = (MIN(x), MIN(y))
LowerRight = (MAX(x), MIN(y))
Where x and y are the coordinates of both rectangles.
You will now define a step for dividing the search area like a mesh. I suggest you use AVG(W,H)/2 where W and H are the width and height of the search area.
Then, you iterate on the mesh points finding for each one if it is inside the collition area:
IsPointInsideRectangle(rectangle1, point) AND IsPointInsideRectangle(rectangle2, point)
Define:
Xi : the ith partition of the mesh in X axis.
CXi: the count of mesh points that are inside the collision area for Xi.
Then:
And you can do the same thing with Y off course. Here is an ilustrative example of this approach:
You need to do the intersection of the boundaries of the boxes using the line to line intersection equation/algorithm.
http://en.wikipedia.org/wiki/Line-line_intersection
Once you have the points that cross you might be ok with the average of those points or the center given a particular direction possibly. The middle is a little vague in the question.
Edit: also in addition to this you need to work out if any of the corners of either of the two rectangles are inside the other (this should be easy enough to work out, even from the intersections). This should be added in with the intersections when calculating the "average" center point.
This one's tricky because irregular polygons have no defined center. Since your polygons are (in the case of rectangles) guaranteed to be convex, you can probably find the corners of the polygon that comprises the collision (which can include corners of the original shapes or intersections of the edges) and average them to get ... something. It will probably be vaguely close to where you would expect the "center" to be, and for regular polygons it would probably match exactly, but whether it would mean anything mathematically is a bit of a different story.
I've been fiddling mathematically and come up with the following, which solves the smoothness problem when points appear and disappear (as can happen when the movement of a hitbox causes a rectangle to become a triangle or vice versa). Without this bit of extra, adding and removing corners will cause the centroid to jump.
Here, take this fooplot.
The plot illustrates 2 rectangles, R and B (for Red and Blue). The intersection sweeps out an area G (for Green). The Unweighted and Weighted Centers (both Purple) are calculated via the following methods:
(0.225, -0.45): Average of corners of G
(0.2077, -0.473): Average of weighted corners of G
A weighted corner of a polygon is defined as the coordinates of the corner, weighted by the sin of the angle of the corner.
This polygon has two 90 degree angles, one 59.03 degree angle, and one 120.96 degree angle. (Both of the non-right angles have the same sine, sin(Ɵ) = 0.8574929...
The coordinates of the weighted center are thus:
( (sin(Ɵ) * (0.3 + 0.6) + 1 - 1) / (2 + 2 * sin(Ɵ)), // x
(sin(Ɵ) * (1.3 - 1.6) + 0 - 1.5) / (2 + 2 * sin(Ɵ)) ) // y
= (0.2077, -0.473)
With the provided example, the difference isn't very noticeable, but if the 4gon were much closer to a 3gon, there would be a significant deviation.
If you don't need to know the actual coordinates of the region, you could make two CALayers whose frames are the rectangles, and use one to mask the other. Then, if you set an image in the one being masked, it will only show up in the area where they overlap.

create a concave polygon from image using N points

i am looking for a algorithm that will generate a concave polygon (with N points where N > 3 - user enters this value) from a image.
My idea for the algorithm:
// Every pixel in image is checked and a minimal orientated bounding box is generated (transparent pixels are ignored)
boundingBox = createImageBoundingBox(image);
curpoints = 4, A = 0, B = 1, tmppoints = curpoints;
while(curpoints < maxNumberOfPoints)
{
add a new point between point A and point B (A and B are points from the boundingBox)
reposition points so that it will contain the minimal surface
A++; B++;
curpoints++;
if(A == tmppoints)
{ A = 0; B = 1; tmppoints=curpoints; }
}
The problem im facing is i dont know how to optimally reposition points. Can this be done any other (better/faster way). Would appreciate any thoughts.
Thanks
EDIT:
The image has to be at least 10x10. I need the N points parameter so the user can regulate how many points are going to be used (for optimization). An alternative would be to have a factor (0-1) which tells how much detailed (how many points) you want the polygon to have (0 being 4 points, > 0 5 or more points). But not sure how to implement it.
You can use a delaunay triangulation and get the average edge lenght. Then try to remove edges that are longer then the average. The concept is from the alpha shapes.
Concave hull may be built with alpha shapes. CGAL link.
1.) Select a point in the middle of the square image.
2.) Jitter this point N times randomly from the center to generate N new points.
3.) Sort these points based on maximum angle from the center point
4.) Use your four points in your bounding box and your midpoint(s) in sorted ascending angle order to create the ordered point list of your concave polygon.
I am not sure if I understand your 'minimal surface' step above, but I believe this algorithm will work for taking a cut out of image to generate a concave polygon. I think this is faster than your above, but I am not sure because I don't understand that step fully.
This will always generate a concave polygon with the same bounds as your original image. If you don't want this, you could add a step 0.) that jitters your bounding box, and then changes your midpoint jitter based on this. Both of these ideas will result in a bounding quadrilateral with a n-sized point chunk taken out, I think.
This requires n > 4 (collapse two of you bounding box points into one if you want this to require n > 3, like you said you want.)

Drawing a circle on an array for CCD integration purposes

I am writing a function to draw an approximate circle on a square array (in Matlab, but the problem is mainly algorithmic).
The goal is to produce a mask for integrating light that falls on a portion of a CCD sensor from a diffraction-limited point source (whose diameter corresponds to a few pixels on the CCD array). In summary, the CCD sensor sees a pattern with revolution-symmetry, that has of course no obligation to be centered on one particular pixel of the CCD (see example image below).
Here is the algorithm that I currently use to produce my discretized circular mask, and which works partially (Matlab/Octave code):
xt = linspace(-xmax, xmax, npixels_cam); % in physical coordinates (meters)
[X Y] = meshgrid(xt-center(1), xt-center(2)); % shifted coordinate matrices
[Theta R] = cart2pol(X,Y);
R = R'; % cart2pol uses a different convention for lines/columns
mask = (R<=radius);
As you can see, my algorithm selects (sets to 1) all the pixels whose physical distance (in meters) is smaller or equal to a radius, which doesn't need to be an integer.
I feel like my algorithm may not be the best solution to this problem. In particular, I would like it to include the pixel in which the center is present, even when the radius is very small.
Any ideas ?
(See http://i.stack.imgur.com/3mZ5X.png for an example image of a diffraction-limited spot on a CCD camera).
if you like to select pixels if and only if they contain any part of the circle C:
in each pixel place a small circle A with the radius = halv size of the pixel, and another one around it with R=sqrt(2)*half size of the circle (a circumscribed circle)
To test if two circles touch each other you just calculate the center to center distances and subtract the sum of the two radii.
If the test circle C is within A then you select the pixel. If it's within B but not C you need to test all four pixel sides for overlap like this Circle line-segment collision detection algorithm?
A brute force approximate method is to make a much finer grid within each pixel and test each center point in that grid.
This is a well-studied problem. Several levels of optimization are possible:
You can brute-force check if every pixel is inside the circle. (r^2 >= (x-x0)^2 + (y-y0)^2)
You can brute-force check if every pixel in a square bounding the circle is inside the circle. (r^2 >= (x-x0)^2 + (y-y0)^2 where |x-x0| < r and |y-y0| < r)
You can go line-by-line (where |y-y0| < r) and calculate the starting x ending x and fill all the lines in between. (Although square roots aren't cheap.)
There's an infinite possibility of more sophisticated algorithms. Here's a common one: http://en.wikipedia.org/wiki/Midpoint_circle_algorithm (filling in the circle is left as an exercise)
It really depends on how sophisticated you want to be based on how imperative good performance is.

Resources