Криво работает свой RayCasting.
- Войдите на сайт для отправки комментариев
Втр, 28/12/2021 - 19:08
Всех приветствую!
Недавно я решил сделать что-то наподобие 3D бродилки на Arduino, поискал немного на эту тему, далее все понял и начал кодить. Сперва получалось все хорошо, но когда дело дошло до угла обзора (FOV) возникла проблема.
Цикл, который высчитывает расстояние до объекта решил пускать столько лучей, сколько ему вздумается. Затем я путем "Научного Тыка" нашел закономерность: Чем больше переменная playerA (это угол между осью Х и основным лучём взгляда), тем меньше цикл пускает лучей.
Вот код:
const size_t kart_w = 16; //Ширина карты const size_t kart_h = 16; //Высота карты const char kart[] = "################"\ "# #"\ "# ##### #"\ "# # #"\ "# # #######"\ "# # #"\ "# ##### #"\ "# # ##### #"\ "# # # #"\ "# # # #####"\ "# # #"\ "# # #"\ "# # #"\ "# ####### #"\ "# #"\ "################"; //Сама карта unsigned int playerX = 5; // Координаты unsigned int playerY = 3; // игрока unsigned int playerA = 0; // Угол основного луча const unsigned int fov = 128; //FOV или в моем случае, сколько будет кидаться лучей. void setup() { Serial.begin(115200); // Ну тут понятно while (!Serial) { ; } } void loop() { float c = 0; //В будущем здесь будет расстояние unsigned int player_A = playerA; //НЕ основной луч for (unsigned int now = 0; now <= fov; now++) { player_A = playerA + now; //Определяем угол луча, который будем обрабатывать. if (player_A >= 360) {player_A=360-player_A;} //Защита от углов, которые больше 360 градусов. for (; c<=20; c=c+0.05) { //Цикл определения расстояния от игрока до предмета по заданному лучу. float x = playerX + c*cos(player_A); float y = playerY + c*sin(player_A); if (kart[int(x)+int(y)*kart_w]!=' ') { //Если замечено столкновение Serial.print("Distance: "); //Здесь по идее должна распологаться функция отрисовки, но пока я оставил на выводе информации. Serial.print(c); Serial.print(". Player_A is now: "); Serial.print(player_A); Serial.print(". Now: "); Serial.print(now); Serial.print(".\n"); break; } } } }
Я получаю следующий лог:
18:03:59.231 -> Distance: 1.00. Player_A is now: 0. Now: 0. 18:03:59.231 -> Distance: 1.90. Player_A is now: 1. Now: 1. 18:03:59.271 -> Distance: 9.65. Player_A is now: 2. Now: 2. 18:03:59.311 -> Distance: 15.20. Player_A is now: 3. Now: 3. 18:03:59.311 -> Distance: 15.20. Player_A is now: 4. Now: 4. 18:03:59.311 -> Distance: 15.20. Player_A is now: 5. Now: 5. 18:03:59.311 -> Distance: 15.20. Player_A is now: 6. Now: 6. 18:03:59.311 -> Distance: 15.20. Player_A is now: 7. Now: 7. 18:03:59.351 -> Distance: 17.20. Player_A is now: 8. Now: 8. 18:03:59.351 -> Distance: 18.70. Player_A is now: 9. Now: 9. 18:03:59.351 -> Distance: 18.70. Player_A is now: 10. Now: 10. 18:03:59.351 -> Distance: 18.70. Player_A is now: 11. Now: 11. 18:03:59.351 -> Distance: 18.70. Player_A is now: 12. Now: 12. 18:03:59.351 -> Distance: 1.00. Player_A is now: 0. Now: 0. 18:03:59.391 -> Distance: 1.90. Player_A is now: 1. Now: 1. 18:03:59.431 -> Distance: 9.65. Player_A is now: 2. Now: 2. 18:03:59.471 -> Distance: 15.20. Player_A is now: 3. Now: 3. 18:03:59.471 -> Distance: 15.20. Player_A is now: 4. Now: 4. 18:03:59.471 -> Distance: 15.20. Player_A is now: 5. Now: 5. 18:03:59.471 -> Distance: 15.20. Player_A is now: 6. Now: 6. 18:03:59.471 -> Distance: 15.20. Player_A is now: 7. Now: 7. 18:03:59.471 -> Distance: 17.20. Player_A is now: 8. Now: 8. 18:03:59.471 -> Distance: 18.70. Player_A is now: 9. Now: 9. 18:03:59.471 -> Distance: 18.70. Player_A is now: 10. Now: 10. 18:03:59.471 -> Distance: 18.70. Player_A is now: 11. Now: 11. 18:03:59.511 -> Distance: 18.70. Player_A is now: 12. Now: 12. 18:03:59.511 -> Distance: 1.00. Player_A is now: 0. Now: 0. 18:03:59.511 -> Distance: 1.90. Player_A is now: 1. Now: 1. 18:03:59.551 -> Distance: 9.65. Player_A is now: 2. Now: 2. 18:03:59.591 -> Distance: 15.20. Player_A is now: 3. Now: 3. 18:03:59.591 -> Distance: 15.20. Player_A is now: 4. Now: 4. 18:03:59.591 -> Distance: 15.20. Player_A is now: 5. Now: 5. 18:03:59.591 -> Distance: 15.20. Player_A is now: 6. Now: 6. 18:03:59.591 -> Distance: 15.20. Player_A is now: 7. Now: 7. 18:03:59.631 -> Distance: 17.20. Player_A is now: 8. Now: 8. 18:03:59.631 -> Distance: 18.70. Player_A is now: 9. Now: 9. 18:03:59.631 -> Distance: 18.70. Player_A is now: 10. Now: 10. 18:03:59.631 -> Distance: 18.70. Player_A is now: 11. Now: 11. 18:03:59.631 -> Distance: 18.70. Player_A is now: 12. Now: 12. *Бесконечный цикл*
Здесь цикл отрабатывает только 13 лучей из 128, хотя должен отработать все.
Я пытался исправить эту ошибку, но не смог. Помогите исправить пожалуйста.
У Вас в цикле строки № 34 переменная "с" постоянно растёт и никогда не уменьшается. Когда она достигает 20.05 цикл в строке №39 просто перестаёт работать - в него программа не заходит. Всё, приплыли.
Вставьте печать "с" после строки №36 и после строки №50 и всё увидите.
Спасибо. Я даже не заметил этого.
Вы прям изображение решили строить с помощью обратной трассировки ? IMHO для дуины на меге жирноват этот вариант, есть же другие алгоритмы.