ADDED INFO:
I'm using the inside of a square as an arena. On start up, the square spawns in a random position, and rotation, and I can't access any of the squares attributes.
I then have a moving object inside the square, that I'm building AI for, and I want the object to 'learn' where the arena walls are. Every time the object bumps into a wall, I get a touch return, so I know if its hit or not. I'm using this to map the global position of where the object hit the wall and save it ... After 3 hits on the same wall, I want to mathematically 'draw a straight line' down those dots which will represent the arena walls - with this, I can tell my object not to go near these coordinates.
The reason for 3 dots? Well, if the object hit one side of a wall, then was to hit another side of a wall, I will have a line drawn from one side to another, giving false data about where the wall is.
If Java sees three (or more) dots inline, it knows that the object has hit the same wall (either being further up or so).
CONTINUED:
I'm trying to map out lines with given coordinate data. Basically I have an array that holds X and Y coordinates, and I want to be able to mathematically detect if it's they make up a straight line (give or take a few pixels). (The coordinate are a boarder of a square)
For example, the array might be like this:
[x0][y0] - 1,1
[x1][y1] - 2,2
[x2][y2] - 5,5
Which will present a diagonal line of on side of the square, like so:
But sometimes I might get one coordinate of one side of the square, and then another side, all mixed up (and not necessarily on a 90 degree angle either!). So I want to be able to run through the array, and detect what coordinates make a line (or the boarder side of the square), like so:
So right now, I have a 2D array:
private double wallLocations[][] = new double[10][10];
and a while loop that doesn't do the job. I don't really know where to even start with this one:
for(int r = 0; r < wallIndex; r++){
for(int c = 0; c < wallIndex; c++){
int index = 0;
if(wallLocations[r][index] == wallLocations[r][c] && wallLocations[r][index + 1] == wallLocations[r][c] &&
wallLocations[r][index + 2] == wallLocations[r][c]){
System.out.println("***** Wall Here! *****");
index++;
}
}
}
---- UPDATE ----
Heres a better example in what I'm looking for. The red dots represent the coordinates coming in, a line is detected when 3 or more dots line up (if it was 2 dots, then it would detect any and ever dot) ... You notice that this is starting to look like the boarder of a square?
This seems to essentially be a clustering problem, and those can be generally pretty hard. Part of a reason clustering is hard is that there may be more than one applicable mapping.
For instance (please forgive my bad ascii art):
X X X
X X X
X X X X
could be mapped
X---X---X X X X
\ / \ / \
X---X---X or X X X
/ \ / \ \
X---X---X---X X X X X
I've seen uses of the Expectation Maximization algorithm using mixed Gaussian models used for this kind of thing (when there were a lot of points but only a few expected lines) but you generally do have to give that algorithm a definite number of clusters, and while its results are good, it's a pretty slow algorithm requiring possibly many iterations. I'm kinda thinking I've seen something generally faster that's some sort of image processing algorithm but I'd have to do some research.
I'm kinda wondering about something where you find y=mx+b for every pair of points and them sort them over m and b. It might be advantageous to find the angle θ in [0,pi) for each pair instead and sort over the angles instead of m, or maybe beter cluster by cos(2θ)-- the point of that being that the group of lines {y= -0.0001x + 1, y =1, and y=0.0001x + 1} are very similar, the group of lines {y= -10000x + 10, x = 0, and y=10000x - 10} are also very similar, but cos(2θ) should put them as far apart as possible, as any two pairs between each group should be nearly perpendicular.
Also note, in my example, b doesn't matter much for the lines nearly perpendicular to the x axis, so "b" might not be so useful for direct clustering.
I guess, perhaps, there may be some utilizable measure of "distance" between two lines, I'm just not sure what it would be. Two lines that are nearly parallel that converge "on screen" (where the points generally are) might ought to be considered "closer" than if they converge a trillion units a way from the screen--or should they? Purely speaking, three lines can never pairwise be considered closer to one another if none of them are parallel (If they're on a plane, they'll all meet somewhere), but intuitively, if we have two lines that are generally one inch apart in the area we're concerned with, we'd pick that pair as closer over two identically pointed lines that are a mile apart in the area of concern. That makes me think maybe the area between the lines,as bound by our area* ought to be used as a metric.
Sorry, I'm not sure how useful all that brainstorming might be, but it might put a different light on things.
Edit: You know what, a better answer might possibly be found by researching this:
http://en.wikipedia.org/wiki/Hough_transform
Edit II & III:
Ok,... the situation you've just described is a lot simpler and less generic (although, to be honest, I think I misread your initial query to be more generic than it really was).
You've got 4 candidate walls. Let your AI bounce around until it finds three co-linear points. That should be a simple test of combinations. Assign those three points a wall. Depending upon what other points you have, you actually might be able to determine or at least estimate the other three walls (assuming it is a square). If you have 5 points with 3 on separate walls, you should be able to calculate the distance between walls, and therefore the likely position of the 4th wall. To test if the other two points are on separate walls, make sure they're pair-wise not co-linear with a line perpendicular or parallel to the line defined by your wall, or if they are on a line parallel, test to see if the distance between them is less than the distance between the wall and them (if that's the case, they're on the wall opposite of the first candidate wall). Given that they are on separate walls, either one is facing the first found wall, or they're on walls perpendicular to that wall. Either way you can find the lines defining the walls with a little tricky geometry.
(and actually, to determine the dimensions, I don't think you need to even test to see that you have 3 co-linear points... I think you just need to test to see that you've made two turns... which takes 4 points minimum but likely more if you're unlucky. two of the points would have to be determinable to be on a different wall from the other two, which means really big bounces!)
There's a bit of math involved, and I'm a bit too tired to explain further tonight, and I don't know how much of the geometry of points around a square you want to take advantage of, because you wouldn't be able to use those properties in a more general case, so I'll leave it at that, and maybe also remove some of my other previous brainstorm cruft later.
If you have two points you can calculate the slope of the connecting line with Math.atan2.
Related
I was presented with the following Backtracking/Seating problem:
Assume you have a room of size k * k, meaning you have exactly k * k seats available and an n amount of people you have to seat. Furthermore, every person has their own specific radius in which they really don't want anyone else to sit in.
The assignment is to write an algorithm in pseudocode or pure text form to find any seating plan (not necessarily perfectly optimal) through backtracking in which every person is not within someone else's radius or indicate that such a seating plan is not possible. Note that the time complexity of the algorithm is not of importance.
To further illustrate this, assume we are given k = 8, meaing we have a total of 8x8 seats. For people n=3 we have Red with a radius of 3, Blue with a radius of 2 and Yellow with a radius of 1.
In the following picture we have an example of an invalid seating plan, because Blue is clearly within Red's radius. One of the many possible valid seating plans for this would be Red at seat (0,0), Blue at seat (4,0) and Yellow at seat (7,0).
Where I'm stuck:
My attempt/pseudocode assumes that an array of n people is an array of radii, sorted by their size in descending order.
We then iterate over the x and y coordinates in respective for loops. We place the largest Element at (0,0) and then pick the next element/radius and check if we can place it in the next (x,y). If person 1 is within person 2's radius or vice-versa, the position is invalid and we move on to the next (x,y). If the position is valid, we move on to the next element/radius and repeat that process until we exhausted all radii/people in n.
Even though this might even work in actual code, I fail to understand how I should implement the required backtracking aspect of my pseudocode. I do believe I understand the basics of how backtracking works but I just can't seem to figure out how I can implement that process into this problem.
I've been working on a project and I need to be able to return a point in a square that acts kind of like a bulls-eye. I wanted to make it return a point that would follow a Gaussian distribution, meaning after a lot of generated results we would see the majority of the points generated near the center and the number would diminish as it goes towards the outer limits of the square. What would be the best way to go about this?
I have a method as seen here:
public static Point randomPoint(final Random random, final Point center,
final double sd) {
Point p = null;
return p;
}
But I am really stuck on where to go from here. With general numbers, a random gaussian number would just use a min and a max with a mean and standard deviation. would I do something similar here but do the min and max for both x and y?
To generate a symmetric 2d Gaussian distribution, you actually only have to generate 2 separate Gaussian numbers and take them as x and y, like this:
new Point(center.getX()+random.nextGaussian()*sd,
center.getY()+random.nextGaussian()*sd);
Note however that mean (the center) and deviation (I assume 'sd' in your example) does not equal min/max. It basically means that roughly 2/3 of all points will be less then 'sd' far from the center, roughly 95% will be at most '2*sd' far. However there is a non-zero probability for all points, however far.
This means, you might want to 'crop' the points to the rectangle of your interest. Note however, there are two approaches to do this:
If a point is outside the rectangle just put it on the border (aka. do min/max checking and take min/max if it's out of bounds)
Repeat the generation if point is outside of bounds
The first one will potentially deform your distribution, as it will be more likely that a point is on exactly the border than it should be. The second one costs a bit more processing, however it will preserve the distribution.
I’m trying to work out a math / geometry problem in a Java project I’m working.
Here is the scenario:
There are two sets of blocks, each with a different number of blocks and different dimensions. In this example Set A has 5 blocks, each is 20x20 pixels; Set B has 6 blocks, and each is 25x50 pixels:
I’m trying to come up with a way to mathematically or logically determine how those sets would line up to maximize the contact between them. If you were to line these set up end-to-end it would look like this:
In this image, 4 of the blocks in set B are in contact with the blocks in set A. However, if you shift set A to the right a bit, you can get 5 of the blocks in set B to touch:
The problem is that the formula / algorithm / logic needs to be flexible enough to handle different combinations. In this example, set C has only 3 blocks, and each block is 40x40:
Any ideas?
Center the two sets of blocks and shift one of them by a small amount.
Check the difference in total length between the two sets of blocks.
If the difference is less than the length of the smaller block, then just align the two sets of blocks on one edge; they all have contact with each other, so call it good.
Otherwise, move the smaller set of blocks sideways by almost the length of one member of the other set (i.e., length of larger block minus some tiny number), to maximize contact.
It will look a bit like this (where top blocks are width 5, and bottom blocks are width 3):
111112222233333444445555566666
--->111222333444555
If you're aiming for the simpler answer of "how many blocks are in contact?", then the computation is simpler. The shorter set of blocks always has contact with the longer set of blocks. The longer set of blocks is in contact with this many blocks in the shorter set if the edges are exactly aligned:
(length of shorter set of blocks) / (length of a single member of longer block)
Add one if that's both less than the number of longer blocks, and if that fraction isn't an integer (to account for a tiny shift like I described earlier). Then round up.
It's a little difficult to come up with a good algorithm for this without understanding what the program is actually trying to do ... but ok, you want to 'maximise' the contact between two lists of blocks (or are they really sets?).
One thing that occurs to me here is that the best alignment will have at least one of the separators between blocks aligned. So you could just keep the longer list fixed, and shift the shorter one along, stepping by separator alignment.
Let a_total and b_total be the total widths of the collections of blocks. Let a_single and b_single be the width of one of the blocks. We can assume a_total <= b_total (otherwise swap).
If the rows of blocks are aligned at their left edges, A is in contact with ceiling(a_total/b_single) blocks from B. That number can be increased by at most one by shifting the starting point of A to the right. The number is at most one because the situation is periodic for large B (imagine an infinitely long B, for example): shifting A by exactly b_single results in a configuration exactly the same as the starting configuration, so another B block has been added to the end.
The trick now is to see whether we can add a B block to the end by shifting the A collection, while not removing the B block at the beginning.
We can add a B block at the end only if B is long enough; the exact condition is a_total <= b_total - b_single.
We can avoid removing a B block from the beginning if we can shift the A collection by less than b_single in order for the right edge of the A collection to pass a B block boundary, in other words if and only if ceiling(a_total/b_single)*b_single - a_total < b_single, i.e., ceiling(a_total/b_single) < (a_total + b_single)/b_single, i.e., ceiling(a_total/b_single) < a_total/b_single + 1. The latter inequality is always true.
In summary, the number of blocks in contact is maximized at ceiling(a_total/b_total) + 1 if a_total <= b_total - b_single, and ceiling(a_total/b_total) otherwise (assuming, of course, that a_total <= b_total).
There is one further issue you need to consider: the above analysis holds when you can adjust the relative positions of the blocks by any real number. If you are restricted to one pixel adjustments, then you may get into further special cases if b_single = 1, for example.
I am making a strategy game in android with lots of units and I have come to a point where I need to check the position of every single object against every other one to see if the two are close enough together that they should start fighting. Right now the only way I can determine if two units are close enough is in this method:
public boolean inProximity(float x2, float y2) {
return Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)) <= proximityRadius;
}
I don't want to be iterating through all the units an n-squared amount of times. I was looking at a TreeMap to store the positions, but then how would I (if it's even possible) get the keys based of distance from a unit?
You might want to reconsider the data structure here and take a look at quadtrees. They essentially allow you to partition 2D space and do collision detections which seems to be your use case.
http://en.wikipedia.org/wiki/Quadtree
Just doing a google on java quadtree produces some hits on implementations. I haven't used any of them so I can't really vouch for them, but that should give you something to go on.
1) As a first thing to think about, you don't need to take the square root. The square and the square root both increase as the numbers increase, so that would be one optimization.
2) This is known as the 'Closest Pair' problem, and there are divide-and-conquer based algorithms to solve it.
Take a look at: http://en.wikipedia.org/wiki/Closest_pair_of_points_problem
I've written some basic graphing software in Clojure/Java using drawLine() on the graphics context of a modified JPanel. The plotting itself is working nicely, but I've come to an impasse while trying to converting a clicked pixel to the nearest data point.
I have a simple bijection between the list of all pixels that mark end points of my lines and my actual raw data. What I need is a surjection from all the pixels (say, 1200x600 px2) of my graph window to the pixels in my pixel list, giving me a trivial mapping from that to my actual data points.
e.g.
<x,y>(px) ----> <~x,~y>(pixel points) ----> <x,y>(data)
This is the situation as I'm imagining it now:
A pixel is clicked in the main graph window, and the MouseListener catches that event and gives me the <x,y> coordinates of the action.
That information is passed to a function that returns a predicate which determines whether or not a value passed to it is "good enough", and filter though the list with that pred, and take the first value it okays.
Possibly, instead of a predicate, it returns a function which is passed the list of the pixel-points, and returns a list of tuples (x index) which indicate how good the point is with the magnitude of x, and where that point is with index. I'd do this with both the x points and the y points. I then filter though that and find the one with the max x, and take that one to be the point which is most likely to be the one the user meant.
Are these reasonable solutions to this problem? It seems that the solution which involves confidence ratings (distance from pix-pt, perhaps) may be too processor heavy, and a bit memory heavy if I'm holding all the points in memory again. The other solution, using just the predicate, doesn't seem like it'd always be accurate.
This is a solved problem, as other graphing libraries have shown, but it's hard to find information about it other than in the source of some of these programs, and there's got to be a better way then to dig through the thousands of lines of Java to find this out.
I'm looking for better solutions, or just general pointers and advice on the ones I've offered, if possible.
So I'm guessing something like JFreeChart just wasn't cutting it for your app? If you haven't gone down that road yet, I'd suggest checking it out before attempting to roll your own.
Anyway, if you're looking for the nearest point to a mouse event, getting the point with the minimum Euclidean distance (if it's below some threshold) and presenting that will give the most predictable behavior for the user. The downside is that Euclidean distance is relatively slow for large data sets. You can use tricks like ignoring the square root or BSP trees to speed it up a bit. But if those optimizations are even necessary really depends on how many data points you're working with. Profile a somewhat naive solution in a typical case before going into optimization mode.
I think your approach is decent. This basically only requires one iteration through your data array, a little simple maths and no allocations at each step so should be very fast.
It's probably as good as you are going to get unless you start using some form of spatial partitioning scheme like a quadtree, which would only really make sense if your data array is very large.
Some Clojure code which may help:
(defn squared-distance [x y point]
(let [dx (- x (.x point))
dy (- y (.y point))]
(+ (* dx dx) (* dy dy))))
(defn closest
([x y points]
(let [v (first points)]
(closest x y (rest points) (squared-distance x y v) v)))
([x y points bestdist best]
(if (empty? points)
best
(let [v (first points)
dist (squared-distance x y v)]
(if (< dist bestdist)
(recur x y (rest points) dist v)
(recur x y (rest points) bestdist best))))))