절두체 내부에 맞는 가장 큰 구를 어떻게 찾을 수 있습니까?


12

원근법으로 그릴 수있는 가장 큰 구를 어떻게 찾습니까?

위에서 본다면 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

추가 : 오른쪽의 절두체에, 나는 우리가 뭔가를 알고 있다고 생각하는 4 가지 점을 표시했습니다. frusum의 8 개 구석과 니어 엔드와 파 엔드의 중앙을 모두 투사 할 수 있습니다. 우리는 또한 점 1, 3 및 4를 알고 있습니다. 또한 점 2는 3과 4와 3의 거리가 동일하다는 것을 알고 있습니다. 센터? 그러나 실제 수학과 코드는 나를 피합니다.

가능한 한 큰 모델 (대략 구형이며 미니 볼 경계 영역이있는 미니 볼 경계 영역이 있음)을 그려보고 싶습니다.

업데이트 : bobobobo와 Nathan Reed가 제안한대로 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 차원으로 확장 하여 적응하려고 합니다. Insphere를 올바르게 계산하지 않습니다. 구의 중심점은 매번 카메라와 왼쪽 상단 사이의 선에 있고 너무 크거나 너무 가까운 것 같습니다. 내 코드에 명백한 실수가 있습니까? 수정 된 경우 접근 방식이 작동합니까?


구가 이미지에서와 같이 먼 평면의 가장 먼쪽에 있어야합니까?
Mikael Högström

@ MikaelHögström 가능한 한 커지기 위해 그들이 있었을 것이라고 생각합니까?
Will

흠 나는 그것이 당신의 목적에 달려 있다고 생각합니다 ... 만약 당신이 먼 평면 너머의 절반을 가진 구체를 그리면 그것은 더 클 것이지만 아마도 그것은 당신의 목적에 어긋날 것입니까?
Mikael Högström

@ MikaelHögström aha 귀하의 질문을 이해합니다. 예, 전체 모델이 그려 지길 원합니다.
Will

답변:


12

나는 당신의 그림이 제안하는 것처럼 보이기 때문에 절두체가 대칭이라고 가정합니다. 세 가지 제약 조건이 있습니다 (절두체가 2D 인 경우 두 가지).

A. 구는 근거리와 원거리 사이의 거리보다 클 수 없습니다

D근거리에 가까운 경우 첫 번째 제약 조건은 다음과 같습니다.

R  D / 2

B. 구는 측면보다 넓을 수 없다

이제 다른 구속 조건 α의 경우 절두체의 절반 각도이고이 L도면에 표시된 것처럼 원 거리면 의 절반 너비입니다.

절두체

첫 번째 공식은 삼각형의 삼각법으로 제공됩니다. 두 번째는 삼각형 각도의 합에서 나옵니다. 우리에게 두 번째 제약 조건이 있습니다.

R  L tan((π - 2α) / 4)

절두체가 3D이면 새 값 Lα값에 대한 세 번째 구속 조건이 있습니다.

최종 결과

R당신이 찾고 있는 가치 min는 세 가지 경계 중 하나입니다.

매개 변수를 얻는 방법

뷰 또는 월드 공간에서 절두체를 투영 해제 할 수있는 경우 P점이 근거리 평면에 있고 점이 원 거리면에있는 다음과 같은 방식으로 L, D 및 α를 계산할 수 있습니다 Q.

공식 2

화살표는 벡터를 의미합니다. 내적은 || 벡터의 길이를 나타냅니다. 교체 Q2Q3P2함께 P3수직 차원에서 L 및 α를 얻을 수 있습니다.


절두체 (뷰포트 점을 투영하여 근거리와 원거리로 계산)에서 시야를 어떻게 결정합니까? 그리고 3D에는 세 가지가 아닌 두 가지 선택 만 있습니다. 알고리즘을 코드에 넣으려는 시도는 항상 매우 큰 R을 제공합니다.
Will

@ 희망적으로 도움이 될 수식이있는 두 번째 그림을 추가했습니다.
sam hocevar

2

2D에서 : 절두체를 삼각형 (2D)으로 간주

여기에 이미지 설명을 입력하십시오

그런 다음 찾으려 내원 삼각형의를.

3D 문제로서 정사각형 피라미드 의 구면 을 찾아야합니다 .

수식이 있으면 여기에 인쇄하지만 슬프게도 수식을 알 수 없습니다.


2
적어도 "표준"절두체 (전단 또는 다른 것은 아님)의 경우 FOV가 더 작은 2D 수직 또는 수평 절두체의 원을 찾는 것으로 충분합니다.
Nathan Reed

1

가능한 가장 큰 구가 중앙의 원 거리면 (여기서 뷰 프러스 텀을 사용하여)에 닿아 야합니다. 또한 어떤 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 '= inverse (View) * C


1

나는 비슷한 것을 시도하고 있는데, 구가 절두체의 경계 바깥에 존재하지 않는 한 속도는 정확성보다 중요합니다.

선분 (또는 3d면) 사이의 최단 거리를 계산하는 경우 발견 된 최단 거리는 절두체 내부에 완전히있는 원 / 내 구경으로 사용될 수 있습니다. 내부 / 구내의 원점은 모든 정점의 평균 (합계 및 나눗셈) 일 수 있습니다. 그것은 매우 빠르며 모든 유형의 볼록 다면체에도 적용됩니다.

유일한 단점은 원이나 구체가 반드시 가장 큰 원 또는 구체 일 필요는 없다는 것입니다. 체적이 많고 가장자리가 매우 짧은 절두체의 경우 원 / 구는 절두체 공간을 가능한 한 적게 공유합니다.

또 다른 아이디어

3D 뷰 절두체의 인피 어를 원하고이 절두체를 구성하는 데 사용되는 원근 매트릭스가있는 경우, 단위 큐브의 내 구체에 해당 매트릭스를 사용하면 절두체에 대한 완벽한 내 구면이어야합니다. (입방체의 insphere의 직경은 입방체의 모서리 중 하나의 길이이고, 중심은 입방체의 정점의 평균 인 입방체의 중간입니다)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.