If I give bodies different densities/mass, they still fall with the same speed. I know about the fact that in a place without air-resistance, mass doesn't affect falling speed.
But then, how do I logically make, let's say a balloon and a brick, fall at different speeds? The closest way I could think of is to use setGravityScale to set this all..
The best method to simulate the air speed reduction effect in box2d is to use "damping".
see: http://www.box2d.org/manual.html
"Damping is used to reduce the world velocity of bodies. Damping is different than friction because friction only occurs with contact. Damping is not a replacement for friction and the two effects should be used together."
"Damping parameters should be between 0 and infinity, with 0 meaning no damping, and infinity meaning full damping. Normally you will use a damping value between 0 and 0.1. I generally do not use linear damping because it makes bodies look floaty."
bodyDef.linearDamping = 0.0f;
bodyDef.angularDamping = 0.01f;
One option is to disable gravity and apply the accelerations you want each frame yourself. That's the route I went in my game. Box2d's built in gravity is ok for quick simulations, but it isn't very customizeable.
Once you've disabled gravity, you have to decide which acceleration formula to apply to your objects. There are several different models of fluid resistance (check Wikipedia), so you'll have to experiment and pick the one that looks the best.
Related
I implemented the diamond square algorithm in Java, but i'm not entirely satisfied with the results as a height map. It forms a lot of "lakes" - small areas of low height. The heights are generated using the diamond square algorithm, then normalized. In the example below, white = high, black = low and blue is anything below height 15: a placeholder for oceans.
This image shows the uncolored height map
How can I smooth the terrain to reduce the number of lakes?
I've investigated a simple box blurring function (setting each pixel to the average of its neighbors), but this causes strange artifacts, possibly because of the square step of the diamond square.
Would a different (perhaps gaussian) blur be appropriate, or is this a problem with my implementation? This link says the diamond square has some inherent issues, but these don't seem to be regularly spaced artifacts, and my heightmap is seeded with 16 (not 4) values.
Your threshold algorithm needs to be more logical. You need to actually specify what is to be removed in terms of size, not just height. Basically the simple threshold sets "sea level" and anything below this level will be water. The problem is that because the algorithm used to generate the terrain is does so in a haphazard way, small areas could be filled by water.
To fix this you need to essentially determine the size of regions of water and only allow larger areas.
One simple way to do this is to not allow single "pixels" to represent water. Essentially either do not set them as water(could use a bitmap where each bit represents if there is water or not) or simply raise the level up. This should get most of the single pixels out of your image and clear it up quite a bit.
You can extend this for N pixels(essentially representing area). Basically you have to identify the size of the regions of water by counting connected pixels. The problem is this, is that it allows long thin regions(which could represent rivers).
So it it is better to take it one step further and count the width and length separate.
e.g., to detect a simple single pixel
if map[i,j] < threshold && (map[i-1,j-1] > threshold && ... && map[i+1,j+1] > threshold) then Area = 1
will detect isolated pixels.
You can modify this to detect larger groups and write a generic algorithm to measure any size of potential "oceans"... then it should be simple to get generate any height map with any minimum(and maximum) size oceans you want. The next step is to "fix" up(or use a bitmap) the parts of the map that may be below sea level but did not convert to actual water. i.e., since we generally expect things below sea level to contain water. By using a bitmap you can allow for water in water or water in land, etc.
If you use smoothing, it might work just as well but you still will always run in to such problems. Smoothing reduces the size of the "oceans" but a large ocean might turn in to a small one and a small one eventually in to a single pixel. Depending on the overall average of the map, you might end up with all water or all land after enough iterations. Blurring also reduces the detail of the map.
The good news is, that if you design your algorithm with controllable parameters then you can control things like how many oceans are in the map, or how large they are, how square they are(or how circular if you want), or how much total water can be used, etc).
The more effort you put in to this you more accurate you can simulate reality. Ultimately, if you want to be infinitely complex you can take in to account how terrains are actually formed, etc... but, of course, the whole point of these simple algorithms is to allow them to be computable in reasonable amounts of time.
I'm looking for a way/algorithm to make a robot balloon fly to a certain altitude. The robot is controlled by a Raspberry Pi and has a propeller. Propeller speed can be set to several values (it uses PWM so technically 1024 different power outputs).
The balloon has a distance sensor pointing down, so it's possible to get the current height several times per second.
Only idea I had so far was to measure the height constantly and set to max speed based on the height left to travel. This doesn't seem like the best option though, but can't figure out how to fit all power outputs in.
Any ideas would be welcome. I'm using Java to code the project but any high-level algorithm/description would be great!
Thx,
Magic
There is a great "game" available that lets you try and play around with exactly that problem: Colobot (seems to be open source now). Create a Winged-Grabber (or shooter if you are more the FPS type of person) and try to get it to fly to a specific destination using only the altitude and motor controls.
in general the Pseudo-Code by MadConan is the way to go, however the main task lies in writing a smart setPower function. In the end you need some smoothing function that reduces the power in relation to how close you are to your desired altitude, however the exact values of that function completely depend on your hardware and the weight of your final system.
Depending on how valuable and/or fragile your setup will be in the end, you might want to develop a learning system, that takes the under-/overshot as a basis to adjust the smoothing function while it runs. Make sure to take factors like up-/down-wind into your calculation.
Pseudo code.
while(true){
val height = getHeight(); // from sensor
// Get the difference between the current height and
// the TARGET height. Positive values mean too low
// while negative values mean too high
val offset = TARGET_VALUE - height;
// Set the power to some direct ratio of the offset
// When the baloon is at 0 height, the offset should
// be relatively high, so the power will be set
// high. If the offset is negative, the power will be
// set negative from the current power.
setPower(offset);// I'll leave it up to you to figure out the ratio
}
I'm currently making a top down gfx actiong RPG on java, using jbox2d. Basically I want the enemies to recoil back after they get hit by the player (with top down graphics I don't have friction or gravity). I tried with restitution, applying impulse and setting linear velocity but I didn't get what I expected: the enemies teleport to the destination istantly and if they are near the wall they get ported out of the map. How can I fix this and what is the best to do it in your opinion? thanks a lot
I don't know how you are using jbox2d and c++ at the same time...
Regardless, if your enemies are represented physically by b2_dynamicBodys then you probably want to apply a linear impulse and set the linear damping of the enemy body to a value greater than zero. Linear damping works like air drag - The faster the object is moving, the larger the force applied in the opposite direction. Applying a large linear impulse and setting a high linear damping will cause your enemies to fly away from your hero with a very high initial velocity, but they will come to rest very quickly.
I hope this helps!
I am creating vehicle like this on the image:
As you can see, there is:
1) main vehicle body (Red rectangle)
2) wheels
3) vehicles arm (black rectangle)
Arm is connected with vehicles main body using Revolute joint in shown anchor center point, this arm can be moved up and down (with following angle limits) so as you can see it can move in 90 degrees only.
My question is, I am moving this arm by applying angular impulse, it works, I can move arm, but it keeps falling down to the default position. I am struggling how to "disable" joint, so arm can be moved only using my controller so its not affected by gravity, so player can move arm slightly up for example and arm should stay in this position, instead of falling down.
Any help would be great, thanks.
The best way to disable gravity impact is to set gravityScale to zero at b2BodyDef. But this parameter appeared only in last versions of Box2D, and, maybe, there is no such thing in your java port
Anyway, your idea with gravity isn't so good I think. It is not physic, not realistic and you can find some related troubles because of this. For example, what if some another force, except gravity, will impact the arm? It will cause all the same problem.
In my opinion, better way to make the arm - use motor of revolute joint. Some tutorial you can find there in section "Revolute joint motor". You can enable/disable motor and change its speed run-time to simulate vehicle logic. In addition, it may be useful also change run-time upper/lower limits of the joint, to prevent arm moving when no action preformed. Another way to achieve this - set motor speed to zero, that will transform motor into some kind of friction force.
I'm doing simple collisions on moving, coloured pixels. If their velocity get's higher than 1, the pixels may pass through something in the static world I'm trying to collide with.
How do I compensate for this?
This C++ example uses a vector based approach to predicting the paths of particles undergoing elastic collisions. This Java example is similar, rewinding to the start of a collision between particles when overlap is detected. In each, the critical element is separating the model from the view. By doing so, it's possible to iterate the model at 1 pixel/tick and update the view at a different, variable rate.
The article 2-Dimensional Elastic Collisions without Trigonometry may also be helpful.