Здесь опишу реализацию всего того что сделано в данной версии
Расчет температуры относительно высоты: Здесь все очень просто. Одна небольшая формула. Но очень большая помощь в будущем. Так как от температуры воздуха зависит многое. Далее об этом поговорим.
Вот вам формулка
Код
float CalculateTemperatureK()
{
return 288.15f-(0.00287142f*transform.position.y);
}
Мы создали метод который вернет нам температуру. Изучим его подробнее. "288.15f-(0.00287142f*transform.position.y);" Начнем слева направо: Что здесь означает 288.15f? - Это температура воздуха в Кельвинах от которой мы отталкиваемся. Это международная константа, стандартная температура на уровне моря;
А что мы делаем здесь -(0.00287142f*transform.position.y)? - Здесь мы умножаем скорость падения температуры на нашу высоту и в полной формуле "288.15f-(0.00287142f*transform.position.y);" Мы из средней температуры вычитаем полученное после умножения число. В итоге мы получим температуру в Кельвинах на нужной нам высоте. Почему именно Кельвины? Во многих формулах нужны именно Кельвины. Если же вам интересно то в 1С(цельсий) = 274.15К, 288.15К = 15С. На уровне моря 15С. От этой температуры мы и отталкиваемся. Что бы перевести из Цельсия в Кельвин нужно просто из нужно температуры в Кельвинах вычти 274.15. И вы получите температуру в Цельсиях
Расчет атмосферного давления относительно высоты: Здесь тоже ничего сложного. Но есть один нюанс. Позже о нем напишу
Формула:
Заметьте. Эта формула для идеального газа - которого не существует! Пока пусть это будет так. Не знаю по каким причинам но формулы для реального газа дают очень большую погрешность.
Код
float CalculatePressurePascal(float _T)
{
return 101325f*Mathf.Exp(-0.0289644f*9.80665f*(transform.position.y/(8.31447f*_T)));
}
Как видите здесь появился аргумент. В этот метод нужно передавать температуру которую мы выше считали. Если все правильно то на высоте 1км давление должно быть ~89800Па а температура 285.2К. Формулу разбирать не буду. Кому интересно тот сам разгребет в общих чертах все так же. Опорное давление 101325Па международная константа, давление на уровне моря.. А далее из нее вычитаем то что получится в объятиях экспоненты.
Расчет плотности воздуха относительно высоты над уровнем моря: Здесь все аналогично, но появляется еще одни аргумент.
В аргументы мы передаем рассчитанную выше температуру в Кельвинах и давление в Паскалях.
На выходе получаем плотность воздуха. Все динамично, все считается, без констант (только постоянные величины).
Формула:
Код
float CalculateAirDensity(float _t, float _p)
{
return (_p*M)/(R*_t);
}
Вот как то так. Спасибо за внимание. На этой части программы. Это были самые простые расчеты. Я буду двигать по общей формуле от простого к сложному. Сделаю себе кофе продолжим =D
Расчет относительной скорости полета: Итак. Давай те теперь попробуем посчитать относительную воздуху скорость. Скорость относительная воздуху - это скорость полета. А скорость полета зависит от сил сопротивления, гравитации, площади рабочей плоскости (крыла) и тд. Это вы увидите из формулы которая выглядит вот так:
V^2 = (2*G)/(Су*p*S) Из формулы видно, что скорость постоянна, пока постоянны все остальные параметры уравнения (полетный вес G, коэффициент подъемной силы Су, площадь крыла S, плотность воздуха) При их изменении равновесие сил нарушается. Полет перестает быть установившимся. Происходит переходный режим полета, во время которого меняется скорость полета и восстанавливается равновесие сил.
Давай те применим эту формулу
Код
float CalculateSpeed(float _G, float _S, float _p)
{
return (2*_G)/(0.04f*_p*_S);
}
Итак что мы видим. 3 аргумента. Сюда мы передаем выше рассчитанную плотность, полетный вес (это тот вес пилота с козявками + вес самого ЛА топлива в нем и тд) и еще передаем площадь рабочей плоскости (крыла) Но я пока просто передал площадь кубика который пока и есть моим ЛА.
Далее все считаем по выше написанной формуле и получаем скорость полета. (пока не окончательную!)
Двигаем далее.
Расчет подъемной силы: Здесь и понеслось самое интересно но в тоже время самое муторное (для меня)
Вот формул по которой мы будем считать:
Y = Cy*((p*V^2)/2)*S; Ну вот формула вроде и простая. Но с характером. Cy здесь это коэффициент подъемной силы, коэффициент подъемной силы - это величина, характеризующая подъемную силу крыла определённого профиля при известном угле атаки. Причем самое страшное что этот коэффициент определяется экспериментальным путём в аэродинамической трубе, либо по теореме Жуковского. Но здесь нам разницы нет. В аэротрубу мы бежать не будем.. Да сбегали бы но в моем городе и в ближайших нет таких достопримечательностей)) А по Жуковского аналогично.. Только здесь используют не воздух а воду. Я не стал заморачиваться и взял готовые константы для разных профилей. Итак перейдем к коду
Код
float CalculateAscensionalPower(float _p, float _V, float _S)
{
return 0.04f*((_p*_V)/2)*_S;
}
Как видим тоже ничего сложно кроме некоторых нюансов о которых расскажу позже.
Здесь 0.04 это наш Cy та константа о которой я говорил а далее 3 аргумента выше рассчитанная плотность, скорость, и площадь крыла.
Но я думаю вы заметили что в исходной формуле V скорость в квадрате. А у меня нет. Здесь простите но я не знаю что делать. И надеюсь на вашу помощь)) если подводить скорость в квадрат то она выходит очень большой и мы взлетаем с очень высокой скорость, потому как подъемная силы выходит здоровой. Ну не знаю может где то я допустил ошибку. Еще ни где не сказано в чем должна быть скорость в км/ч или в м/с... Ну ладно оставлю так как есть. Может кто найдет ошибку прошу писать не стеснятся =D
Ладно, с горем пополам бежим далее.
Расчет силы сопротивления: Хе, ну вот добрались и до нее.. Итак как обычно ловите формулку:
Как видите она очень похожа на формулу для расчета подъемной силы. Но отличается лишь коэффициентом Cx. Это коэффициент силы сопротивления. Так же устанавливается экспериментально вроде как.. Я взял значение 0.25. Вот вам кусок кода:
Код
float CalculareDragForse(float _p, float _V, float _S)
{
return 0.25f*((_p*_V)/2)*_S;
}
Видим уже привычные 3 аргумента. Плотность, скорость, и площадь крыла.
Ну вот посчитали)) Насчитали мы с вами уже много. Вопрос: Ну когда будет видимый результ? Ответ: Он уже есть!))
Мы уже можем заставить кубик лететь поднимаясь от скорости под подъемной силой, с учетом силы сопротивления. Пока этого мало. Но все же с этим то домучались. Впереди еще очень много расчетов, много московыносной математики физики и прочего. Я по кофе.. И продолжим. Думаю еще сделать пару законов. Ах да совсем забыл написать вам обвертку для всех этих расчетов. Вот готовый класс
Код
using UnityEngine;
using System.Collections;
public class PhysicsCast : MonoBehaviour {
public const float M = 0.0289644f; // Молярная масса сухого воздуха
public const float R = 8.31447f; // Универсальная газовая постоянная
public float Pressure=0.0f; // Давление
public float TemperatureC=0.0f; // Температура
public float AirDensity=0.0f; // Плотность
public float FlightSpeed=0.0f; // Скорость полета
public float AscensionalPower=0.0f; // Подъемная сила;
public float DragForse=0.0f; // Сила сопротивления
public Vector3 forse1;
public Vector3 forse2;
public Vector3 ff;
void Start ()
{
}
void Update ()
{
TemperatureC=CalculateTemperatureK();
Pressure=CalculatePressurePascal(TemperatureC);
AirDensity=CalculateAirDensity(TemperatureC, Pressure);
FlightSpeed=CalculateSpeed(100,120,AirDensity);
AscensionalPower=CalculateAscensionalPower(AirDensity, FlightSpeed, 120);
DragForse=CalculareDragForse(AirDensity, FlightSpeed, 120);
forse1 = new Vector3(0,AscensionalPower,0);
forse2 = new Vector3(DragForse,0,1);
ff=forse1+forse2;
rigidbody.AddForce(ff, ForceMode.Impulse);
}
float CalculatePressurePascal(float _T)
{
return 101325f*Mathf.Exp(-0.0289644f*9.80665f*(transform.position.y/(8.31447f*_T)));
}
float CalculateAirDensity(float _t, float _p)
{
return (_p*M)/(R*_t);
}
float CalculateSpeed(float _G, float _S, float _p)
{
return (2*_G)/(0.04f*_p*_S);
}
float CalculateTemperatureK()
{
return 288.15f-(0.00287142f*transform.position.y);
}
float CalculateAscensionalPower(float _p, float _V, float _S)
{
return 0.04f*((_p*_V)/2)*_S;
}
float CalculareDragForse(float _p, float _V, float _S)
{
return 0.25f*((_p*_V)/2)*_S;
}
void OnGUI()
{
GUI.Label(new Rect(0,0,1000,1000),
"Pressure: "+Pressure.ToString()
+ '\n' + "Temperature: "+TemperatureC.ToString()
+ '\n' + "Height: " + transform.position.y.ToString()
+ '\n' + "Air Density: " + AirDensity.ToString()
+ '\n' + "Flight Speed: " + FlightSpeed.ToString()
+ '\n' + "Ascensional Power: " + AscensionalPower.ToString());
}
}
Да.. забыл сказать.. Насчет силы сопротивления. Так как пока у нас нет реализации тяги некой что мы сделаем в следующей части (версии). То пока мы летим на силе сопротивления.. Извращение знаю обращать силу сопротивления против ее самой и делать из нее тягу... Но пока нет выхода) Далее сделаем) Всем спасибо за внимание. За поддержку. Тролям спасибо за настроение... Особенно про козявки.. Убило. Лан встретимся в след версии. А у меня чайник горит мать его.