Третий день пытаюсь реализовать реалистичный отскок, вроде того, который был у гранаты в Worms 2D. Перепробовал несколько алгоритмов, но все они работают плохо.
Основная трудность заключается в том, что объект должен отскакивать от растра, который, естественно, представлен в виде пикселей - проходимых и непроходимых.
Если сделать объект точечным и отражать угловую скорость при контакте с непроходимыми пикселями, то при касательном отскоке граната отлетает обратно, то есть угол получается неправильный. Да и при некасательном отскоке угол получается неестественный.
Попытался определять, какие непроходимые пиксели попадают внутрь оболочки гранаты в потенциальной позиции. Затем я строю вектор для каждого такого пикселя - от пикселя к центру гранаты. Все вектора всех пикселей складываются, а потом нормализуются. Я надеялся, что это позволит мне получить вектор взаимодействия с землей в точке касания (нормаль).
Это тоже почему-то не работает. Объект лишь иногда отскакивает нормально.
Я бы хотел узнать вот что:
Пытаюсь делать так:
velocity_x -= 2 * velocity_x * normal_x;
velocity_y -= 2 * velocity_y * normal_y;
Вот тестовый код, если кому-то интересно:
void Grenade::processing(float _dt, Image &ground)
{
velocity_y += GRAVITY * _dt;
auto checkArea = [](const size_t _x, const size_t _y)->bool
{
if ((_x >= 0U) && (_x < WINDOW_WIDTH) && (_y >= 0U) && (_y < WINDOW_HEIGHT))
{
return true;
}
else {
return false;
}
};
auto checkCollision = [&ground, &checkArea](const size_t _x, const size_t _y)->bool
{
if (checkArea(_x, _y) == true)
{
auto pixel = ground.getPixel(_x, _y);
if (pixel.a != 0)
{
return true;
}
}
return false;
};
const float new_x = x + velocity_x * _dt;
const float new_y = y + velocity_y * _dt;
float force_x = 0.f;
float force_y = 0.f;
for (int ix = new_x - GRENADE_RADIUS; ix < new_x + GRENADE_RADIUS; ++ix)
{
for (int iy = new_y - GRENADE_RADIUS; iy < new_y + GRENADE_RADIUS; ++iy)
{
if (checkCollision(ix, iy) == true)
{
const float fx = ix - new_x;
const float fy = iy - new_y;
const float fr = sqrt(pow(fx, 2) + pow(fy, 2));
if (fr <= GRENADE_RADIUS)
{
force_x += fx / fr;
force_y += fy / fr;
}
}
}
}
if ((force_x != 0.f) || (force_y != 0.f))
{
const float force_r = sqrt(pow(force_x, 2) + pow(force_y, 2));
force_x /= force_r;
force_y /= force_r;
velocity_x -= 2 * velocity_x * force_x * ELASTICITY;
velocity_y -= 2 * velocity_y * force_y * ELASTICITY;
}
else {
x = new_x;
y = new_y;
}
}
Мне удалось выяснить, что отскок происходил неправильно из-за того, что я рассчитывал новую скорость по неправильной формуле.
Правильная:
velocity_x = velocity_x - 2 * force_x * (force_x * velocity_x + force_y * velocity_y);
velocity_y = velocity_y - 2 * force_y * (force_y * velocity_y + force_x * velocity_x);
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
При отладке функции rand() вылезает ошибка: Не удалось найти файл /build/glibc-LK5gWL/glibc-223/stdlib/random
Есть вот такой кодПри уменьшении ширины добавил скролл по оси x но элементы текст перепрыгивает на вторую строчку
Я хочу чтобы url выводилося названия статьи типо programs/kak-vzlomat-jopu или как то такИ еще настораживает то что как рагумент берет slug : 13 а это вообще...