Como você encontra a maior esfera que pode desenhar em perspectiva?
Visto de cima, seria o seguinte:
Adicionado: no frustum à direita, marquei quatro pontos sobre os quais acho que sabemos algo. Podemos projetar todos os oito cantos do frusum e os centros das extremidades próxima e longínqua. Portanto, sabemos os pontos 1, 3 e 4. Também sabemos que o ponto 2 é a mesma distância de 3 e 4 é de 3. Portanto, podemos calcular o ponto mais próximo da linha 1 ao 4 e ao ponto 2 para obter o Centro? Mas a matemática e o código reais me escapam.
Quero desenhar os modelos (que são aproximadamente esféricos e para os quais tenho uma esfera delimitadora de minibolas) o maior possível.
Atualização: tentei implementar a abordagem incircle-on-two -planes, conforme sugerido por bobobobo e Nathan Reed :
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;
}
Eu admito que estou voando; Estou tentando adaptar o código 2D , estendendo-o em 3 dimensões. Não calcula a esfera corretamente; o ponto central da esfera parece estar sempre na linha entre a câmera e a parte superior esquerda, e é muito grande (ou muito próximo). Existe algum erro óbvio no meu código? A abordagem, se corrigida, funciona?