I am practicing my programming skill using Unity3D. I have a grid set up that has coordinates in an x,y type of setup.
[0,0] to [10,10]
With all the numbers in between (I.E. 5,5 would be close to center of the map).
The thing that I am trying to do now is figure out a mathematical formula to calculate the coordinates my character can move. If the character is at position 5,5 and has a movement radius of 2 what is the most efficient way to return a list or an array of coordinates my character can move to? Every single grid square is its own object and have public variables for its X and Y so once I have the available results actually using them in the code isn't hard.
Here's what I'm trying so far (I'm ignoring the out of range possibility for right now, that's an easy fix):
for(int x = currentGridSquare.xCoord - myMovementRange;
x <= currentGridSquare.xCoord + myMovementRange; x++){
for(int y = currentGridSquare.yCoord - myMovementRange;
y <= currentGridSquare + myMovementRange; y++)
{
//Starting at 5,5 with a movement range of 2 should
//start this process at the value of 3,3 which
// is incorrect
}
}
I may be too tired to actually calculate a formula for this but I've been searching and haven't come across anything so if anyone's had experience with this and knows a quick way to do it I would be greatly appreciative.
Update: The values that I am expecting this to return would be coordinates. In this example starting at 5,5, the values I'd want back would be [3,5],[4,4],[4,5],[4,6],[3,5],[4,5],[5,5],[6,5],[4,6],[5,6],[6,6] and [5,7]
So I used formula Ben provided and came up with:
foreach(var gridSquare in allGridSquares)
{
if( (Mathf.Abs(myX - gridSquare.Xcoord) + (Mathf.Abs(myY - gridSquare.Ycoor) >= myMovementValue)
{
gridSquare.activate();
}
}
I know that if the grid starts getting bigger than the distance formula will be more complicated and I will update this later if that's the case but for the size of my grid this works wonderfully.
Related
Alright, I don't know if you can quite consider it ray casting, but I am basically trying to find which tile on my 2d grid is being hovered over so I can place an object there.
The solution should only pick up the grid and not the buildings on the grid. Building highlighting will be based on if any of the tiles the building occupies is being hovered over.
A great example of what I am trying to achieve is a Factorio like building system.
Edit:
The grid is a 2d array which contains all the tile info. The tiles in world are each 2 triangles (Made from a vertex array and index array). The camera is a perspective camera (If Factorio uses Orthographic, I could switch to it if it made things simpler).
Edit 2:
The array contains a class called TileInformation which has a couple of things related to what the tile contains and such. The tiles are 1x1 in size and the array is 256x256. (There will be multiple grid pieces which can be individually updated.) All tiles are in a grid with positions represented as int's (Coordinate system is positive and negative.)
Your question is still not clear enough, but I'll make a few assumptions and hope that they meet your situation.
First, we need a picking ray that represents the 2D mouse position in 3D space. For this, we first transform the mouse position from pixel coordinates into normalized device coordinates between -1 and 1:
mouseNDCX = 2 * mousePixelX / viewportWidth - 1
mouseNDCY = 1 - 2 * mousePixelY / viewportHeight
Then, we find the ray. For this, we need the view-projection matrix of your camera. Then:
mouseNear = inverse(viewProjection) * (mouseNDCX, mouseNDCY, 0, 1)
mouseFar = inverse(viewProjection) * (mouseNDCX, mouseNDCY, 1, 1)
This will give you two positions on the picking ray. One on the z-near plane and one on the z-far plane. Do not forget to do the perspective divide:
mouseNear = (1 / mouseNear.w) * mouseNear
mouseFar = (1 / mouseFar.w) * mouseFar
The next step is calculating the intersection point with the grid. This is where your question is heavily underspecified. I assume that the grid lies on a plane that is parallel to one of the principal planes. In the following, this will be the xy-plane. If you have a different plane, you need to replace the corresponding components. I will further assume that the grid is located at height z.
Now, we want to find the intersection, i.e.:
((1 - t) * mouseNear + t * mouseFar).z = z
<=> mouseNear.z + t * (mouseFar.z - mouseNear.z) = z
<=> t = (z - mouseNear.z) / (mouseFar.z - mouseNear.z)
This lets us calculate the intersection point:
intersection = (1 - t) * mouseNear + t * mouseFar
This intersection point lies on the plane of the grid. Finally, we need to find the tile index. For this, we only need to consider the x- and y-components. Assuming that your grid origin is at o and that the tiles have size s, then the tile indices are:
i = floor((intersection.x - o.x) / s)
j = floor((intersection.y - o.y) / s)
i have a 2d array of tuples representing the xy coordinates of equally spaced points. what i need to do is given a center point coordinates, get all other points within radius. i have found this picture on the internet which sort of demonstrate what i want to achieve only difference is that my array is not random.
i have been using a kdTree to search for items within radius and it works fine but for a lot of points this gets super slow. i have also tried the following but it is also extremely slow
for (int i = 1; i < radius; i++)
{
for (int j = 1; j < radius; j++)
{
if (i*i + j*j <squaredRadius)
{
points.Add(new int[]{i,j});
points.Add(new int[]{-i,j});
points.Add(new int[]{i,-j});
points.Add(new int[]{-i,-j});
}
}
}
i was if anyone would have any suggestions on a faster way to achieve this
I think you can you a formula like (x-a)^2 + (y-b)^2 = r^2 where (a,b) is coord of the center and r is its radius. Then use (x-a)^2 + (y-b)^2<=r^2 to check if (x,y) is with the radius or not.
You can loop all the cell of your array to collect all the value you need or you can use some math to narrow the range of x and y to make the finding process faster.
This problem lends itself perfectly for parallel execution. You need to find the boundary of one quadrant then you can spawn 2r threads and do this for each vertical strip or horizontal strip (like a blur image filter). That should speed things up.
Obviously you will have to bounds check in each thread, think if your center point is corner or edge or close to....
I am using a .DAT file that contains 700 x and y coordinates with a name of the location, I know how to separate the x and the y for each of them, so at the moment each coordinate is separated. So my main point is set up like USAcamp 50 50 and I need to find the farthest distance away from 50,50 inside my code with the name attached. What is the best formula to use to find this? I also need to find how many miles are between each point and 50,50.
Everything is seperated like this:
string usaNames;
double x;
double y;
Thanks for any help, I can clarify on things if this is too confusing, I'm learning so everything helps.
Shortest distance between two points is:
SQRT((x2-x1)^2 + (y2-y1)^2)
Thus do this calculation for all sets of points and find the greatest distance.
As it related to C#, I would create a composite class around C#'s Point class and add the field for the name, then perform the nested for-loop to find the distances.
double max = -1;
for(int i = 0; i<arr.length-1;i++){
for(int j = i+1; j<arr.length; j++){
// Calculate the distance and set the max if highest
}
}
For more information look at this post: What is the most efficient way to calculate the maximum distance of two points in a list?
public void checkForCollision () {
int headX = cells[0].x;
int headY = cells[0].y;
int noOfParts = nPoints;
for(int i = 1; i <noOfParts;i++)
{
int tempX = cells[i].x;
int tempY = cells[i].y;
if(tempX == headX && tempY == headY){
JOptionPane.showMessageDialog(null,"Head hit body");
//EndGameCollectScore etc.
}
}
}
EDIT: 'Cells[]' is an array of type Point AND noOfParts is just how many segments the snake has
main Question
With the above code I'm trying to compare tempX to headX but i would like to have a sort of margin for error e.g. +-5 but am unsure how to accomplish this, my reasoning behind this is i'm thinking maybe the x and Y variables might be a few digits apart so if i have the radius of one of the segment of the snake (explanation of 'snake' in Alternate below) then if i'm right and the values are a tiny bit off it should still come back positive.
OR
Alternative
if anyone can suggest a better way for doing this? Basically it's for a Snake game and headX and headY is the head of the snake and the remaining X and Y variables in Cells is the body, and I'm attempting to compare if the head hits the body.
I tested it and it seemed to work but after i tested it again it seems it will only pick up the collision if i make the snake double back on itself for a few squares. e.g. IF i cross the body perpendicular it will not detect the collision.
Also i am fairly certain that this method is called after each block the snake moves.
Cheers,
Shane.
P.S Running of very little sleep and way too much sugar in my blood, If you need further clarification because the above doesn't make alot of sense let me know.
int eps = 5;
if (Math.abs(tempX - headX) <= eps && Math.abs(tempY - headY) <= eps) {
// ...
}
To check if two points are within a delta from each other, compute the distance between them. You can avoid going into the square root territory by using squares, like this:
int distSq = (tempX-headX)*(tempX-headX) + (tempY-headY)*(tempY-headY);
int minDist = 5;
if (distSq < minDist*minDist) {
// too close
}
I don't know how your snake looks, but if it has a complex shape, looking for a hit can be expensive in terms of speed. You can speed up collision detection if you can do a quick test, to see if a collision is possible at all. You can do this by using a bounding box. You would have to keep track of minimum and maximum x and y positions of the snake body. Only if a coordinate lies within these boundaries you would take account of the exact shape of the snake. How this has to be done depends on how the snake is represented. Check for each tile or each pixel the snake is made of or possibly check if the coordinate is within a polygon, if the snake outline is defined by a polygon. (I'm not going to explain how this works here, but you will find algorithms if you google a bit.)
If you need to calculate the distance to another point (the snake head), you can use different metrics for this. If only horizontal and vertical movements are possible within the game, the so called Manhattan or taxi distance can be used: d = |x1-x0| + |y1-y0|. It consists of adding the x and y distances, or you can use the maximum of both distances: d = Max(|x1-x0|, |y1-y0|) (correponds to 2kay's approach).
If you need the exact distance, apply the Pythagorean formula. In order to compare the distance with the error margin, you don't need to calculate the square root. Instead compare the square of the distance with the square of the error margin. This saves time. (x1-x0)^2 + (y1-y0)^2 < error_margin^2.
I am building a Kinect SDK WPF Applicaiton and using the Kinect to move a "cursor"/hand object.
The problem i am having is that at 30 frames a second the cursor is actually jumping around a bit erratically because of the precision of the Kinect (i.e. while holding your hand still the object moves within a 5px space).
I am planning on writing an algorithm that doesn't simply move the X/Y of my "cursor" sprint to the right position on the screen, but behaves more like a "move the hand towards this X/Y co-ordinate" so that it is a more smooth movement.
Can someone point me to a good one that someone else has written so i can avoid reinventing the wheel.
I understand that this is probably pretty common, but as i am more of a business developer i am not sure of the name for such a feature so apologies in advance if its a n00b question.
When I worked with the Kinect, I just used some simple math (which I think is called linear regression) to move to a point some distance between the cursor's current location and its target location. Get the location of the cursor, get the location the user's hand is at (translated to screen coordinates), then move the cursor to some point between those.
float currentX = ..., currentY = ..., targetX = ..., targetY = ...;
float diffX = targetX - currentX;
float diffY = targetY - currentY;
float delta = 0.5f; // 0 = no movement, 1 = move directly to target point.
currentX = currentX + delta * diffX;
currentY = currentY + delta * diffY;
You'll still get jittering, depending on the delta, but it will be much smoother and generally in a smaller area.
On a related note, have you taken a look at the Kinect's skeleton smoothing parameters? You can actually let the SDK handle some of the filtering.
Consider your input values (those jumping positions) as a signal with both low and high frequency parts. The low frequencies represent the rough position/movement while the high frequency parts contain the fast jumping within smaller distances.
So what you need or look for is a low pass filter. That filters out the high frequency parts and leaves the rough (but as accurate as the Kinect can get) position over, if you manage to set it up with the right parameter. This parameter is the crossover frequency for the filter. You have to play around a bit and you will see.
An implementation example for time-discrete values would be from here (originally from wikipedia):
static final float ALPHA = 0.15f;
protected float[] lowPass( float[] input, float[] output ) {
if ( output == null ) return input;
for ( int i=0; i<input.length; i++ ) {
output[i] = output[i] + ALPHA * (input[i] - output[i]);
}
return output;
}
You can put the last values of both the X and Y components of your position vectors into this function to smooth them out (input[0] for X and input[1] for Y, output[0] and output[1] are results of the previous function call).
Like I already said, you have to find a good balance for the smoothing factor ALPHA (0 ≤ ALPHA ≤ 1):
Too big and the signal will not get smoothed enough, the effect wont be sufficient
Too small and the signal will be smoothed 'too much', the cursor will lag behind the users movement, too much inertia
(If you look at the formula newout = out + alpha * (in - out), you see that with a alpha value of 0, you just take the old out value again, therefore the value will never change; while with a value of 1 you have newout = out + in - out that means you dont smooth anything but always take the newest value)
One very simple idea for solving this problem would be to display the cursor at a location that's the average of some past number of positions. For example, suppose that you track the last five locations of the hand and then display the cursor at that position. Then if the user's hand is relatively still, the jerkiness from frame to frame should be reasonably low, because the last five frames will have had the hand in roughly the same position and the noise should cancel out. If the user then moves the cursor across the screen, the cursor will animate as it moves from its old position to the new position, since as you factor in the last five positions of the hand the average position will slowly interpolate between its old and new positions.
This approach is very easily tweaked. You could transform the data points so that old points are weighted more or less than new points, and could adjust the length of the history you keep.
Hope this helps!