Current aerodynamic slowdown is calculated roughly equivalently to:
200 / (200 + 30 * num_strongly_blocking + 10 * num_weakly_blocking). This multiplier affects safe speed, maximum speed and (inverted) vehicle strain at given speedIt has some limitations:
But then, I don't have a good idea on how to fix that. The best I can come up with is penalizing "extra" parts (superficial roofs), penalizing non-enclosed tiles (those that count as outside) slightly, and penalizing tiles with lots of part volume on them (stacked batteries, cargo holders, armor etc.).
I have a complex idea which involves physics but I think you need something simple, right?
F = A_C_p*v^2 / 2
A - area of intersection
C - drag coeff.
p - air density
v - speed of the body
The hardest thing is to implement finding A (pretty easy if you know what to do) and C (pretty hard but possible to approximate)
I'm mostly concerned about the C part.
Recently I was reproducing #15798. The described setup (V12 on a bicycle) gave me a hyper sonic bicycle: Safe/Top Speed: 4070/11541 km/h
4070 km/h (3,3 M) is a safe speed for a bicycle, Coral! I believe it has something to do with aerodynamics.
I'm mostly concerned about the C part.
IMHO it should be added to vehicles JSON. Damages/embellishments could modify the value (e.g. they could have their own drag coefficients).
F = ACp*v^2 / 2
v^2 is the most important part here. The current formula is linear which causes these miracles. We could even end up having something like this: factor * v^2 and calculate the factor from a base value (JSON) and the mentioned modifiers.
IMHO it should be added to vehicles JSON.
That could easily lead to discrepancies, where a tank built from a car stripped down to the last frame has a different coefficient than the same tank made from the last tile of a truck.
It must be calculable, not a parameter.
I'm mostly concerned about the C part.
https://en.wikipedia.org/wiki/Drag_coefficient
Here are Cs for some shapes
What you need is to approximate the shape of the vehicle and translate it into one of these shapes or split vehicle into a number of these shapes and find _k_ by using them. You don't even need to approximate the shape of the whole vehicle, you only need to account for the front line.
Now that's a problem we need to tackle here which is to come up with an algorithm to compare car's shape to known shapes.
What you need is to approximate the shape of the vehicle and translate it into one of these shapes
The problem is, the vast majority of cars in the game won't have any of those shapes. Trucks and RVs will be similar to long cylinder, but that's it. Not one of those shapes will work for the regular car of type car.
Hm, true. Well, I don't think creating 3D voxel models of vehicles and simulating air-flow is going to work that easily. It's possible, just way too overboard for something like that.
Would it make it better if we still disregarded overall shape of the
vehicle, but had finer graduations for a component's contribution to
cross-section? E.g. a door is full height, but it doesn't normally present
it's cross section to the front of the vehicle, so quarter panels and doors
should present less than e.g windscreens.
To avoid over compensating in the other direction, we might want to only
discount these parts if they have an open space next to them.
Expanding on Kevin's comment (and taking a few pages from what From the Depths does):
For each frame, find the largest part cross section and the largest part drag coefficient; but allow aerodynamic parts (quarterpanel, etc) to reduce or cap the drag coefficient (as they cover up other parts). You could adjust these parameters based on adjacent frames, part damage, etc.
Then cast a ray per Y coordinate starting from the front. Track total drag (initially 0) and cross-sectional airflow (initially 1)
For each frame in order:
The idea being that you pay a cost for increasing the vehicle's cross-section at the point where the airflow first hits it (and that is the point where adding fairings etc have most benefit), and frames behind an obstruction are sheltered by it. So adding a fairing to the front of a brick would work.. while the fairing is intact.
I'll try to write a Python script to show what might be done with the idea.
So I did.
Well, it's kinda bad but still, here is the script. I commented the hell out of it so you should be able to use it and get the idea. http://rghost.net/8HVSbMBFs
Run cataclysmdda.py
Play around with vehicle_layout, you should be able to easily understand how to do that.
It's kinda bad, but should work just fine. Sorry, diagonal walls are a pain in the ass.
http://i.imgur.com/8cxCOZJ.png
The value after the map is basically k for that vehicle, that is 0.5*A*C*p.
Anyway, the idea is that it is sort of an antiforce that is applied to the car with accordance to k*v^2. It works just like an engine but in reverse. Fiddle around with constants to make that k meaningful and you should be done. The "hardest" part is creating models for parts.
Here is another boat:
http://i.imgur.com/h4POwtI.png
@EditorRUS , I believe p (air density) is not a constant, it is a function of temperature and pressure https://en.wikipedia.org/wiki/Density_of_air , which are definitely varying in the game.
Total drag in the @mutability 's formulae is essentially a drag area. Here is some reference values:
Average full-size passenger cars have a drag area of roughly (0.790 m2). Reported drag area ranges from the 1999 Honda Insight at (0.474 m2) to the 2003 Hummer H2 at (2.44 m2).
http://www.batoautomoto.com/CarAerodynamics.asp
https://en.wikipedia.org/wiki/Automobile_drag_coefficient#Drag_area
@EditorRUS , I believe p (air density) is not a constant, it is a function of temperature and pressure https://en.wikipedia.org/wiki/Density_of_air , which are definitely varying in the game.
They don't vary that much and it's definitely not something you need to account for. Let's just imagine we have equal distribution of air density. Changing it won't really do much. Unless somebody implements flight or something in which case we'll probably need to add barometric formula too.
As of "drag area", my script actually accounts for how air flow interacts with car's exteriors and interiors. It doesn't explicitly defines drag area because the idea here is that you need to draw simple models of car parts and blow some air at it and see what's going on.
This is how diagonal wall to the right looks like in that kind of form:
\\....
-\\...
--\\..
---\\.
----\\
The air will hit these and be slightly redirected to go around that wall making what you can see here
https://i.imgur.com/e9hoK6Y.png
Since air already hits some area and gets redirected, some of air force will be applied to that part and therefore to the whole vehicle. My script basically traces these changes in magnitude and direction and outputs sum of all these changes therefore making "k" value which is A and C altogether and p and v just as undefined variables
All that's needed is to balance that thing out and find reasonable absorption coefficients. Hitting a penpedicular flat plane will block air flow entirely and therefore apply the whole force to it whereas hitting a parallel flat plane will only absord so much and only because there is some thickness to that plane (that coeff is called "thickness_absorb_coeff" in the script). Hitting a slightly rotated plane will change direction of air flow and absorb some part of its force and hitting a plane which will result in 90 degrees rotation will absorb a lot of power from that hit but still not as much as hitting essentially wall.
Sorry, I am not going to implement actual pressure/velocity system for that, I only wanted to show the concept.
But how can you apply your model to the ingame cars? Or in another words how to improve ingame car model to fit realistic aerodynamics?
Take for example motorcycle and superbike. Both of them have one blueprint
o#>o
Inner parts of the superbike:
frame_vertical + wheel_motorbike_steerable
frame_handle + headlight + gas_tank_small + battery_motorbike
frame_vertical_2 + saddle + controls + vehicle_alarm + engine_inline4 + alternator_motorbike
frame_vertical + wheel_motorbike
... motorcycle:
frame_vertical + wheel_motorbike_steerable
frame_handle + headlight + gas_tank_small + battery_motorbike
frame_vertical_2 + saddle + controls + vehicle_alarm + horn_car + engine_vtwin + alternator_motorbike
frame_vertical + wheel_motorbike + box
As you can see there isn't much difference. Motorcycle has a different engine and additional horn plus box. However it's drag area may be twice bigger than of a suberbike (0.5 m2 vs 0.25 m2) according to https://books.google.com.ua/books?id=rJTQxITnkbgC&pg=PA75&lpg=PA75&dq=motorcycle+drag+area&source=bl&ots=DZfVFehPwF&sig=WGsIr64iPejr18u76aO_EAQyY6k&sa=X&sqi=2&ved=0ahUKEwjiwNiZpdTLAhVHfHIKHb-CCwcQ6AEIGjAA#v=onepage&q=motorcycle%20drag%20area&f=false _(it also contains additional info on topic, worth looking!)_.
@Isk1n I'm guessing the superbike should have some cowling parts to reduce its drag. We can implement those if we have a working (simplified) model of aerodynamics.
But how can you apply your model to the ingame cars? Or in another words how to improve ingame car model to fit realistic aerodynamics?
Same applies here. You need to create simple "models" for external parts. Not just that, you can also mix them together on the resulting air-testing virtual map (which is essentially a two dimensional array of symbols).
Say we have a box which has that model:
.....
.---.
.|.|.
.---.
.....
Let's imagine we also have a spike plating on it which has this model:
(I am not sure how spiked plating looks like, but...)
..|..
./.\.
.|.|.
.|.|.
.\-/.
Now since spiked plating is the outermost part here, its model is used in the air testing instead of model of the box. I don't really force any limits for model sizes, you can use not just 5x5 map, but also 15x15, 20x20 or whatnot, it only matters if you want that much of detailing to be accounted for in the actual airtesting. If you really want to go overboard, you can also implement the third dimension, it's not that hard actually. Slapping parts together on 3D map is harder than it is on 2D but totally worth it.
Also for the sake of being fair, air drag should also be computed from down to up because players also move backwards sometimes. But I think it's not that needed.
So in case of superbike the box is the only difference that matters in those two models as it is an external part and it should be accounted for.
Anyways, I did my thing, I suggested how to implement aerodynamics and even threw some code to show how to implement that and I am done.
Overall idea of calculating drag force by summing pressure over area is good. But I don't really like
the idea here is that you need to draw simple models of car parts and blow some air at it and see what's going on.
It seems very tedious.
Instead we can treat each car tile as whole and calculate fractions of air being deflected to the left, to the right and to the top (assuming air flows from the front to the rear), for example [0.7, 0, 0.2].
1 - (0.7+0+0.2) = 0.1 being applied pressure. Basically it is an approach, proposed by @mutability , plus one dimension.
Evaluated at constant velocity and air density total drag force should be normalized to represent drag area, which is known for some vehicles. Such drag area should be recalculated each time car part being changed.
Equation for a tile's air deflection fractions should account presence of ajacent tiles, combination of frame + armor, external parts, state of parts.
Lastly
Also for the sake of being fair, air drag should also be computed from down to up* because players also move backwards sometimes.
*from rear to front
I suppose it's my turn to write some scipts
Instead we can treat each car tile as whole and calculate fractions of air being deflected to the left, to the right and to the top (assuming air flows from the front to the rear), for example [0.7, 0, 0.2].
This method will have problems with air that flows _not_ just from front to rear.
Imagine we have just a vertical wall:
|
|
|
Let's blow some air from right to left and to rear.
| /
|?
|
And how are you going to deal with that kind of situation if you don't know how that part looks like?
The only reason you would need 3 directions here is to simulate air flow but instead of using symbolic models, you just define what that part essentially is going to do with penpedicular flow.
You could add more data but in fact that will be just as tedious as my method. Not just that, it also is not really representative as you use vague numbers.
You could come up with some weird formula to translate that data but that still is not going to work that well since that data only represents how air works with front part of the part.
So what are you going to do?
In my approximation air always flow from front to rear (or vice versa), I evaluate projection of drag force opposite to the vehicle movement. Deflecting left or right just means more air in the tile left behind or right behind. Deflecting to the top means more air in the tile directly behind. I can substract from the amount of air that came in amount of air that came out and that would be total drag.
I think that a simple system is the best. Non-blocking tiles, sleek tiles, and blocking tiles. Raycast from front, if a nonblocking tile is hit, set air blocking to 5, if sleek tile is hit, replace that with 10, if blocking tile is hit, do 30 for just blocking tile or 15 for sleek->blocking.
Not only is it a simple formula, but it is largely analogous to the current one, which means you can transplant the current numbers and tweak them into something that makes a bit more sense overall.
I'd be very interested to see what kind of impact we'd see from taking an
average coefficient and area calculation similar to what we already have vs
a more complicated system. I suspect the difference is negligible.
Places this impacts the game:
Vehicle range when traveling at "cruising speed" e.g. highway type travel.
(This almost never happens)
Max speed for purpose-built drag racers (honestly this isn't super
compelling to make accurate)
Vehicle range under stop and go conditions (I suspect the impact of drag
being inaccurate here is minimal since v^2 will be very low)
What I'd like to see is switch the formula to square with velocity and have
a simple unit test to validate that resulting drag for some sample
predefined vehicles is good-ish. If that's not good enough I'd like to see
some test cases in said unit test that demonstrate a game-impacting
problem, then we can fix that and repeat until it's good enough.
Don't discard the value of simple systems, being simpler to reason about is a good enough reason to keep them that way. I'd say that what's already here probably already leaves enough people scratching their heads.
Kevin Granade notifications@github.com wrote:
I'd be very interested to see what kind of impact we'd see from taking an
average coefficient and area calculation similar to what we already have vs
a more complicated system. I suspect the difference is negligible.
Places this impacts the game:
Vehicle range when traveling at "cruising speed" e.g. highway type travel.
(This almost never happens)
Max speed for purpose-built drag racers (honestly this isn't super
compelling to make accurate)
Vehicle range under stop and go conditions (I suspect the impact of drag
being inaccurate here is minimal since v^2 will be very low)What I'd like to see is switch the formula to square with velocity and have
a simple unit test to validate that resulting drag for some sample
predefined vehicles is good-ish. If that's not good enough I'd like to see
some test cases in said unit test that demonstrate a game-impacting
problem, then we can fix that and repeat until it's good enough.--
You are receiving this because you commented.
Reply to this email directly or view it on GitHub:
https://github.com/CleverRaven/Cataclysm-DDA/issues/15839#issuecomment-271468988
No discussion in over a year, closing.
I wonder if we should add an "unresolved" label to cover valid issues that
were off-topic, simply ran out of steam or listed a bunch of issues.
Hopefully these would be a relatively small number, and filtering on this
label would be a meaningful search.
Sounds good to me. If the number of such issues is high enough, you could always create a few "priority" variants of the tag, with the issues passing to the next one once no one cared about them for a long enough time.
Most helpful comment
I wonder if we should add an "unresolved" label to cover valid issues that
were off-topic, simply ran out of steam or listed a bunch of issues.
Hopefully these would be a relatively small number, and filtering on this
label would be a meaningful search.