В 3D пространстве имеется полигон, заданный массивом вертексов. Вертексы лежат в одной плоскости, которая в общем случае не параллельна плоскости XoZ, но плоскость не вертикальна, её проекция на XoZ имеет ненулевую площадь. Лицевой считается верхняя часть полигона, её нормаль заранее вычислена.
Сверху вниз вдоль строго вертикальной оси с известными координатами X и Z опускается сфера с радиусом R.
Необходимо узнать, коснётся ли сфера полигона. В случае касания нужно найти Y координаты центра сферы в момент касания и нормаль в точке касания. Под нормалью подразумевается вектор, направленный из точки касания к центру сферы.
Это всё желательно сделать оптимально с точки зрения быстродействия.
Я разделил задачу на три части:
1. Проверка касания с внутренней областью полигона.
Это проверяется просто. Умножаем нормаль полигона на -R, X и Z полученного вектора V прибавляем к X и Z оси сферы - если точка лежит внутри проекции полигона на XoZ, то соответствующая точка сферы - это и есть место касания, из координаты Y этой точки вычитает Y вектора V - получаем Y сферы в момент касания, нормаль равна нормали полигона.
2. Проверка касания с рёбрами полигона поочерёдно.
Тут основная загвоздка. Будь полигон параллелен XoZ, было бы просто - если проекция оси на XoZ (точка) проецируется на проекцию ребра на эту же плоскость, попадая между вершинами этого отрезка, и длина линии W последней проекции меньше R, то получили касание. Считаем W одним катетом, достраиваем второй вдоль Y ток, чтобы гипотенуза была равна R, получаем нормаль в точке проекции, высота тоже вычисляется не сложно, не буду останавливаться.
Но, когда полигон не параллелен XoZ, проекция на XoZ уже не помогает, радиус сферы не будет перпендикулярен проекции ребра на XoZ. Он будет перпендикулярен при проекции сферы на плоскость полигона, но в этом случае мы получаем невертикальную ось, её проекция уже не точка, а линия. Всё как-то сильно усложняется.
3. Проверка касания с вершинами полигона поочерёдно.
В случае выпуклых углов проекции оси могут не попасть на рёбра, но сфера касается вершины между ними. Поэтому проверяем касания с вершинамы, это просто - считаем отрезок, соединяющий проекцию оси сферы с проекцией вершины на XoZ отрезком W из предыдущего пункта, дальше так же.
Просьба поделиться мыслями по второму пункту, либо, возможно, вообще по альтернативному варианту решения задачи.