Криво работает свой 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 для дуины на меге жирноват этот вариант, есть же другие алгоритмы.