In a given 2D square (n*n) even size array, i want to traverse from a starting corner till its center. Below is the image for more info.
My algorithm is to start from corner and maintain two global variable as currentX and currentY and run a loop until currentX and currentY reach to the center. Below is my pseudo code-
x=0
y=0
currentX=0
currentY=0
while(currentX != centerX and currentY != centerY){
currentX=travel_in_x_plus_direction(x,n);
currenty=travel_in_y_plus_direction(y,n);
currentX=travel_in_x_minux_direction(currentX,x);
currentY=travel_in_y_minux_direction(currentY,y-1);
n--;
x--;
y--;
}
The function travel_in_x_plus_direction(currentX) traverse the array starting from currentX till x and returns the final value of x. The same concept applies for rest of the functions also.
Is this the right way? Is there any better way to traverse it in the same manner?
Psuedocode "uses the structural conventions of a programming language, but is intended for human reading rather than machine reading." (http://en.wikipedia.org/wiki/Pseudocode)
I would suggest that writing psuedocode that conforms to this definition would be of great benefit to you and help you think about how you are going about solving your problem.
Your algorithm
Seems to suggest that you are
checking if you are at your goal "END", and if you are not
Move right
Move down
Move left
Move up
which means you will never get anywhere.
Starting point for a solution
My container is of size n*n
therefore intially the boundary is n*n
if I travel through an individual square, it becomes part of the boundary.
The path is quite simple, begin by moving right, and then whenever blocked change direction. The sequence of directions is right, down, left, up in that order, until the goal is reached.
HorizontalMax = n (the right wall)
HorizontalMin = 0 (the left wall)
VerticalMax = n (the bottom wall)
VerticalMin = 0 (the top wall)
While not at goal
While not at right boundary or goal
Move right
Increment VerticalMin (you just moved along the top wall)
While not at bottom boundary or goal
Move down
Decrement HorizontalMax (you just moved along the right wall)
While not at left boundary or goal
Move left
Decrement VerticalMax (you just moved along the bottom wall)
While not at top boundary or goal
Move up
Increment HorizontalMin (you just moved along the left wall)
End
Related
I am trying to create a physically plausible 2d physics engine. I have read many documents about detection of collisions, contact resolving, interpenetrations, projection, separating axis theorem (SAT) methods, etc.
Projection via SAT appears to be one physically plausible method for dealing with overlapping ("penetrating") objects. This works fine for objects with no rotation, but I can't figure out how to deal with rotations.
Imagine two polygons in rotation that will collide:
I need to understand how to project the point of contact and the time when this happens.
any help will be appreciated!
The problem is that you are assuming both bodies are moving at the same time, which will be a huge pain to calculate the exact collision point.
You can update the position of each body sequentially, and apply the collisions accordingly:
(I know the bodies are not rotated in this example, but I have no means right now to draw rotated forms, but the same idea applies, sorry)
First, the rectangle is moved, and checks for collision.
Then, the pentagon moves, and collides with the rectangle, updating its position.
And last, the triangle position is also checked for collition and updated.
About how to calculate the collision point, you can apply this:
Position calculateValidPosition(Position start, Position end)
Position middlePoint = (start + end) /2
if (middlePoint == start || middlePoint == end)
return start
if( isColliding(middlePont) )
return calculateValidPosition(start, middlePoint)
else
return calculate(middlePoint, end)
Note that
Position middlePoint = (start + end) /2
not only calculates the body's middle position, but also should calculate it's middle rotation:
If rotation is X at the begining of the movement, and Y at the end, the middle point rotatiln is just (X+Y)/2
Note this algorithm leaves a lot of room for optimization (like making it non-recursive)
This solution might seem not really accurate, but it will only work incorrectly when the speed of the bodies is way greater than the body's size, which will only happen if a really small body moves really fast. In the rest of scenarios the result is "good enough" for a game.
I have a complicated problem and it involves an understanding of Maths I'm not confident with.
Some slight context may help. I'm building a 3D train simulator for children and it will run in the browser using WebGL. I'm trying to create a network of points to place the track assets (see image) and provide reference for the train to move along.
To help explain my problem I have created a visual representation as I am a designer who can script and not really a programmer or a mathematician:
Basically, I have 3 shapes (Figs. A, B & C) and although they have width, can be represented as a straight line for A and curves (B & C). Curves B & C are derived (bend modified) from A so are all the same length (l) which is 112. The curves (B & C) each have a radius (r) of 285.5 and the (a) angle they were bent at was 22.5°.
Each shape (A, B & C) has a registration point (start point) illustrated by the centre of the green boxes attached to each of them.
What I am trying to do is create a network of "track" starting at 0, 0 (using standard Cartesian coordinates).
My problem is where to place the next element after a curve. If it were straight track then there is no problem as I can use the length as a constant offset along the y axis but that would be boring so I need to add curves.
Fig. D. demonstrates an example of a possible track layout but please understand that I am not looking for a static answer (based on where everything is positioned in the image), I need a formula that can be applied no matter how I configure the track.
Using Fig. D. I tried to work out where to place the second curved element after the first one. I used the formula for plotting a point of the circumference of a circle given its centre coordinates and radius (Fig. E.).
I had point 1 as that was simply a case of setting the length (y position) of the straight line. I could easily work out the centre of the circle because that's just the offset y position, the offset of the radius (r) (x position) and the angle (a) which is always 22.5° (which, incidentally, was converted to Radians as per formula requirements).
After passing the values through the formula I didn't get the correct result because the formula assumed I was working anti-clockwise starting at 3 o'clock so I had to deduct 180 from (a) and convert that to Radians to get the expected result.
That did work and if I wanted to create a 180° track curve I could use the same centre point and simply deducted 22.5° from the angle each time. Great. But I want a more dynamic track layout like in Figs. D & E.
So, how would I go about working point 5 in Fig. E. because that represents the centre point for that curve segment? I simply have no idea.
Also, as a bonus question, is this the correct way to be doing this or am I over-complicating things?
This problem is the only issue stopping me from building my game and, as you can appreciate, it is a bit of a biggie so I thank anyone for their contribution in advance.
As you build up the track, the position of the next piece of track to be placed needs to be relative to location and direction of the current end of the track.
I would store an (x,y) position and an angle a to indicate the current point (with x,y starting at 0, and a starting at pi/2 radians, which corresponds to straight up in the "anticlockwise from 3-o'clock" system).
Then construct
fx = cos(a);
fy = sin(a);
lx = -sin(a);
ly = cos(a);
which correspond to the x and y components of 'forward' and 'left' vectors relative to the direction we are currently facing. If we wanted to move our position one unit forward, we would increment (x,y) by (fx, fy).
In your case, the rule for placing a straight section of track is then:
x=x+112*fx
y=y+112*fy
The rule for placing a curve is slightly more complex. For a curve turning right, we need to move forward 112*sin(22.5°), then side-step right 112*(1-cos(22.5°), then turn clockwise by 22.5°. In code,
x=x+285.206*sin(22.5*pi/180)*fx // Move forward
y=y+285.206*sin(22.5*pi/180)*fy
x=x+285.206*(1-cos(22.5*pi/180))*(-lx) // Side-step right
y=y+285.206*(1-cos(22.5*pi/180))*(-ly)
a=a-22.5*pi/180 // Turn to face new direction
Turning left is just like turning right, but with a negative angle.
To place the subsequent pieces, just run this procedure again, calculating fx,fy, lx and ly with the now-updated value of a, and then incrementing x and y depending on what type of track piece is next.
There is one other point that you might consider; in my experience, building tracks which form closed loops with these sort of pieces usually works if you stick to making 90° turns or rather symmetric layouts. However, it's quite easy to make tracks which don't quite join up, and it's not obvious to see how they should be modified to allow them to join. Something to bear in mind perhaps if your program allows children to design their own layouts.
Point 5 is equidistant from 3 as 2, but in the opposite direction.
The problem I'm trying to solve is the following:
In a 2-D space, Given a grid size and a rectangle, calculate the grid cells
occupied (partially or totally) by the rectangle.
By "Grid size" I mean something like: "A 16x16 grid" or "A 32x32 grid". All grids are centered on the origin of coordinates (0,0).
The rectangle is defined by 4 floats: the left, top, width and height.
The result of this operation is always a rectangle. I'd like to return the coordinates of top-left cell (i.e. 0,0) followed by the number of cells the retangle occupies to the right and down (a bit like width and height, but for cells)
So far I've been able to write an algorithm that mostly works. What it does first, is calculating the cell coordinates where a single dot resides in the grid. Then, given the rectangle, I calculate where its top-left and lower-rights corner are on the grid, and then it's a simple substraction:
-- given a world coordinate, return the coordinates of the cell that would contain it
local function _toGrid(wx, wy)
return math.floor(wx / __cellSize), math.floor(wy / __cellSize)
end
-- given a box in world coordinates, return a box in grid coordinates that contains it
-- returns the x,y coordinates of the top-left cell, the number of cells to the right and the number of cells down.
local function _toGridBox(l, t, w, h)
local gl,gt = _toGrid(l, t) -- top left grid corner
local gr,gb = _toGrid(l+w, t+h) -- bottom-right grid corner
return gl, gt, gr-gl+1, gb-gt+1 -- return top,left,cells to the right, cells to bottom
end
Notes:
The source code is Lua, but I will accept solutions in any programming language, as long as they are intelligible.
The y-coordinate goes "down when increasing"; that's how a lot of screen systems work. I don't think that's significant for this problem, but don't get confused by that).
In a 16x16 grid, a rectangle on 0,0, with width=10 and height=20, gr will be 0 and gt 1, so _toGrid will return 0,0,1,2 (1 row, two columns, on the 0,0 cell).
The problem happens when the rectangle "touches" (not crosses) either the lower or right side of one cell from inside. In that case, _toGrid returns "one more cell" than I'd like it to.
For example, if I move the previous rectangle to the left 6 pixels (so it is on 10,0), it will be "touching" the left-side border of its containing grid, which goes from 0 to 16. Then gr will be 1, and the returned data will be 0,0,2,2.
I'd like to avoid this, if at all possible. For a rectangle going to 16 "from the left", I'd like it to remain on the first grid cell. I'd like it to begin "occupying the next cell" as soon as it surpasses 16 - for example when it's at 16.00000001 .
Also, notice that this only applies to the right and bottom sides. The left and upper sides work as I want them to. For example, a rectangle whose left coordinate is 16, should appear on the "second cell to the right", not on the first.
I'm sure the solution isn't complicated, but I've been thinking about this for a while now and I don't seem to find it. Any help will be appreciated.
For the bottom and right hand side, you need to use ceil instead of floor. I don't know any Lua, so this may not be syntactically correct, but you would want something along these lines:
local function _toGridBox(l, t, w, h)
local gl = math.floor(l / _cellSize)
local gt = math.floor(t / _cellSize)
local gr = math.ceil((l+w) / _cellSize)
local gb = math.ceil((t+h) / _cellSize)
return gl, gt, gr-gl, gb-gt -- return top,left,cells to the right, cells to bottom
end
Your problem, essentially, is that the function _toGrid is the wrong abstraction for your purpose because it always uses floor. Apparently, you locked yourself into using that abstraction, which then made it difficult to come up with the right answer.
I am trying to write an application to draw schematic diagrams which contain rectangles, lines and circles. Now I want to add another functionality to drag a rectangle to different position. The problem I am facing is to detect whether I have clicked within a rectangle or not. I know there is a function like Rectangle.Contains(Point). To use such method I need to use a for loop to check against each rectangle. If I have a large number of rectangles present, then its not wise to use this method. Is there any other way to do this task.
You need a computer graphics textbook, this and similar problems are often discussed.
If memory serves me, make sure the point is below the top edge of the rectangle, above the bottom edge, left of the right edge and right of the left edge.
Regarding testing a bunch of rectangles in a loop. Consider having a circle that each rectangle fits in, a bounding circle. First test to see if the point is farther from the origin of the circle than the radius of the circle. If so there is no need to test the rectangle, its a miss. OK, that was a very theoretical answer. In reality calculating the distance from the point to the origin can be a very expensive calculation, it involves a square root, it may be faster to do the four comparisons of the point in rectangle check. Again if memory servers me, we don't really care what the distance from the origin is only if it is greater than the radius. So only partially perform the distance calculation, omitting the final square root, and compare against the square of the radius. Of course you still need to experiment and profile to make sure this bounding circle check is faster than just doing the regular point in rectangle check and you need to make sure you will have sufficient misses to offset the hits where you will end up doing both the bounding circle and rectangle checks.
You need to use a spatial index to find quickly in which rectangle the mouse is. I suggest a R-tree, here is the theorical part:
http://en.wikipedia.org/wiki/R-tree
And the c#,implementation:
http://sourceforge.net/projects/cspatialindexrt/
Create an rtee, add your rectangles then call the rtree.nearest method with the mouse coordinate to know the rectangles containing the mouse cursor. You can play with the distance parameter.
Hope it helps,
Anben Panglose.
I would go about dividing the display region into a quadrant.
Then place the rectangles into top-left, top-right, bottom-left, bottom-right grids.
Placing them means, creating a list for every quadrant and placing the rectangles in it.
Once the point is clicked, determine which quarter it belongs to and search in those rectangles only. This approach reduces your linear search by 4 times.
Remember that you need to also take care of overlapping where the point can belong to many rectangles. Here the z-order of your rectangles matter. So while the list is maintained for a quadrant, it should be sorted with it's z-order as a key.
Hope this helps.
May be something like this?
public bool isRectangelContainPoint(RectangleF rec, PointF pt)
{
if (pt.X >= rec.Left && pt.X <= rec.Right && pt.Y <= rec.Bottom && pt.Y >= rec.Top)
return true;
else
return false;
}
I have a grid based game (platformer) where I've based everything on tiles. I have tiles that are solid and liquid. I'm trying to find of a good way to make water tiles simulate water in a rough way.
At the moment I have the current system:
When a water tile is added above another water tile, it adds 1 to the water tile below. The number indicates the pressure.
Here's how it looks like at the moment:
[0] <- This water tile has 0 in pressure.
[1] <- This water tile has 1 in pressure.
if I add another water tile next to the bottom one, it searches from left, right and above if there are any water tiles and inheritates the biggest pressure around it.
Example:
[0]
[1][1]
And here's a bigger example after adding few water tiles:
[0][0]
[1][1][1][1]
[2][2][2][2][2]
Then I make every water tile that has pressure that is equal or bigger than 1 try to move left/right if there's free space, then set pressure to 0 and check if it can inheritate pressure around itself from neighbor water tiles if there are any.
This system works very well, except for the case when water tiles are removed from the top.
If I remove the top water tiles from the last example:
[1][1][1][1]
[2][2][2][2][2]
Then we have the top row with pressure 1, it should have 0 there now and the bottom row should have 1.
Is there some smarter system I can implement to do this more proper?
The following are the restrictions:
Each tile can only check its neighbors tiles.
Tile can have any function defined.
Tile can have any variable to store data.
Can you guys come up with a better system that works better than mine?
The usual test case I do is:
[]
[] should become [][]
[]
[]
[] should become [][][]
[]
[][][] should become [][][][]
Assuming the game runs for a while.
Any suggestions would be more than welcome!
Maybe you could forget about pressures (since you are not really using them as pressures) and simply use a bool tryMove or something like that.
Each simulation step should be broken in two substeps:
First loop in tiles:
If space below is free, set tryMove to true, finish this tile.
If has tile above, set tryMove to true else set tryMove to false.
If any neighbor is trying to move, set tryMove to true.
Second loop in tiles:
If trying to move and space below is free, move tile down, set
tryMove to false, finish tile.
If trying to move and can move sideways (free space to left or
right) set neighbors tryMove as false, move it, set this tryMove as false, finish tile.
I think this should fix your issue.
If you have the resources to support it, I recommend a recursive function that tries pushing tiles left and right from above. If the function finds another tile below, it can try displacing that tile to either side. The best method would be to start stepping left and right, one tile at a time. If it keeps finding water tiles, then it keeps going. Eventually it will either run out of tiles to check (ends up at a wall) or will find a water tile with free space to move over. After multiple iterations, the water should push outward and make room for the higher water to fall down.
Let me reclarify the left then right nature of the recursion. Essentially, once the function makes it to the base level of the water, it should start choosing water tiles, alternating left and right. So it will first check the tile directly left, then directly right, then two left, then two right, etc. If it finds an air tile, it should do a displacement of the nearest water tile. If it finds something else (usually a wall) it should give up on that side. Once it's given up on both sides, you should consider other behaviors instead, such as the topmost water randomly traveling around over the surface.
If you really want the behavior to seem natural, I highly recommend a random variable deciding whether it checks left or right first. Otherwise you will probably end up with strangely regular recurring patterns.