This is a question from a mind games book. I tried solving it like this (http://pastebin.com/sdfcuxW1) but had no luck. It also has to be very optimized to process outputs for 2000 input coordinates under 4 seconds.
Any suggestions about my code, or any new algorithm ideas would be very helpful.
Question:
We have a coordinate plane, and we are only using the first quadrant. We are supplied with a number of coordinates each with +X and +Y values. For example 0,2 - 5,4 etc. We are required to connect each of these coordinates with rectangles (one corner of the rectangle touches one coordinate and another corner touches another coordinate) so that all coordinates are in contact with each other (no left-outs). We also have to make sure that the rectangles that we use to connect our 2 coordinates do not overlap with any other coordinate (on the edges is fine). What kind of algorithm can print out the best solution to this problem, given that the goal is to use the smallest total rectangle area possible.
http://cl.ly/image/1P012s3p1E1g
purple areas are rectangles and green dots are coordinates. we can have rectangles which have 0 height of width, which consume no area.
What I couldn't figure out: find the closest coordinates to our starting coordinate is easy. but it is hard to make sure that all coordinates are connected together. i always get pieces of coordinates floating in different areas of the plane. my code also lags with >1000 points.
Here is a solution:
Let's model this problem as a graph problem.
The vertices are the given points.
There is an edge between every pair vertices. The weight of this edge is the area of the rectangle formed by this pair of points.
The answer is the minimum spanning tree in this graph. We can use Prim's algorithm to find it.
The time complexity of this solution is O(n ^ 2).
The only question is: why can't a rectangle generated by this algorithm contain another point? I will not post a formal proof here, but drawing some pictures shows that if there is such a rectangle, the solution is not optimal(an idea of a proof: let's assume that there is a point inside. We can split this rectangle into two so that this points becomes one of their corner. The total area can only decrease after performing this operation).
Related
The following problem im working on is for one of my favorite past-times: game development.
Problem:
We're in 3D space. I'm trying to determine if a line between two vectors in said space is passing through a circle; the latter of which consists of: center vector, radius, yaw & pitch.
In order to determine that, my aim is to convert the circle to a plane which can either be infinite or just have the diameter of the circle for all it's sides.
Should the line between the two vectors in fact pass through that plane, i am left with the simple task of determining wether that intersection point is within the radius of the circle, in which case i can return either true or false.
What's already working:
I have my circles set up and the general framework is there. The circles are appearing/rendered in the 3D space exactly as specified, great!
What was already tried:
Copied some github gist codes and tried to make them work for my purposes. I kinda worked, sometimes at least. Unfortunately due to the nature of how the code was written, i had no idea what it was doing and just scrapped all of that.
Researched the topic a lot, too. But due to me not really understanding the language people speak when talking about line/plane intersections, i could have read the answer without recognizing it as such.
Question:
I'm stuck at line intersections. No idea where to go and how it works logically! So, where do i go from here and how can one comprehend all of this?
Note:
I did tag this issue as "java", but i'm not looking for spoon-fed code. It's a logical issue i'm trying to get past. If explained well enough, i will make the code work with trial and error!
Say if your circle is a circle in the XY plane with its centre on (0,0,0) and radius 1. How would you solve that?
You would check the values of X and Y when Z is equal to zero. And X squared plus Y squared would be less than 1 (radius squared) if the line passes through the circle.
In other words, you could transform the 3D coordinates to a simpler reference frame. So I think you need to learn transformation of 3D coordinates, which is really not too hard to do. You need to rotate the 3D space around until the centre vector only has a Z component, and yaw and pitch are zero. And then offset the coordinates so the circle centre is in (0, 0, 0). Then apply the same transformation to the line. You could lastly scale by radius, but to be honest that is not so important since the circle math is easy.
I'm trying to fit two ellipses to what happens to be the top view / outline of a body. For simplicity let's use the following example:
As you can see, this simple body is made up of a long core (blue) and a head (red). In reality this outline would be in one color, I'm just using two colors for visualization purposes here.
I know how to fit a single ellipse to either parts of that outline, but I do not know how to do the fit to two ellipses, given the constraint that these two ellipses are actually connected. In this particular case the constraint is that the two ellipses will never part and that there can only be a certain angle between ellipse 1 and ellipse 2.
I'm grateful for any pointers that tell me how to write a function, so that after calling magic_fitting_function(body_outline) the program returns to me the coordinates of the two underlying ellipses:
EDIT1:
what is are the minimal requirements that could make solving this problem easier? E.g. if I were given one point, two points, etc, how would that possibly simplify the problem?
EDIT2:
I'm looking for a programming language independent solution.
EDIT3:
any hints on how to formulate the constraint of these two ellipses being located in a certain relationship to each other programmatically? E.g.: I know that the small ellipse will always be located at one end of the major axis of the big ellipse. Plus the small ellipse can only rotate by +- 90 degrees relative to the big ellipse.
I have never solved this problem, so I'm just throwing out a suggestion.
First, generate a bounding ellipse for the entire figure in order to determine what are the topmost and the bottommost points. (This step may not be necessary if you have a better way of finding these points.)
Next, detect the location of the "neck" by using a modified binary search. (Here I'm assuming that your bounding ellipse has a vertical orientation, as though the figure were standing up or standing on its head.) Generate two sets of bounding ellipses: one with an ellipse from the top of the figure to the 1/4 point of the figure (meaning if you draw a line through the bounding ellipse then the 1/4 point is between the top-left point and the middle) and with an ellipse from the 1/4 point to the bottom of the figure, and one with an ellipse from the top of the figure to the 3/4 point and with an ellipse from the 3/4 point to the bottom of the figure; the set of ellipses with the smaller total area is the one that is better encapsulating the head. Continue the search (e.g. next test an ellipse from the top to the 1/8 point / 7/8 point, and/or from the top to the 3/8 point / 5/8 point) until you've minimized the total bounding area of the set of ellipses; the point at which the ellipses meet is the neck. (No need to be too precise with this, it probably doesn't make much difference if you put the neck at the 34/256ths point or at the 35/256ths point.)
To detect the neck you may want to use bounding boxes instead of bounding ellipses.
Finally, adjust the two bounding ellipses in order to meet their angle constraints, e.g. by moving their extreme points in 5% increments (so assuming that the head ellipse's extreme points are on the y-coordinates 0 and 50 and the body ellipse's extreme points are on the y-coordinates 50 and 200, adjust them so that their extreme y-coordinates are on 0 and 60 and on 40 and 200).
If you have the complete outline, you can find where the two ellipses intersect - just look for the two sharp corners where the first derivative of your outline becomes discontinuous. Then, draw a straight line between those corners.
Everything on one side of the line is in ellipse A, everything on the other side is in ellipse B. The sharp corners are in both ellipses. Now, just fit a single ellipse to each of the two ellipses you've found and recalculate the points where the fitted ellipses intersect.
You can try isolating ellipses using the Hough transform. There are some FEX tools out there that are worth trying, for example this Ellipse Detection Using 1D Hough Transform.
Find the two points that are furthest from each other. One will belong to Ellipse1, the other to Ellipse2.
Check the nearest neighbors of these points to get 5 points belonging to Ellipse1, and 5 to Ellipse2.
Check out Wikipedia, and choose your favorite equation of an ellipse.
Using junior high algebra, for each ellipse, plug in the points to get 5 simultaneous equations, and solve these to get the 5 parameters that define your ellipse.
EDIT
I didn't realize this was tagged "matlab". In that case, once you have identified some points for each ellipse, there are matlab functions for fitting the points to an ellipse.
I bring you a maybe complex question which i would love your help with. Allow me to go straight to the point:
I desire an algorithm or logic in which i draw a shape using my mouse (for example a square) and it becomes a perfect square, with all the 4 sides in straight lines and perfectly regular. A human-drawn square is hardly perfect, but i wish that after it goes through the "filter" of this algorithm ,it becomes such.
A fine example of what i wish is in the game Trine, where the Wizard works by a similar principle: You draw a shape in the screen and it becomes the closest shape, that is, if you draw something similar to a square it becomes a perfect square box, but if you draw a triangle it becomes a perfect triangular box. Its like it detects what kind of shape it is and then draws a better version of it.
I want this for a game, just so you know what is the goal of all this.
Please help me figure out either the algorithm or logic behind this, or at least tell me what is the name of this kind of action (:
P.S. i added a simple image so it becomes even more clear what i intend =)
If I had to implement this task, I would store the recognizable patterns, and would try to make a match for them.
Take the minX, maxX, minY, maxY values form the user-drawn points, that will help you to scale the pattern. Choose the scaling so that the aspect ratio for the pattern would be the average of the X and Y aspect ratios.
The patterns can consist of certain number of straight lines. The pattern matches if
There are no points outside of the threshold
There is at least one user-drawn point close to each key points in the pattern
If you have the pattern matched, you will have the key points for your pattern (calculating the center of your pattern, and the size/aspect ratio). Then you can replace the user-drawn points with your image - that may be totally different from the pattern used to match (imagine a circle).
There are many ways to do this. One way that you could do it is to create a neural net that recognizes these shapes. I would generate variations of circles, squares, lines, and triangles with random perturbations to replicate "hand-drawn" versions. Then you would want to represent this as a two-dimensional array (where locations that have been drawn on would be 1's and locations that haven't been drawn on, would contain 0's). You can then convert this two-dimensional array into an input vector of n x n elements. The output of the neural net would be a vector with four elements, each one representing either a line, circle, square, or triangle. You would then train this neural net using your randomly-perturbed images until you end up with a neural net that recognizes the input with an error that is under some error-threshold. This is actually quite similar to recognizing handwritten digits.
Other ways include:
Shape contexts.
k-means clustering
Support vector machines
You don't have just an arbitrary shape, you also have the shape's path. So try counting corners. Decide on a angle threshold that will represent a corner. For each point, sample the next consecutive x number of points. Measure the angle between the first half and second half. If the angle surpasses your threshold, consider it a corner. (Obviously select the point that give you the best angle with the least amount of error, not just the first one that surpasses the threshold.) Mark the location of the corners and draw your shape to match.
Ellipses & lines: if no angles are detected, sample a few segments. Measure the orientation. If they are very similar, then line. If very different, then ellipse. If ellipse, find the bounding box and draw inside.
Problem: Given a list of spheres, find all empty spaces that are completely enclosed by spheres.
Detail: This is a problem I am working on in which I try to determine the cavities located in a protein. I am given a list of atoms that make up the protein ((x,y,z) coordinates and radius). I then run my algorithm to find all empty spaces that lie within the bounds of the protein by checking if a probe (of given radius) can be placed at a location without colliding with other spheres. There are two types of empty spaces, void spaces and cavities. Void spaces are spaces that can lead to or on the outside of the protein. Cavities are empty spaces that are completely enclosed by protein atoms. Here is an image of the sample "protein" we are working with.
It can be viewed in three dimensions here.
There is a cavity located near the center of the protein, the tunnel you see going through the protein would be considered a void space because it is not fully enclosed by atoms.
Example: Given a list of 26 atoms, these atoms are evenly spaced from (0,0,0) to (1,1,1) in a 3-dimensional grid. Each atom has a radius of 0.25 and is placed on either 0, 0.5, or 1 on any axis. There is no atom at the point (0.5, 0.5, 0.5). If we were to draw a 3D figure of these atoms, it would be a cube like shape with the center missing. A cavity would be designated at (0.5,0.5,0.5) with a radius of 0.25. It can be assumed that this cavity is surrounded by proteins on all sides.
Example image:
Note that the above is only a 2D representation of the cube and protein. It is actually 3D.
How would one go about determining void spaces vs. cavities for a much larger and irregularly shaped group of atoms?
I was thinking about implementing a recursive algorithm that checks every direction to see if it can reach the maximum and minimum bounds of the graph but I am not sure if this is the correct way to go about doing it.
Extra: Is there a different algorithm that would say the cavity in the example is actually a void space because there are very small "paths" to reach the outside of the protein? A cavity would have to be completely enclosed by atoms to exist. Any void spaces that have a path (in any direction, not necessarily straight) to the outside of the protein would not be considered cavities.
Cool question. Here's an algorithm that should do the trick:
Notation:
Let's call our moveable sphere S.
Write diam(X) for the diameter of a sphere X
Write dist(X,Y) for the distance from X to Y; this is the same as the distance from the center of X to the center of Y minus the sum of the radii.
The algorithm:
For any two unmoveable spheres A and B, check whether S can pass directly between the centers of A and B (i.e. is diam(S) <= dist(A,B)?).
If so, for each other sphere C, check whether S could simultaneously touch all three spheres A, B, and C, if there were no other spheres present. If S could simultaneously touch all 3, draw a triangle between the centers of A, B, and C.
This can be checked in several ways. One fairly easy way: the possible positions of the center of S while touching both A and B form a circle. You want to know whether this circle has a point on it which is less than diam(S) + diam(C) away from the center of C. This is easy geometry.
The problem now reduces to the question: do the triangles separate the initial position of the center of S from infinity? You can answer this one connected component at a time. In fact, you can even answer this one "edge-connected" component at a time, where a component is edge-connected if any two non-vertex points can be linked by a path that doesn't pass through any vertices. You can calculate these components through a simple graph search.
For a given edge-connected component, you need to decide whether the component separates the center of S from infinity. There are a few ways you might do this:
Calculate the 2-homology of the component, choose effective generators, and for each, ask whether your point and infinity are on the same side of the cycle or not, which can be checked using the orientation class.
Or, just start painting the component:
Start with a triangle that you can reach from S, and paint every face that can be reached from there. This is slightly subtle, but the algorithm is just "start anywhere, queue up the edges, cross each edge onto the face forming the smallest angle with that edge, and stop when there are no edges left." Keep in mind that the opposite side of the same triangle might be the face forming the smallest angle.
Do the same from infinity. Did you cross any painted triangles? If yes, your sphere can escape. If no, it can't.
Why it works
Step 3 is true because if you don't hit any sphere C while "rolling around" the edge between A and B, then you can reach any side of that edge. Put another way, any position that stops you from going to infinity must involve S touching at least 3 spheres.
Note that there are some subtleties that arise from "exceptional" situations, like when S touches 4 spheres at once. You can avoid these subtleties by re-triangulating your shape before performing steps 3 and 4.
I want to make a game where the character is a rectangular prism that can be rotated, and the rest of the map are axis-aligned rectangular prisms. Everything other than the character will be static, so I was wondering what would be the best algorithm for finding if the character is colliding with any parts in the map. Any tutorials/code/advice would be much appreciated :)
Also, the character will only be rotated on the Y axis, if that helps.
In the special case that the character only rotates around its axis parallel to the Y-axis, the collision detection with another axis-aligned rectangular prism reduces to:
Check if the character's Y-interval intersects the other prism's Y-interval.
Check if the corresponding XZ-cross-sections of the two prisms intersect, which amounts to a problem of collision detection between two rotated rectangles.
If the answer to both the above is yes, then and only then do the prisms overlap.
Having reduced the particular problem to that of overlapping intervals and intersecting (rotated) rectangles, there are a number of good code resources for each of these tasks. The first task is pretty trivial:
Overlapping intervals
Two closed intervals [a,b] and [c,d] intersect if and only c ≤ b and a ≤ d. Here we also assume the intervals' notation is consistent, i.e. that a ≤ b and c ≤ d (otherwise swap the endpoints as necessary to make it so).
Intersecting rotated rectangles
A highly rated SO answer to this specific question is here. A Lua implementation I wrote for a slightly more general problem, Shortest distance between two rectangles, includes "early exit" optimizations (bounding circle and vertex in rectangle) that I mentioned on this thread. My Lua code returns "false" if the rotated rectangles intersect, otherwise the distance between them. For Java purposes the return value of zero in the collision cases would serve.
I believe one way to test for this is to check the 16 cases of line intersections:
http://www.math.niu.edu/~rusin/known-math/95/line_segs
If you want to optimize you could also check if the rectangles have no chance of overlapping, i.e. if all corners are to the right/left/above/below of the other rectangle.
Edit:
Se comment below.