Как найти самую большую сферу, которую вы можете нарисовать в перспективе?
Если смотреть сверху, это будет так:
Добавлено: в области справа я выделил четыре точки, о которых, как мне кажется, мы кое-что знаем. Мы можем отменить проекцию всех восьми углов фруза, а также центров ближнего и дальнего концов. Итак, мы знаем точки 1, 3 и 4. Мы также знаем, что точка 2 - это то же расстояние от 3, что и 4 от 3. Итак, мы можем вычислить ближайшую точку на линии 1 - 4 до точки 2, чтобы получить центр? Но настоящая математика и код ускользает от меня.
Я хочу нарисовать модели (которые являются приблизительно сферическими и для которых у меня есть ограничивающая сфера для минибола) как можно большего размера.
Обновление: я попытался реализовать подход в виде круговой плоскости на двух плоскостях, как это предложили Бобобо и Натан Рид :
function getFrustumsInsphere(viewport,invMvpMatrix) {
var midX = viewport[0]+viewport[2]/2,
midY = viewport[1]+viewport[3]/2,
centre = unproject(midX,midY,null,null,viewport,invMvpMatrix),
incircle = function(a,b) {
var c = ray_ray_closest_point_3(a,b);
a = a[1]; // far clip plane
b = b[1]; // far clip plane
c = c[1]; // camera
var A = vec3_length(vec3_sub(b,c)),
B = vec3_length(vec3_sub(a,c)),
C = vec3_length(vec3_sub(a,b)),
P = 1/(A+B+C),
x = ((A*a[0])+(B*a[1])+(C*a[2]))*P,
y = ((A*b[0])+(B*b[1])+(C*b[2]))*P,
z = ((A*c[0])+(B*c[1])+(C*c[2]))*P;
c = [x,y,z]; // now the centre of the incircle
c.push(vec3_length(vec3_sub(centre[1],c))); // add its radius
return c;
},
left = unproject(viewport[0],midY,null,null,viewport,invMvpMatrix),
right = unproject(viewport[2],midY,null,null,viewport,invMvpMatrix),
horiz = incircle(left,right),
top = unproject(midX,viewport[1],null,null,viewport,invMvpMatrix),
bottom = unproject(midX,viewport[3],null,null,viewport,invMvpMatrix),
vert = incircle(top,bottom);
return horiz[3]<vert[3]? horiz: vert;
}
Я признаю, что я облажался; Я пытаюсь адаптировать 2D-код , расширяя его в 3 измерения. Это не правильно вычисляет сферу; кажется, что центральная точка сферы находится на линии между камерой и верхним левым краем каждый раз, и она слишком большая (или слишком близко). Есть ли явные ошибки в моем коде? Работает ли подход, если он исправлен?
Ответы:
Я предполагаю, что ваш усеченный симметрично, так как ваш рисунок, кажется, предлагает это. Есть три ограничения (два, если ваш усеченный 2D):
A. сфера не может быть больше расстояния между ближней и дальней плоскостями
Если
D
расстояние ближнее-дальнее, первое ограничение просто:B. сфера не может расти шире боковых плоскостей
Теперь для другого ограничения, скажем,
α
это половинный угол усеченного конуса иL
половинная ширина дальней плоскости, как показано на этом рисунке:Первая формула задается тригонометрией в треугольнике. Второе происходит от суммы углов треугольника. Что дает нам второе ограничение:
Если усеченный является 3D, вы будете иметь третье ограничение с новыми
L
иα
значениями.Конечный результат
R
Значение , которое вы ищете,min
из трех границ.Как получить параметры
Если вы можете отменить проекцию вида или мирового пространства, вы можете вычислить L, D и α следующим образом, где
P
точки находятся в ближней плоскости, аQ
точки - в далекой плоскости:Стрелки означают векторы, «.» является точечным произведением, а || указывает длину вектора. Заменить
Q2
сQ3
иP2
с ,P3
чтобы получить L и а в вертикальном измерении.источник
В 2D: рассмотреть усеченный треугольник (2D)
Затем вы хотите найти вкрапление треугольника.
В качестве трехмерной задачи вам нужно найти суть квадратной пирамиды.
Если бы у меня была формула, я бы напечатал ее здесь, но, увы, я не знаю формулу.
источник
Самая большая возможная сфера должна касаться дальней плоскости (используя здесь термины для просмотра вида) прямо в центре. Он также будет касаться верхней / нижней или левой / правой плоскостей, в зависимости от того, какой угол FoV меньше. Я должен сказать, что у меня нет фактического математического доказательства для этих предположений, но они должны быть правы. Может быть, у кого-то есть идея, как это доказать.
Сфера может быть определена ее центральной точкой и радиусом. Cx и Cy совпадают с центром дальней плоскости.
Cz и радиус могут быть получены путем решения системы уравнений на основе предположений, перечисленных выше.
T является одной из нижней / верхней плоскости или левой / правой плоскости (см. Выше) с t1, t2 и t3 как нормализованным вектором нормали и t4 как расстоянием от начала координат. f - центр дальней плоскости.
t1 * cx + t2 * cy + t3 * cz - t4 = r
-fz + cz = r
t1 * cx + t2 * cy + t3 * cz - t4 = -fz + cz
t1 * cx + t2 * cy + fz - t2 = + cz - t3 * cz
t1 * cx + t2 * cy - fz - t2 = cz * (1 - t3)
cz = (t1 * cx + t2 * cy - fz - t2) / (1 - t3)
Затем рассчитывается r, вставляя в него cz: -fz + cz = r
Вы можете получить все плоскости из матрицы проекции, которую вы используете. (Не ViewProjection в этом случае)
после этого вы должны переместить сферу в нужное место: C '= обратный (вид) * C
источник
Я пытаюсь сделать что-то подобное, и в моем случае скорость важнее точности, если сфера не существует за пределами границ усеченного конуса.
Если вы вычислите кратчайшее расстояние между линейными сегментами (или гранями в 3d), самое короткое найденное расстояние можно использовать как диаметр вкрапления / сферы, которая полностью лежит внутри усеченного конуса. Происхождение врезки / сферы может быть просто средним числом всех вершин (сумма и деление). Это было бы довольно быстро, а также работать для всех типов выпуклых многогранников.
Единственный недостаток заключается в том, что круг или сфера не обязательно будут самым большим вписанным кругом или сферой. Для усеченного конуса с большим объемом и одним очень коротким ребром окружность / сфера будет разделять гораздо меньше пространства усеченного конуса, чем это возможно.
Другая идея
Если вам нужна сфера трехмерного вида, и у вас есть перспективная матрица, используемая для построения этого усеченного контура, то вы можете просто использовать эту матрицу в области единичного куба, и это должно быть идеальным основанием для усеченного конуса. (Диаметр сферы куба - это длина одного из краев куба, центр - середина куба, которая является средним из вершин куба)
источник