The title is a little vague, but I'll explain better here.
The Setup
I'm trying to program a little water level simulator, much like the water levels in the game, LIMBO. When an opening is made, allowing water to flow between two bodies of water, the levels equalize. The setup I have now is two containers, with blue blocks inside representing water levels. My mouse removes chunks of terrain away, and so, when an opening is made between the bodies, they should adjust and their Y values should move to match.
Image examples:
Semi-filled tanks:
Equalized tanks:
Now, I know some maths could be done to figure out how much to adjust the levels and the ratios between different sized tanks. That part I think is pretty straight forward. But I can't figure out a good method of determining if and when the two bodies of water are connected.
Any algorithm, pseudo-code, or references would be much appreciated!
If you need more clarification, please, don't hesitate to ask. I look forward to all feedback and will edit my post for specific clarification.
Thanks!
~ natebot13
BTW: I'm using C++, SFML, and Box2D (Box2D is for some other physics related things I need, not necessarily needed for this example).
You need to check whether the edge of the container1 is connected to container2 at any point of time if so then adjust the water level. I guess you are working on a image so you can use the connected components algorithm to check if any of the edge pixels of container1 is connected to any of edge pixels of container2 and also get their positions.
Algorithm :-
puts edges of container1 in one set which is connected to a dummy parent1.
puts edges of container2 in another set which is connected to another dummy parent2.
say after every one second add the new added pixels to sets using connected components
check at end of every union whether dummy parent1 and parent2 are connected.
You can use DFS to check the exacts points of connection by starting from one edge set1 and reaching the other. The last pixel and
the previous first pixel in edge set1 are connection end points.
Note:-
There is a implementation of disjoint set in c++ boost lib which might be useful in implementation of connected components.
I think you can start from left to right for example:
the right side of the left tank position is known.
search the column to its right for a blue square.
once found, search its surrounding squares - up, down and to the right.
keep searching until you get to the known left side of the right tank.
Related
I'm programming my first game and I have one last problem to solve. I need an algorithm to check if I can move a chosen ball to a chosen place.
Look at this picture:
The rule is, if I picked up the blue ball on the white background (in the very middle) I can move it to all the green spaces and I can't move it to the purple ones, cause they are sort of fenced by other balls. I naturally can't move it to the places taken by other balls. The ball can only move up, down, left and right.
Now I am aware that there is two already existing algorithms: A* and Dijkstra's algorithm that might be helpful, but they seem too complex for what I need (both using vectors or stuff that I weren't taught yet, I'm quite new to programming and this is my semester project). I don't need to find the shortest way, I just need to know whether the chosen destination place is fenced by other balls or not.
My board in the game is 9x9 array simply filled with '/' if it's an empty place or one of the 7 letters if it's taken.
Is there a way I can code the algorithm in a simple way?
[I went for the flood fill and it works just fine, thank you for all your help and if someone has a similar problem - I recommend using flood fill, it's really simple and quick]
I suggest using Flood fill algorithm:
Flood fill, also called seed fill, is an algorithm that determines the
area connected to a given node in a multi-dimensional array. It is
used in the "bucket" fill tool of paint programs to fill connected,
similarly-colored areas with a different color, and in games such as
Go and Minesweeper for determining which pieces are cleared. When
applied on an image to fill a particular bounded area with color, it
is also known as boundary fill.
In terms of complexity time, this algorithm will be equals the recursive one: O(N×M), where N and M are the dimensions of the input matrix. The key idea is that in both algorithms each node is processed at most once.
In this link you can find a guide to the implementation of the algorithm.
More specifically, as Martin Bonner suggested, there are some key concepts for the implementation:
Mark all empty cells as unknown (all full cells are unreachable)
Add the source cell to a set of routable cells
While the set is not empty:
pop an element from the set;
mark all adjacent unknown cells as "reachable" and add them to the set
All remaining unknown cells are unreachable.
PS: You may want to read Flood fill vs DFS.
You can do this very simply using the BFS(Breadth First Search) algorithm.
For this you need to study the Graph data structure. Its pretty simple to implement, once you understand it.
Key Idea
Your cells will act as vertices, whereas the edges will tell whether or not you will be able to move from one cell to another.
Once you have implemented you graph using an adjacency list or adjacency matrix representation, you are good to go and use the BFS algorithm to do what you are trying to do.
I have a wireless mesh network of nodes, each of which is capable of reporting its 'distance' to its neighbors, measured in (simplified) signal strength to them. The nodes are geographically in 3d space but because of radio interference, the distance between nodes need not be trigonometrically (trigonomically?) consistent. I.e., given nodes A, B and C, the distance between A and B might be 10, between A and C also 10, yet between B and C 100.
What I want to do is visualize the logical network layout in terms of connectness of nodes, i.e. include the logical distance between nodes in the visual.
So far my research has shown the multidimensional scaling (MDS) is designed for exactly this sort of thing. Given that my data can be directly expressed as a 2d distance matrix, it's even a simpler form of the more general MDS.
Now, there seem to be many MDS algorithms, see e.g. http://homepage.tudelft.nl/19j49/Matlab_Toolbox_for_Dimensionality_Reduction.html and http://tapkee.lisitsyn.me/ . I need to do this in C++ and I'm hoping I can use a ready-made component, i.e. not have to re-implement an algo from a paper. So, I thought this: https://sites.google.com/site/simpmatrix/ would be the ticket. And it works, but:
The layout is not stable, i.e. every time the algorithm is re-run, the position of the nodes changes (see differences between image 1 and 2 below - this is from having been run twice, without any further changes). This is due to the initialization matrix (which contains the initial location of each node, which the algorithm then iteratively corrects) that is passed to this algorithm - I pass an empty one and then the implementation derives a random one. In general, the layout does approach the layout I expected from the given input data. Furthermore, between different runs, the direction of nodes (clockwise or counterclockwise) can change. See image 3 below.
The 'solution' I thought was obvious, was to pass a stable default initialization matrix. But when I put all nodes initially in the same place, they're not moved at all; when I put them on one axis (node 0 at 0,0 ; node 1 at 1,0 ; node 2 at 2,0 etc.), they are moved along that axis only. (see image 4 below). The relative distances between them are OK, though.
So it seems like this algorithm only changes distance between nodes, but doesn't change their location.
Thanks for reading this far - my questions are (I'd be happy to get just one or a few of them answered as each of them might give me a clue as to what direction to continue in):
Where can I find more information on the properties of each of the many MDS algorithms?
Is there an algorithm that derives the complete location of each node in a network, without having to pass an initial position for each node?
Is there a solid way to estimate the location of each point so that the algorithm can then correctly scale the distance between them? I have no geographic location of each of these nodes, that is the whole point of this exercise.
Are there any algorithms to keep the 'angle' at which the network is derived constant between runs?
If all else fails, my next option is going to be to use the algorithm I mentioned above, increase the number of iterations to keep the variability between runs at around a few pixels (I'd have to experiment with how many iterations that would take), then 'rotate' each node around node 0 to, for example, align nodes 0 and 1 on a horizontal line from left to right; that way, I would 'correct' the location of the points after their relative distances have been determined by the MDS algorithm. I would have to correct for the order of connected nodes (clockwise or counterclockwise) around each node as well. This might become hairy quite quickly.
Obviously I'd prefer a stable algorithmic solution - increasing iterations to smooth out the randomness is not very reliable.
Thanks.
EDIT: I was referred to cs.stackexchange.com and some comments have been made there; for algorithmic suggestions, please see https://cs.stackexchange.com/questions/18439/stable-multi-dimensional-scaling-algorithm .
Image 1 - with random initialization matrix:
Image 2 - after running with same input data, rotated when compared to 1:
Image 3 - same as previous 2, but nodes 1-3 are in another direction:
Image 4 - with the initial layout of the nodes on one line, their position on the y axis isn't changed:
Most scaling algorithms effectively set "springs" between nodes, where the resting length of the spring is the desired length of the edge. They then attempt to minimize the energy of the system of springs. When you initialize all the nodes on top of each other though, the amount of energy released when any one node is moved is the same in every direction. So the gradient of energy with respect to each node's position is zero, so the algorithm leaves the node where it is. Similarly if you start them all in a straight line, the gradient is always along that line, so the nodes are only ever moved along it.
(That's a flawed explanation in many respects, but it works for an intuition)
Try initializing the nodes to lie on the unit circle, on a grid or in any other fashion such that they aren't all co-linear. Assuming the library algorithm's update scheme is deterministic, that should give you reproducible visualizations and avoid degeneracy conditions.
If the library is non-deterministic, either find another library which is deterministic, or open up the source code and replace the randomness generator with a PRNG initialized with a fixed seed. I'd recommend the former option though, as other, more advanced libraries should allow you to set edges you want to "ignore" too.
I have read the codes of the "SimpleMatrix" MDS library and found that it use a random permutation matrix to decide the order of points. After fix the permutation order (just use srand(12345) instead of srand(time(0))), the result of the same data is unchanged.
Obviously there's no exact solution in general to this problem; with just 4 nodes ABCD and distances AB=BC=AC=AD=BD=1 CD=10 you cannot clearly draw a suitable 2D diagram (and not even a 3D one).
What those algorithms do is just placing springs between the nodes and then simulate a repulsion/attraction (depending on if the spring is shorter or longer than prescribed distance) probably also adding spatial friction to avoid resonance and explosion.
To keep a "stable" diagram just build a solution and then only update the distances, re-using the current position from previous solution as starting point. Picking two fixed nodes and aligning them seems a good idea to prevent a slow drift but I'd say that spring forces never end up creating a rotational momentum and thus I'd expect that just scaling and centering the solution should be enough anyway.
Say we have an object at point A. It wants to find out if it can move to point B. It has limited velocity so it can only move step by step. It casts a ray at direction it is moving to. Ray collides with an object and we detect it. How to get a way to pass our ray safely (avoiding collision)?
btw, is there a way to make such thing work in case of object cast, will it be as/nearly fast as with simple ray cast?
Is there a way to find optimal in some vay path?
What you're asking about is actually a pathfinding question; more specifically, it's the "any-angle pathfinding problem."
If you can limit the edges of obstacles to a grid, then a popular solution is to just use A* on that grid, then apply path-smoothing. However, there is a (rather recent) algorithm that is both simpler to implement/understand and gives better results than path-smoothing. It's called Theta*.
There is a nice article explaining Theta* (from which I stole the above image) here
If you can't restrict your obstacles to a grid, you'll have to generate a navigation mesh for your map:
There are many ways of doing this, of varying complexity; see for example here, here, or here. A quick google search also turns up plenty of libraries available to do this for you, such as this one or this one.
One approach could be to use a rope, or several ropes, where a rope is made of a few points connected linearly. You can initialize the points in random places in space, but the first point is the initial position of A, and the last point is the final position of A.
Initially, the rope will be a very bad route. In order to optimize, move the points along an energy gradient. In your case the energy function is very simple, i.e. the total length of the rope.
This is not a new idea but is used in computer vision to detect boundaries of objects, although the energy functions are much more complicated. Yet, have look at "snakes" to give you an idea how to move each point given its two neighbors: http://en.wikipedia.org/wiki/Snake_(computer_vision)
In your case, however, simply deriving a direction for each point from the force exerted by its neighbors will be just fine.
Your problem is a constrained problem where you consider collision. I would really go with #paddy's idea here to use a convex hull, or even just a sphere for each object. In the latter case, don't move a point into a place where its distance to B is less than the radius of A plus the radius of B plus a fudge factor considering that you don't have an infinite number of points.
A valid solution requires that the longest distance between any neighbors is smaller than a threshold, otherwise, the connecting line between two points will intersect with the obstacle.
How about a simple approach to begin with....
If this is just one object, you could compute the convex hull of all the vertices of the obstacle, plus the start and end points. You would then examine the two directions to get from A to B by traversing the hull clockwise and anti-clockwise. Choose the shortest path.
It's a little more complex because the shape you are moving is not just a point. You can't just blindly move its centre or it will collide. It gets more complicated still as it moves past a vertex, because you have to graze an edge of your object against the vertex of the obstacle.
But hopefully that gives you an idea to ponder over, that's not conceptually difficult to understand.
I have made this image to tell my idea for reaching the object to point B.
Objects in the image :-
The dark blue dot represents the object. The red lines are obstacles. The grey dot and line are the area which can be reached. The purple arrow is the direction of the point B. The grey line of the object is the field of visibility.
Understanding the image :-
The object will have a certain field of visibility. This is a 2d situation so i have assumed the field of visibility to be 180deg. (for human field of visibility refer http://en.wikipedia.org/wiki/Human_eye#Field_of_view ) The object will measure distance by using the idea of SONAR. With the help of SONAR the object can find out the area where it can reach. Using BACKTRACKING, the object can find out the way to the object. If there is no way to go, the object must change its field of visibility
One way to look at this is as a shadow casting problem. Make A the "light source" and then decide whether each point in the scene is in or out of shadow. Those not in shadow are accessible by rays from A. The other areas are not. If you find B is in shadow, then you need only locate the nearest point in the scene that is in light.
If you discretize this problem into "pixels," then the above approach has very well-known solutions in the huge computer graphics literature on shadow rendering. For example, you can use a Shadow Map to paint each pixel with a boolean flag that indicates whether it's in shadow or not. Finding the nearest lit pixel is just a simple search of growing concentric circles around B. Both of these operations can be made extremely fast by exploiting GPU hardware.
One other note: You can treat a general object path finding problem as a point path problem. The secret is to "grow" the obstacles by an appropriate amount using Minkowski Differences. See for example this work on robot path planning.
I'm trying to develop a game where cars move along roads and stop according to the signal of the traffic lights. They've got different velocities. Sometimes cars need to decelerate in order to not hit the leading car. They need to stop at the red lights. They have to make turns and etc. This is all relatively easy when working with straight intersecting roads. But how can I move a car/cars along a curved path? So far it was easy because I was just using either x or y of a car's position. But this time it's not the case, both coordinates seem to be necessary for moving it ahead. With straight roads I can just give a car an arbitrary speed and it will move along x or y axis with that speed. But how can I determine the velocity, if both coordinates have to be taken into account? Acceleration and decelerations are also mistery to me in this case. Thanks ahead.
Although this is about moving a train over a freeform track, the same issues and principles apply to cars moving across freeform roads. Actually, cars may be easier because they don't need to stick to their track 100% accurately.
In short: it's not easy, but doable. How hard it is going to be depends on how realistic you want your cars to look and finding corners to cut.
In your case the cars should simply follow a path (series of points). Since CCActions are bad for frequent direction/velocity changes, you should use your own system of detecting path points and heading to the next. Movement along a bezier curve is not going to have your cards move at constant speed, that rules out the CCBezier* actions.
For Operating Systems class I'm going to write a scheduling simulator entitled "Jurrasic Park".
The ultimate goal is for me to have a series of cars following a set path and passengers waiting in line at a set location for those cars to return to so they can be picked up and be taken on the tour. This will be a simple 2d, top-down view of the track and the cars moving along it.
While I can code this easily without having to visually display anything I'm not quite sure what the best way would be to implement a car moving along a fixed track.
To start out, I'm going to simply use OpenGL to draw my cars as rectangles but I'm still a little confused about how to approach updating the car's position and ensuring it is moving along the set path for the simulated theme park.
Should I store vertices of the track in a list and have each call to update() move the cars a step closer to the next vertex?
If you want curved track, you can use splines, which are mathematically defined curves specified by two vector endpoints. You plop down the endpoints, and then solve for a nice curve between them. A search should reveal source code or math that you can derive into source code. The nice thing about this is that you can solve for the heading of your vehicle exactly, as well as get the next location on your path by doing a percentage calculation. The difficult thing is that you have to do a curve length calculation if you don't want the same number of steps between each set of endpoints.
An alternate approach is to use a hidden bitmap with the path drawn on it as a single pixel wide curve. You can find the next location in the path by matching the pixels surrounding your current location to a direction-of-travel vector, and then updating the vector with a delta function at each step. We used this approach for a path traveling prototype where a "vehicle" was being "driven" along various paths using a joystick, and it works okay until you have some intersections that confuse your vector calculations. But if it's a unidirectional closed loop, this would work just fine, and it's dead simple to implement. You can smooth out the heading angle of your vehicle by averaging the last few deltas. Also, each pixel becomes one "step", so your velocity control is easy.
In the former case, you can have specially tagged endpoints for start/stop locations or points of interest. In the latter, just use a different color pixel on the path for special nodes. In either case, what you display will probably not be the underlying path data, but some prettied up representation of your "park".
Just pick whatever is easiest, and write a tick() function that steps to the next path location and updates your vehicle heading whenever the car is in motion. If you're really clever, you can do some radius based collision handling so that cars will automatically stop when a car in front of them on the track has halted.
I would keep it simple:
Run a timer (every 100msec), and on each timer draw each ones of the cars in the new location. The location is read from a file, which contains the 2D coordinates of the car (each car?).
If you design the road to be very long (lets say, 30 seconds) writing 30*10 points would be... hard. So how about storing at the file the location at every full second? Then between those 2 intervals you will have 9 blind spots, just move the car in constant speed (x += dx/9, y+= dy/9).
I would like to hear a better approach :)
Well you could use some path as you describe, ether a fixed point path or spline. Then move as a fixed 'velocity' on this path. This may look stiff, if the car moves at the same spend on the straight as cornering.
So you could then have speeds for each path section, but you would need many speed set points, or blend the speeds, otherwise you'll get jerky speed changes.
Or you could go for full car simulation, and use an A* to build the optimal path. That's over kill but very cool.
If there is only going forward and backward, and you know that you want to go forward, you could just look at the cells around you, find the ones that are the color of the road and move so you stay in the center of the road.
If you assume that you won't have abrupt curves then you can assume that the road is directly in front of you and just scan to the left and right to see if the road curves a bit, to stay in the center, to cut down on processing.
There are other approaches that could work, but this one is simple, IMO, and allows you to have gentle curves in your road.
Another approach is just to have it be tile-based, so you just look at the tile before you, and have different tiles for changes in road direction an so you know how to turn the car to stay on the tile.
This wouldn't be as smooth but is also easy to do.