Check if one line contains a part of the other - algorithm

Given two horizontal lines on a 1 dimension plane. I want to check if they overlap at any point.
Below I show some examples of overlap. Please note that, intervals like [1,2] and [2,3] have borders "touching" but they don't overlap each other.
[1,2] is basically a line going from 1 on the x axis, to 2 on the x axis.
My question is, what are the exhaustive set of checks for such a condition. These are the ones I came up with, assuming that the first line is called, a, and the second line is called b.
b.s <= a.s && b.e > a.s
b.s <= a.s && b.e >= a.e
b.s < a.e && b.e >= a.e
b.s > a.s && b.e < a.s
Is it really this complicated? Isn't there an easier way to figure out if two lines overlap/one line contains a part of the other?
Aliter
By looking at the negation condition
public boolean isOverlap(Interval i1, Interval i2)
{
// if(i2.start <= i1.start && i2.end > i1.start)
// return true;
//
// if(i2.start <= i1.start && i2.end >= i1.end)
// return true;
//
// if(i2.start < i1.end && i2.end >= i1.end)
// return true;
//
// if(i2.start >= i1.start && i2.end <= i1.end)
// return true;
//
// return false;
if(i2.start <= i1.start && i2.end <= i1.start)
return false;
if(i2.start >= i1.end && i2.end >= i1.end)
return false;
return true;
}

An alternative method is to consider them on the same axis and check for disconnectedness.
Then you can say "what is the left most point?"
I'll use .l for "left" and .r for "right."
leftmost = a.l < b.l ? a : b
rightmost = leftmost == a ? b : a
Now you know the left most one and the right most one. In order for them to be connected the right most one must have a left part in between the the left and right of the leftmost one.
Assuming every line must have at least length 1 then you can simply do:
connected = rightmost.l < leftmost.r

Related

Best practice to evaluate permutations

I came across this question, where the OP wanted to improve the following if-block. I open this as a new question because I'm searching a more general solution to this kind of problem.
public int fightMath(int one, int two) {
if(one == 0 && two == 0) { result = 0; }
else if(one == 0 && two == 1) { result = 0; }
else if(one == 0 && two == 2) { result = 1; }
else if(one == 0 && two == 3) { result = 2; }
else if(one == 1 && two == 0) { result = 0; }
else if(one == 1 && two == 1) { result = 0; }
else if(one == 1 && two == 2) { result = 2; }
else if(one == 1 && two == 3) { result = 1; }
else if(one == 2 && two == 0) { result = 2; }
else if(one == 2 && two == 1) { result = 1; }
else if(one == 2 && two == 2) { result = 3; }
else if(one == 2 && two == 3) { result = 3; }
else if(one == 3 && two == 0) { result = 2; }
else if(one == 3 && two == 1) { result = 1; }
else if(one == 3 && two == 2) { result = 3; }
else if(one == 3 && two == 3) { result = 3; }
return result;
}
Now there are n^k possibilities to get a result, where n = 2 and k = 4.
Some answers are suggesting to use an multi-array as a table to reduce the if-jungle.
But I would like to know how to solve such a problem with big n and k? Because a solution with if, switch and the suggested array approach will not scale well and to type things like that in code should be avoided.
If I think about combinatoric problems, there have to be a way to evaluate them easy.
It's just a table of data. The answer to the question is found by multiple keys. It is no different to returning some data held in a database table which could itself be huge and perhaps span multiple tables.
There are two ways to solve this:
Data-based. For example you could create a HashMap mapping the pair of values to the result.
class Pair {
int one, two;
//Generate hashcode and equals
}
Map<Pair, Integer> counts = new HashMap<>();
Pattern-based. Identify a rule/formula that can be used to determine the new value.
This is obviously better but relies on being able to identify a rule that covers all cases.
I would like to know how to solve such a problem with big n and k.
Since the output is determined arbitrarily (a game designer's whims) instead of mathematically (a formula), there's no guarantee of any pattern. Therefore the only general solution is some kind of lookup table.
Essentially, the question is similar to asking for a program that does f(a,b) -> c mapping, but you don't know any of the data beforehand -- instead it's provided at runtime. That program could process the data and find a pattern/formula (which might not exist) or it could build a lookup table.
Personally, I think it's clearer to change the logic to operate on intent (so reading the code explains how the attack works) instead of the actual outcomes (enumerating the list of inputs and matching outputs). Instead of building an if-jungle or a lookup table, structure your code based on how you want the logic to work. JAB's enum-based solution expresses the fight logic explicitly which makes it easier to see where to add new functionality and easier to see bugs (an off by one error in a lookup table isn't obviously wrong on inspection). A lookup table is a likely optimization, but that's only necessary if a profiler says so.
Looking at your question and the original one there appears to be no deducible pattern between the input from the two players and the output (perhaps I'm wrong). Given this the only options are the "if-jungle" you mention or to use a data structure.
To solve such a problem for big n and k values my suggestion would be to create a rule to determine the output (either none, one or both players hit), but ensuring that this rule isn't easily deducible to the players. You could do this by making the rule a function of turn number (e.g. if both players press button 1 on turn #1 the output will be different to if they take the same action on turn #2).

Simple collsion not working to the left or top

This should be a very easy question, basically I have two squares, and I'm trying to see if they overlap. So far I've figured out the right and bottom collisions, but I can't figure out collisions from the left and top. Here's my code:
if (e.getX() >= player.getX() && e.getX() <= player.getX() + Entity.SIZE && e.getY() >= player.getY() && e.getY() <= player.getY() + Entity.SIZE) {
return true;
Let e be the entity that I'm checking and Entity.SIZE be the size for both the squares. What am I doing wrong?
I would suggest just making the player and every entity have a bounding rectangle using java's Rectangle class. You can do easy operations like:
if(e.boundingBox.intersects(player.boundingBox)){...}
where each entity has something like:
private Rectangle boundingBox;
Silly me, I forgot to check for the size on the x and y axis when above or next to a rectangle. Here's the new code:
e.getX() + Entity.SIZE >= player.getX() && e.getX() <= player.getX() + Entity.SIZE && e.getY() + Entity.SIZE >= player.getY() && e.getY() <= player.getY() + Entity.SIZE

Trouble implementing North-East Paths with recursion

I'm supposed to use recursion to output the total number of unique north-east paths ne(x, y) to get from point A to point B, where B is x rows north and y columns east of A. In addition, I am required to print the possible unique NE paths.
I know how to use recursion to get the total number of unique paths. However, I am stuck with using recursion to print all the NE paths correctly.
This is the given output of some test cases:
image of output
Anyway, here's a screenshot of my faulty recursive code.
Please do give me advice where I went wrong. I have been burning a lot of time on this, but still I can't reach a solution.
I think you should print if( rows == 0 && cols == 0 ), because it's the case when you've reached point B.
Why are you using path+="N" in the first ne call in return? this will add "N" to original path and then you'll get path+"N"+"E" in the second call.
Try following:
public static int ne( int rows, int cols, String path )
{
if( rows == 0 && cols == 0 )
{
System.out.println(path);
return 1;
}
int npats = 0, wpaths = 0;
if( rows != 0 )
npaths = ne( rows-1, cols, path+"N" );
if( cols != 0 )
wpaths = ne( rows, cols-1, path+"E" );
return npaths + wpaths;
}

How to detect if a certain range resides (partly) within an other range?

Lets say I've got two squares and I know their positions, a red and blue square:
redTopX;
redTopY;
redBotX;
redBotY;
blueTopX;
blueTopY;
blueBotX;
blueBotY;
Now, I want to check if square blue resides (partly) within (or around) square red. This can happen in a lot of situations, as you can see in this image I created to illustrate my situation better:
alt text http://www.feedpostal.com/etc/ranges.gif
Note that there's always only one blue and one red square, I just added multiple so I didn't have to redraw 18 times.
My original logic was simple, I'd check all corners of square blue and see if any of them are inside square red:
if (
((redTopX >= blueTopX) && (redTopY >= blueTopY) && (redTopX <= blueBotX) && (redTopY <= blueBotY)) || //top left
((redBotX >= blueTopX) && (redTopY >= blueTopY) && (redBotX <= blueBotX) && (redTopY <= blueBotY)) || //top right
((redTopX >= blueTopX) && (redBotY >= blueTopY) && (redTopX <= blueBotX) && (redBotY <= blueBotY)) || //bottom left
((redBotX >= blueTopX) && (redBotY >= blueTopY) && (redBotX <= blueBotX) && (redBotY <= blueBotY)) //bottom right
) {
//blue resides in red
}
Unfortunately, there are a couple of flaws in this logic. For example, what if red surrounds blue (like in situation 1)?
I thought this would be pretty easy but am having trouble coming up with a good way of covering all these situations.. can anyone help me out here?
Regards,
Tom
A test that checks whether red rectangle resides completely outside the blue rectangle looks as follows
bool outside =
redBotX > blueTopX || redTopX < blueBotX ||
redBotY > blueTopY || redTopY < blueBotY;
Now, the negative of that will tell you whether red rectangle intersects the blue rectangle
bool intersects =
!(redBotX > blueTopX || redTopX < blueBotX ||
redBotY > blueTopY || redTopY < blueBotY);
If you wish, you can apply the De Morgan rule and rewrite it as
bool intersects =
redBotX <= blueTopX && redTopX >= blueBotX &&
redBotY <= blueTopY && redTopY >= blueBotY;
Of course, the above tests assume that the coordinates are "normalized*, i.e.
assert(redBotX <= redTopX && redBotY <= redTopY);
assert(blueBotX <= blueTopX && blueBotY <= blueTopY);
Also, the comparisons might be strict or non-strict depending on whether you consider touching rectangles as intersecting or not.
EDIT: I see that you use a different convention for rectangle coordinates: Top is the lower coordinate and Bot is the higher one, i.e.
assert(redTopX <= redBotX && redTopY <= redBotY);
assert(blueTopX <= blueBotX && blueTopY <= blueBotY);
To handle this case you just need to swap the Bot and Top coordinates in all conditions. For example, the last one will now look as follows
bool intersects =
redTopX <= blueBotX && redBotX >= blueTopX &&
redTopY <= blueBotY && redBotY >= blueTopY;
Assuming both squares are aligned, as you've indicated:
The squares intersect if all of the following hold:
The left side of Red is left of the right side of Blue.
The right side of Red is right of the left side of Blue.
The top of Red is above the bottom of Blue.
The bottom of Red is below the top of Blue.
(Convince yourself that this is true!)
One formula for intersection of two rectangles would be
! ( (redTopX > blueBotX) || (blueTopX > redBotX) || (redTopY < blueBotY) || (blueTopY < redBotY))
You can use DeMorgan's Theorem to simplify.
if (blueTopY < redBotY) return (0);
if (blueBotY > redTopY) return (0);
if (blueBotX < redTopX) return (0);
if (blueTopX > redBotX) return (0);
return (1); // there must clash
for each blue corner:
if corner is between all four red sides:
return true
return false
For higher-dimensional ranges or if you want to check a lot of ranges it might be worthwhile to store your ranges (e.g. their centers) in a R tree and search for it for where the corners of your range are.

Determining valid adjacent cells of a square stored as an array

I have an array (of 9 elements, say) which I must treat as a (3 by 3) square.
For the sake of simplifying the question, this is a one-based array (ie, indexing starts at 1 instead of 0).
My goal is to determine valid adjacent squares relative to a starting point.
In other words, how it's stored in memory: 1 2 3 4 5 6 7 8 9
How I'm treating it:
7 8 9
4 5 6
1 2 3
I already know how to move up and down and test for going out of bounds (1 >= current_index <= 9)
edit: I know the above test is overly general but it's simple and works.
//row_size = 3, row_step is -1, 0 or 1 depending on if we're going left,
//staying put or going right respectively.
current_index += (row_size * row_step);
How do I test for an out of bounds condition when going left or right? Conceptually I know it involves determining if 3 (for example) is on the same row as 4 (or if 10 is even within the same square as 9, as an alternate example, given that multiple squares are in the same array back to back), but I can't figure out how to determine that. I imagine there's a modulo in there somewhere, but where?
Thanks very much,
Geoff
Addendum:
Here's the resulting code, altered for use with a zero-based array (I cleaned up the offset code present in the project) which walks adjacent squares.
bool IsSameSquare(int index0, int index1, int square_size) {
//Assert for square_size != 0 here
return (!((index0 < 0) || (index1 < 0))
&& ((index0 < square_size) && (index1 < square_size)))
&& (index0 / square_size == index1 / square_size);
}
bool IsSameRow(int index0, int index1, int row_size) {
//Assert for row_size != 0 here
return IsSameSquare(index0, index1, row_size * row_size)
&& (index0 / row_size == index1 / row_size);
}
bool IsSameColumn(int index0, int index1, int row_size) {
//Assert for row_size != 0 here
return IsSameSquare(index0, index1, row_size * row_size)
&& (index0 % row_size == index1 % row_size);
}
//for all possible adjacent positions
for (int row_step = -1; row_step < 2; ++row_step) {
//move up, down or stay put.
int row_adjusted_position = original_position + (row_size * row_step);
if (!IsSameSquare(original_position, row_adjusted_position, square_size)) {
continue;
}
for (int column_step = -1; column_step < 2; ++column_step) {
if ((row_step == 0) & (column_step == 0)) { continue; }
//hold on to the position that has had its' row position adjusted.
int new_position = row_adjusted_position;
if (column_step != 0) {
//move left or right
int column_adjusted_position = new_position + column_step;
//if we've gone out of bounds again for the column.
if (IsSameRow(column_adjusted_position, new_position, row_size)) {
new_position = column_adjusted_position;
} else {
continue;
}
} //if (column_step != 0)
//if we get here we know it's safe, do something with new_position
//...
} //for each column_step
} //for each row_step
This is easier if you used 0-based indexing. These rules work if you subtract 1 from all your indexes:
Two indexes are in the same square if (a/9) == (b/9) and a >= 0 and b >= 0.
Two indexes are in the same row if they are in the same square and (a/3) == (b/3).
Two indexes are in the same column if they are in the same square and (a%3) == (b%3).
There are several way to do this, I'm choosing a weird one just for fun. Use modulus.
Ase your rows are size 3 just use modulus of 3 and two simple rules.
If currPos mod 3 = 0 and (currPos+move) mod 3 = 1 then invalid
If currPos mod 3 = 1 and (currPos+move) mod 3 = 0 then invalid
this check for you jumping two a new row, you could also do one rule like this
if (currPos mod 3)-((currPos+move) mod 3)> 1 then invalid
Cheers
You should be using a multidimensional array for this.
If your array class doesn't support multidimensional stuff, you should write up a quick wrapper that does.

Resources