9

포인트 (x, y z)가있는 경우 어떻게 선형 인덱스를 찾을 수 있습니까? 내 번호 매기기 구성표는 (0, 0, 0)은 0, (1, 0, 0)은 1입니다. . ., (0, 1, 0)은 최대 x 치수, .... 또한 선형 좌표가있는 경우, 어떻게 찾을 수 있습니까 (x, y, z)? Google에서이 항목을 찾을 수없는 것 같습니다. 모든 결과는 다른 관련없는 항목으로 채워집니다. 고맙습니다!3D 좌표의 선형 인덱스는 어떻게 계산합니까?

+0

좌표는 항상 정수로 구성되어 있습니까? 음의 좌표를 가질 수 있습니까? x 축 외에 어떤 축에 대해서도 최대 값을 갖고 있습니까? – Kevin

+0

각 좌표의 분할 수가 동일하거나 다를 수 있습니까? 마지막 점은'(N, N, N)'또는'(N1, N2, N3)'로 표현됩니까? – ja72

답변

23

3 차원 좌표를 단일 숫자로 매핑하는 데는 몇 가지 방법이 있습니다. 한 가지 방법이 있습니다.

일부 함수 f (x, y, z)는 좌표 (x, y, z)의 선형 인덱스를 제공합니다. 그것은 우리가 유추하고자하는 몇 가지 상수 a, b, c, d를 가지므로 유용한 변환 함수를 작성할 수 있습니다.

f(x,y,z) = a*x + b*y + c*z + d 

당신은 (0, 0, 0)에 따라서 0으로 매핑하는 것을 지정했습니다 해결 거라고 것

f(0,0,0) = a*0 + b*0 + c*0 + d = 0 
d = 0 
f(x,y,z) = a*x + b*y + c*z 

. (1,0,0)은 그래서 1로 매핑 당신이 지정한 것을 :

f(1,0,0) = a*1 + b*0 + c*0 = 1 
a = 1 
f(x,y,z) = x + b*y + c*z 

해결 된 것 그. (MAX_X, 0, 0)이 (0,1,0) 다음에 오는 가장 높은 숫자를 임의로 결정합시다.

f(MAX_X, 0, 0) = MAX_X 
f(0, 1, 0) = 0 + b*1 + c*0 = MAX_X + 1 
b = MAX_X + 1 
f(x,y,z) = x + (MAX_X + 1)*y + c*z 

해결되었습니다. (MAX_X, MAX_Y, 0)이 (0,0,1) 이후의 다음 높은 숫자를 임의로 결정하자. 다음과 같이

f(MAX_X, MAX_Y, 0) = MAX_X + MAX_Y * (MAX_X + 1) 
f(0,0,1) = 0 + (MAX_X + 1) * 0 + c*1 = MAX_X + MAX_Y * (MAX_X + 1) + 1 
c = MAX_X + MAX_Y * (MAX_X + 1) + 1 
c = (MAX_X + 1) + MAX_Y * (MAX_X + 1) 
c = (MAX_X + 1) * (MAX_Y + 1) 

지금 우리가 A, B, C 및 D를 알고, 우리는 당신의 함수를 작성할 수 있습니다

function linearIndexFromCoordinate(x,y,z, max_x, max_y){ 
    a = 1 
    b = max_x + 1 
    c = (max_x + 1) * (max_y + 1) 
    d = 0 
    return a*x + b*y + c*z + d 
} 

당신은 유사한 논리에 의해 선형 인덱스에서 좌표를 얻을 수 있습니다. 나는이 페이지를 포함하기에는 너무 작기 때문에 이것에 대한 놀라운 시연을하고있다. 그래서 저는 수학 강좌를 건너 뛰고 마지막 방법을 알려 드리겠습니다.

function coordinateFromLinearIndex(idx, max_x, max_y){ 
    x = idx % (max_x+1) 
    idx /= (max_x+1) 
    y = idx % (max_y+1) 
    idx /= (max_y+1) 
    z = idx 
    return (x,y,z) 
} 
+0

좋은 답변입니다! 나는 단지 375 년 동안 당신의 기이 한 증거에 대해서만 수수께끼를 풀 것입니다. 무리 감사. – user1438116

+0

@ 케빈 안녕하세요! 나는이 질문이 거의 2 살이라는 것을 알고 있지만, 나는 궁금해하고 있었다 : 당신이 언급 한 그 수학 강연에 대한 링크를 가지고 있겠는가? 당신의 방법은 절대적으로 환상적으로 보입니다. 그래서 나는 그 뒤에있는 수학에 대해 궁금합니다. –

+0

답변을 수락 한 후에는 수정 사항의 코드를 변경하면 안됩니다. 주석으로 처리해야합니다. –

1

좌표의 상한선이없는 경우 원점과 바깥쪽으로 번호를 매길 수 있습니다. 레이어로 레이어.

(0,0,0) -> 0 
(0,0,1) -> 1 
(0,1,0) -> 2 
(1,0,0) -> 3 
(0,0,2) -> 4 
    :  : 
(a,b,c) -> (a+b+c)·(a+b+c+1)·(a+b+c+2)/6 + (a+b)·(a+b+1)/2 + a 

3 차 다항식을 풀어야하기 때문에 역이 더 힘듭니다.

InverseTetrahedralNumber(n) = { x ∈ ℕ | Tetra(n) ≤ x < Tetra(n+1) } 
Tetra(n) = n·(n+1)·(n+2)/6 
InverseTriangularNumber(n) = { x ∈ ℕ | Tri(n) ≤ x < Tri(n+1) } 
Tri(n) = n·(n+1)/2 

InverseTetrahedralNumber(n)가 어느 large analytic solution 계산 또는 some numeric method으로 검색 할 수

m1 = InverseTetrahedralNumber(n) 
m2 = InverseTriangularNumber(n - Tetra(m1)) 
a = n - Tetra(m1) - Tri(m2) 
b = m2 - a 
c = m1 - m2 

.


여기 대수 솔루션 (javascript)에서의 시도입니다. 방정식을 단순화하기 위해 대체 문자 p = a+b+c, q = a+b, r = a을 사용하고 있습니다.

function index(a,b,c) { 
    var r = a; 
    var q = r + b; 
    var p = q + c; 
    return (p*(p+1)*(p+2) + 3*q*(q+1) + 6*r)/6; 
} 

function solve(n) { 
    if (n <= 0) { 
     return [0,0,0]; 
    } 

    var sqrt = Math.sqrt; 
    var cbrt = function (x) { return Math.pow(x,1.0/3); }; 

    var X = sqrt(729*n*n - 3); 
    var Y = cbrt(81*n + 3*X); 
    var p = Math.floor((Y*(Y-3)+3)/(Y*3)); 
    if ((p+1)*(p+2)*(p+3) <= n*6) p++; 
    var pp = p*(p+1)*(p+2); 

    var Z = sqrt(72*n+9-12*pp); 
    var q = Math.floor((Z-3)/6); 
    if (pp + (q+1)*(q+2)*3 <= n*6) q++; 
    var qq = q*(q+1); 

    var r = Math.floor((6*n-pp-3*qq)/6); 
    if (pp + qq*3 + r*6 < n*6) r++; 

    return [r, q - r, p - q]; 
} 
관련 문제