If objects (x,y) are near other objects (x,y) - java

I have two separate objects in Java, Object1 and Object2, both are the same size and square. For each object I can get the x and y coordinates. What I need to do is check if Object1 is within a certain distance of Object2. That distance is within 32 points on both the X and Y axis.
once the condition has been met then I can run my code. e.g.
if ( check condition ) {
//my code here
}

Try the following:
if(Math.abs(Object1.x - Object2.x) <= 32 && Math.abs(Object1.y - Object2.y) <= 32)
{
// Do stuff
}

If these are rectangles and not points, you need to compensate for their width and height. Since they're squares, just use their width if you have it
if(Math.abs(Object1.X - Object2.X) <= 32 + Object1.Width && Math.abs(Object1.Y - Object2.Y) <= 32 + Object1.Width)
{
// my code here
}

Related

Catching ArrayIndexOutOfBoundsException in backward?

I creating pacman game. I have array of size 15x15, total 225fields. When I move from 255 to i.e.256, I got ArrayIndexOutOfBoundsException, this makes sense. So I can catch it and do some operation, lets say I set new starting point of pacman. But if I go from field 75 to 74 nothing happened.
So I asking, can I somehow catch this and do some operation, like I mention above.
You should not rely on ArrayIndexOutOfBoundsException for normal logic. This exception is an indication of a programming error.
Instead, you should check the index before incrementing it:
if (currentIndex == 255) {
// "special logic"
} else {
// "usual logic"
}
This way you can also handle any "special" indexes, e.g.
if ((currentIndex + 1) % 15 == 0) {
// "special logic"
} else {
// "usual logic"
}
Another point: consider using two indexes - x and y - if you are programming a 2-D game.
Every move modifies x and/or y, which can easily "wrap around" like in pacman (e.g. 13 -> 14 -> 15 -> 1 -> 2 -> ...).
And convert the (x,y)-Pair to an index only when you need to access the field element:
// Assuming that x and y are 1-based, not 0-based:
public FieldElement getFieldElementAtPosition(final int x, final int y) {
final int index = (y - 1) * FIELD_WIDTH + x - 1;
return fieldArray[index];
}

How to detect if coordinate is inside region?

I am trying to detect if a player is inside a specific region, I currently store a Region object that contains two variables that I'll be calling cornerOne and cornerTwo, the corners are basically vector variables that contains X, Y, Z, I save all the regions on a MutableSet.
I want to make sure that the new vector I am passing to it is inside the region.
Currently what I tried was:
fun isInRegion(location: Location): Boolean {
return regions.none { inside(location, it.cornerOne, it.cornerTwo) }
}
private fun inside(location: Location, cornerOne: Location, cornerTwo: Location): Boolean {
return (location.x >= cornerOne.x && location.x <= cornerTwo.x) &&
(location.z >= cornerOne.z && location.z <= cornerTwo.z)
}
I am ignoring Y because the region is only horizontal, so I'll be ignoring height.
The way I currently have it, works for the first 3 regions, but as soon as I make a 4th one it stops working completely, detects the first ones but doesn't the other ones.
Is there a better way to do this? I was told a quadtree could be better, but I don't understand how it would work in this situation.
PS: I am tagging Java too because if someone sees it in the Java section I won't mind a Java help either.
Edit:
On the region code I have if (!isValidRegion()) return which will prevent the region from being too small:
fun isValidRegion(): Boolean {
return !(getXSelected() < 5 || getZSelected() < 5)
}
This makes sure that cornerOne.x <= cornerTwo.x and cornerOne.z <= cornerTwo.z.
This is the method to get the selected X, it'll get the X of the final block and subtract from the X of the first block.
private fun getXSelected(): Int {
return abs(finalBlock.x - originBlock.x) + 1
}
Edit 2:
So I changed the inside function to be:
private fun inside(location: Location, cornerOne: Location, cornerTwo: Location): Boolean {
return inBetween(location.x, cornerOne.x, cornerTwo.x) &&
inBetween(location.z, cornerOne.z, cornerTwo.z)
}
private fun inBetween(a: Int, b: Int, c: Int): Boolean {
return (a in b..c) || (a in c..b)
}
And it worked, however I don't know if this would be a good solution, as I don't know if it would be bad for performance if it is called too often.
Change your code in one of two ways:
1) change the definition of inside to be (less preferred):
private fun inside(location: Location, cornerOne: Location, cornerTwo: Location): Boolean {
return (location.x >= Math.min(cornerOne.x, cornerTwo.x) && location.x <= Math.max(cornerOne.x, cornerTwo.x)) &&
(location.z >= Math.min(cornerOne.z, cornerTwo.z) && location.z <= Math.max(cornerOne.z, cornerTwo.z))
}
Or change the way you generate cornerOne and cornerTwo:
2.1) do without the `abs in your generation (you will need more iterations of generation)
2.2) after you generate the initial candidates of corners swap cornerOne xs if their order is not as expected and do the same on the z axis (separately!!)

Using math in solr if expressions

I am trying to use math in an 'if' statement in solr. What I want to achieve is following, I have a trapeze function defined as:
There are 4 points on the x axis, left_minimum, left_optimum, right_optimum, right_maximum.
For every value of the field I want to have following outcome:
value v
score s
maxscore
if (v<left_minimum)
s = 0;
if (v>right_maximum)
s = 0;
if (v>=left_optimum AND v<=right_optimum)
s = maxScore;
if (v>=left_minimum AND v<left_optimum)
s = maxScore * (v - left_minimum) / (left_optimum - left_minimum)
if (v>right_optimum AND v<=right_maximum )
s = maxScore * (v - right_optimum) / (right_maximum - right_optimum)
The basic idea is to rank results which are "near" the ideal result higher than the results that are too far away.
to achieve this I tried to split my calculation for height in three parts (maxscore is 1.0):
heightWM=product(1.0, map(height,160,170,1,0))
&heightWL=if(height < 160 AND height > 150, product(1.0, div(sub(height,160),10)), 0)
&heightWR=if(height < 180 AND height > 170, product(1.0, div(sub(height,170),10)), 0)
&heightW=sum(heightWL, heightWM, heightWR)
problem is that solr doesn't like if with mathematical expression. Or at least I haven't find how.
Is there any other possibility to achieve this?
Ok, I actually found a solution or, better, a workaround.
heightWL=if(map(height,160,169,1,0),div(sub(height,160),10),0)
so I am basically mapping all values between x and y in a > x and a < y to 1, and all other values to 0. This way if can actually check, since it can work with 1 and 0, and in that case I calculate the subvalue for this area.

Lines Intersect method not working correctly

I'm working on some vector math, and I need to calculate the normal vector of a polygon.
My code:
//p is a parameter, is a Vec2, second point on first line
double[][] vert = getVerticies(); //[any length, # of verticies][2]
for(int i = 0; i < vert.length; i++) {
Vec2 cm = Vec2.ZERO_VEC;//first point on first line, always is <0, 0> as it is the origin
Vec2 rcm = getCM(); // just used to get relative positions.
Vec2 v1 = cm.sub(new Vec2(vert[i])); //the first point in one of all edges of the shape, second line
Vec2 v2 = cm.sub(new Vec2(i == vert.length - 1 ? vert[0] : vert[i + 1])); // the second point on the second line.
double den = (v2.getY() - v1.getY()) * (p.getX() - cm.getX()) - (v2.getX() - v1.getX()) * (p.getY() - cm.getY());
if(den == 0D) {
continue;
}
double a = ((v2.getX() - v1.getX()) * (cm.getY() - v1.getY()) - (v2.getY() - v1.getY()) * (cm.getX() - v1.getX())) / den;
double b = ((p.getX() - cm.getX()) * (cm.getY() - v1.getY()) - (p.getY() - cm.getY()) * (cm.getX() - v1.getX())) / den;
if(a >= 0D && a <= 1D && b >= 0D && b <= 1D) {
Vec2 mid = v2.add(v2.sub(v1).scale(0.5D)); //this is just normal vector calculation stuff, I know the error isn't here, as if it was, it would return a non-unit-scale vector.
return mid.uscale(); //hats the vector, returns
}
}
return p; // return the parameter, second point on first line, used as a contingency, should never actually run, as the first line is fully contained in the lines were testing against
I've done some debugging, and I just don't see what's happening. Can anyone tell me what's wrong with my math? It just seems to flow absolutely fine, but the math just doesn't seem right. My goal with this code is to determine the index of the two verticies that my line intersects.
Oops, figured it out by virtue of attempted to explain it. I need to be ray tracing, or use ray intersection testing.
If you are trying to calculate the normal of a polygon, it looks like you are trying to do something overly complicated. You can simply use cross product of two adjacent edges to get it. Even better, with a simple math explained here, you don't even need to calculate the edge vectors. Just take the cross product of each adjacent vertex pair and sum them up:

Efficiency problem

i am trying to make my algorithm more efficient but for some reason its not working correctly could someone tell me if my logic is correct. The general problem is that if u have a height of 'x', and you can jump 'u' distance but you fall 'd' distance if you havent cleared the height already. i have to calculate the number of jumps.
Initial code works correctly
while(x-u>0) {
x=x-u+d;
i++;
}
i++;
more efficient code (for some reason fails some cases, I don't know which cases though)
int k=u-d;
if(x-u<=0){
i++;
} else {
int z=x/k;
if (x-((z-1)*k)-u <= 0) {
i+=z;
} else {
i=i+z+1;
}
}
let me try and clarify the problem you have a wall of height X, you can jump up distance U but every time you jump you also slip down distance D.
so lets say if u have a wall of height x=4, u=4, d=1. Then you would only have to jump once because the first time you jump you have cleared the wall, so you dont slip down at all. now lets say x=6, u=4,d=1. Then you would have to jump twice because the first time you would jump up to 4 but fall 1 so you are at 3 then the next jump you clear the wall.
Okay, let's see. The last jump comes from the height of x - u or higher. The rest you have to cover in (u - d)-size steps, the number of such steps is of course (x - u)/(u - d).
After i-th step you are at height i * (u - d) + u (and falling down). So, in approx. (x - u)/(u - d) steps you are at height x - u + u = x. Recalling that the number of steps should be a whole number, we get the final result:
if (u >= x)
return 1;
if (u <= d)
throw "Impossible";
return ceil((x - u)/(u - d));
(ceil is a mathematical function returning the smallest integer not less than the given number.)

Categories

Resources