Member 11733943 Ответов: 1

Как получить все треугольники, затронутые светом или набором лучей?


Всем Привет!

Я работаю в приложении аэрофотосъемки, которое пытается определить, какая часть местности просматривается с аэрофотокамеры. Сначала я визуализировал DEM (цифровую модель рельефа) из существующего файла .tif, генерируя все треугольники сетки по позициям и значениям .tif. Я нашел решение, используя RayMeshGeometry3DHitTestResult, и посылая различные лучи от камеры. Проблема в том, что производительность очень низкая, потому что тест попадания нужно повторять тысячи раз, и он становится слишком медленным:


private static RayMeshGeometry3DHitTestResult rayHit;
       public static RayMeshGeometry3DHitTestResult SurfaceRayHit(Point3D p, Vector3D v)
       {
           RayHitTestParameters hitParams = new RayHitTestParameters(p,v);
           VisualTreeHelper.HitTest(App.AppDemModel, null, new HitTestResultCallback(MainDemHitPoint), hitParams);
           return rayHit;
       }

       public static HitTestResultBehavior MainDemHitPoint(HitTestResult result)
       {

           if (result.VisualHit == App.AppDemModel)
           {
               rayHit = (RayMeshGeometry3DHitTestResult)result;
               //rList.Add(hit);
               return HitTestResultBehavior.Stop;
           }


           return HitTestResultBehavior.Continue;
       }


Что я уже пробовал:

Я думаю, что это должно быть внутренне реализовано ViewPort3D (HelixViewport в моем случае), так как свет попадает только на определенные треугольники в Geometry3D, но я не мог найти способ получить список треугольников(вершин), затронутых светом.

Заранее спасибо, любая помощь будет действительно оценена по достоинству.

1 Ответов

Рейтинг:
2

Rick York

Есть тонны научных работ, написанных на эту тему или ее родственников, и есть несколько используемых тактик. Одним из наиболее распространенных является разделение сетки и проверка каждого деления. Как правило, это делается путем деления сетки на четверти и проверки попадания в каждую четверть, а затем для попадания в секции повторите процесс, который означает деление каждой из них на четверти и тестирование каждой из них.

Другой способ заключается в том, чтобы сначала определить область, просматриваемую камерой, а не методом трассировки лучей. Затем вы можете просто проверить, находятся ли треугольники в этой области. Можно также использовать подразделение. Возможно, будет проще проверить сетку в ее четырехугольной форме, если вы сохраните эти данные.

Если вы используете проверку расстояния путем вычисления величины вектора, то одна простая оптимизация производительности, которую вы можете сделать, - это не вычислять квадратный корень, потому что это обычно медленная операция. Вы можете сравнить квадрат величины (без квадратного корня) и получить те же результаты быстрее. Берите квадратный корень только тогда, когда вам нужно фактическое расстояние, а для сравнения оно вам не нужно.


Member 11733943

Большое спасибо, Рик! Я думаю, что подход содержания камеры является лучшим, проблема в том, как я могу получить треугольники, показанные в камере? Я также думаю, что что-то связанное с попаданием света также должно быть интересным, так как должна быть некоторая информация (внутренняя), которая представляет треугольники, где показан свет, удаляя непосредственно те, которые скрыты.