큐브의 정점과 그 삼각형을 인쇄


9

큐브 정점의 좌표를 출력합니다. 그런 다음 큐브를 덮을 12 개의 삼각형 목록을 출력합니다. 각 삼각형은 일관된 방향을 가진 3 개의 정점 색인 목록입니다. 출력은 고유 한 10 진수의 ASCII 문자열이어야합니다. 이 골프는 입력이 없습니다. 우승자는 문자 수가 유니 코드 인 가장 적은 문자입니다.

예를 들어, 0,0,0에 모서리가있는 1x1x1 큐브를 고려하십시오. 큐브의 8 개의 꼭짓점은 3 차원 데카르트 그리드에서 다음 xyz 좌표로 설명 할 수 있습니다.

x y z = (0,0,1) (1,0,1) (1,1,1) (0,1,1) (0,0,0) (1,0,0) (1,1,0) (0,1,0)

각 정점에는 색인이 주어질 수 있습니다. x y z->index: 0 0 1->0, 1 0 1->1, 1 1 1->2, 0 1 1->3, 0 0 0->4, 1 0 0->5, 1 1 0->6, 0 1 0->7

이제 상단면을 고려하십시오. 꼭지점은 0에서 3까지 색인됩니다. 두 개의 커버링 삼각형은 각각 세 개의 인덱스로 설명 될 수 있습니다.

[0,1,2] [2,3,0]

다음은이 윗면의 사진입니다. 큐브 위에서봤을 때 :

 3_____2
 |    /| 
 |   / |                  
 |  /  |
 | /   |
 0_____1                

그리고 여기는 각도에서 본 것입니다.

    3____2
   / __-/|
 0/_`__1 |
  |    | /6
  |____|/
 4     5

큐브를 '외부'에서 볼 때 문제의 얼굴을 직접 바라 보는 큐브의 '외부'에서 볼 때 두 삼각형의 방향 또는 '감기'는 '시계 반대 방향'입니다 (각 정점을 방문하면 시계 반대 방향으로 이동한다고 가정). 이제 큐브의 6면 모두에 대해이 작업을 수행했다고 상상해보십시오.

vertices: (0,0,1) (1,0,1) (1,1,1) (0,1,1) (0,0,0) (1,0,0) (1,1,0) (0,1,0)
triangles as indices: [0,1,2], [2,3,0], [6,5,4], [4,7,6], 
  [5,2,1], [2,5,6], [0,3,4], [4,3,7], [2,6,3], [3,6,7], [0,4,1], [1,4,5]

모든 좌표에 위치한 모든 크기의 큐브를 출력 할 수 있습니다. 원하는대로 정점 좌표의 번호를 지정하고 순서를 지정할 수 있습니다. 인덱스는 0 기반 또는 1 기반 일 수 있습니다. 삼각형의 방향은 모든 삼각형에 대해 일관된 한 큐브 외부에서 볼 때 시계 방향 또는 시계 반대 방향 일 수 있습니다.

각 ASCII 10 진수가 하나 이상의 숫자가 아닌 ASCII 문자로 분리되어 있으면 원하는대로 출력 형식을 지정할 수 있습니다. 예를 들어 위의 예는 다음과 같이 출력 될 수도 있습니다.

0 0 1 1 0 1 1 1 1 0 1 1 0 0 0 1 0 0 1 1 0 0 1 0 
0 1 2 2 3 0 6 5 4 4 7 6 5 2 1 2 5 6 0 3 4 4 3 7 2 6 3 3 6 7 0 4 1 1 4 5

이 골프는 OpenGL, OBJ, OFF, AMF, CGAL 등을 포함한 다양한 3D 그래픽 시스템 및 형식에서 영감을 얻었습니다.이 골프는 Calvin 's Hobbies 가 Numbered Cube에서 Output a Face 라는 골프와 유사 합니다. 꼭짓점의 xyz 좌표를 출력하고 삼각형 인덱스를 출력합니다. 읽어 주셔서 감사합니다.

사용자 당 영감은 vertstr 및 idxstr 변수의 테스트 출력 데이터에 대해 'ok'또는 'not ok'를 인쇄하는 python2 (non-golfy)의 "도우미"검증 프로그램입니다. 완벽하게 작동하지는 않지만 약간의 오류가 발생할 수 있습니다.

편집 : 예제의 오타 수정 및 유효성 검사 코드의 버그.

    

#vertstr = '00 1011 1011 101111 '
#idxstr = '1 2 1 3 7 5 6 4 6 5 2 4 4 6 6 3 3 5 1 5 3 1 15 5 5 6 6 2 3 6'
vertstr = '0110111101010010'
idxstr = '0112 34 5678 9 1 5 5 0 34 4 3 7 2 6 3 3 6 7 4 1 4 5'

클래스 벡터 :
    데프 __init __ (self, v) :
        self.x, self.y, self.z = v [0], v [1], v [2]
    데프 __add __ (self, v) :
        벡터 반환 ([self.x + vx, self.y + vy, self.z + vz])
    데프 __sub __ (self, v) :
        벡터 반환 ([self.xv.x, self.yv.y, self.zv.z])
    데프 __str__ (자체) :
        str (self.x) + ','+ str (self.y) + ','+ str (self.z) 반환

데프 크로스 (v1, v2) :
    x = v1.y * v2.z-v2.y * v1.z
    z = v1.x * v2.y-v2.x * v1.y
    y = v1.z * v2.x-v2.z * v1.x
    벡터 반환 ([x, y, z])

# http://mathforum.org/library/drmath/view/55343.html & http://sympy.org
데프 와인딩 (v1, v2, v3, obs) :
    x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4 = v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, v3. x, v3.y, v3.z, obs.x, obs.y, obs.z
    d = x1 * (y2 * z3-y2 * z4-y3 * z2 + y3 * z4 + y4 * z2-y4 * z3) 
    d = d + y1 * (-x2 * z3 + x2 * z4 + x3 * z2-x3 * z4-x4 * z2 + x4 * z3) 
    d = d + z1 * (x2 * y3-x2 * y4-x3 * y2 + x3 * y4 + x4 * y2-x4 * y3)
    d = d-x2 * y3 * z4 + x2 * y4 * z3 + x3 * y2 * z4-x3 * y4 * z2-x4 * y2 * z3 + x4 * y3 * z2 
    d를 반환

데프 노멀 (v1, v2, v3) :
    va = v2-v1
    vb = v3-v2
    vc = v1-v3
    n1 = 교차 (va, vb)
    n2 = 교차 (vb, vc)
    n3 = 교차 (vc, va)
    반환 [n1, n2, n3]


데프 트립 플리 (str) :
    숫자, 트리플 = [], []
    str.split ( '')의 num : nums + = [int (num)]
    range (0, len (nums), 3)의 i의 경우 :
        트리플 + = [[숫자 [i], 숫자 [i + 1], 숫자 [i + 2]]]
    트리플을 반환

verts = 삼중 화 (vertstr)
지수 = triplify (idxstr)
nsum = 벡터 ([0,0,0])
windsum = 0
xs, ys, zs = [], [], []
verts에서 v의 경우 :
    xs + = [v [0]]
    ys + = [v [1]]
    zs + = [v [2]]
#print xs, ys, zs, len (xs)
중심 = 벡터 ([float (sum (xs)) / len (xs), float (sum (ys)) / len (ys), float (sum (zs)) / len (zs)])
인덱스 삼각형의 경우 :
    v1 = 벡터 (verts [triangle [0]])
    v2 = 벡터 (verts [triangle [1]])
    v3 = 벡터 (verts [triangle [2]])
    규범 = 법선 (v1, v2, v3)
    v1, v2, v3, norms [0], norms [1], norms [2] 인쇄
    규범에 따라 n :
        nsum + = n
    w = 권선 (v1, v2, v3, center)
    '와인딩'인쇄, w
    w <0 인 경우 : windsum- = 1
    elif w> 0 : windsum + = 1
abs (windsum) == 12 인 경우 : 'winding ok'인쇄
else : 'winding not ok'인쇄
(nsum.x == 0 및 nsum.y == 0 및 nsum.z == 0) 인 경우 : '정상 합계 ok'인쇄
else : '정상 합계가 정상이 아닙니다'인쇄

1
예제에서 명확하지만 완벽하게 모호하게 만들기 위해 인덱스가 0부터 시작한다고 언급 할 수 있습니다. 예로 제시 한 형식 중 하나 (OBJ)가 1 기반 인덱스를 사용하기 때문에 이것은 제공되지 않습니다.
Reto Koradi

잘 작동합니다. 나는이 도전에 대한 한 가지 어려움은 출력의 정확성을 확인하는 것이 적당히 고통 스럽다는 것입니다. 종이에 선택한 정점 순서로 큐브를 스케치하고 12 개의 삼각형을 모두 수동으로 확인해야합니다. 검증 프로그램을 작성할 수 있습니다. 그것은 실제로 다른 도전 아이디어 일 수 있습니다 ...이 아이디어보다 더 어렵다고 생각합니다.
Reto Koradi

유효성 검사기의 다른 골프라는 아이디어가 정말 좋습니다. 전체 데이터 세트를 제공하도록 예제를 업데이트했습니다. 다시 감사합니다.
밝게 돈

ok 각 삼각형의 각 벡터 쌍의 교차 곱을 가져 와서 모두 더하고 0이 'ok'라고 표시되는 매우 빠르고 더러운 유효성 검사 프로그램을 추가했습니다.
밝게 돈

답변:


1

Pyth, 18 자

j`CM"⭧勛囃勦⾽仵ᶌﻘꚱ쥎➡˻ì

내 Haskell 답변과 동일한 아이디어입니다. 인쇄물:

[
1
1
1
1
1
,

2
1
2
1
1
...

난 당신이 3 개 개의 다른 언어로 같은 유니 코드 문자열을 사용하는 것을 좋아한다
밝은 돈

1
이 유니 코드 마술은 무엇입니까?
RK.

2

CJam, 35 바이트

YZm*`3{[XY4]m<)\0+_:+1$f-+_@f+W%}%`

온라인으로 사용해보십시오

출력은 다음과 같습니다.

[[0 0] [10 1] [10 1] [01 1] [10] [10 1] [1 1] [11 1]] [[12 2 2 3 3 ] [7 5 4 6 5] [2 4 4 6 6] [7 3 1 5 3] [4 1 15 5] [7 6 3 2 3 6]]

삼각형 방향은 바깥에서 시계 방향입니다. 나는 이것을 수동으로 확인했는데, 나에게 맞는 것처럼 보인다.

설명:

YZ      Push 2 and 3 on stack.
m*      Cartesian power, creates the coordinates of the 8 vertices.
`       Convert to string for output. Done with vertices.
3{      Start loop over 3 coordinate directions.
  [XY4]   Push [1 2 4], which are the vertex index offsets for the 3 directions.
  m<      Rotate by loop counter. So the remaining loop body will be executed once
          with [1 2 4], once with [2 4 1], once with [4 1 2].
  )       Pop off last offset. Will use this as index offset between the two
          parallel faces.
  \       Swap pair of remaining two offsets to top. These are the index offsets
          within the face.
  0+      Add a 0 to the list. These 3 indices define the first triangle.
  _:+     Calculate the sum. This is the vertex index of the opposite corner.
  1$      Copy first triangle to the top.
  f-      Subtract all indices from the index of the opposite corner, producing
          the second triangle of the face.
  +       Concatenate the indices of the two triangles, resulting in a list with
          the 6 vertex indices for the face.
  _       Copy the list.
  @       Bring the offset between the two faces to the top.
  f+      Add the offset to each index in the copied list.
  W%      Revert the order, resulting in the properly oriented list of the 6 vertex
          indices for the parallel face.
}%      End of loop over 3 coordinate directions.
`       Convert to string for output. Done with triangles.

정말 멋지다. . . 대칭을 사랑합니다 ...
밝은

이것은 분명히 가장 재미있는 답변이지만 정적 설명과 "입력 없음"을 갖기 위해 문제 정의를 엉망으로 만들었습니다. 그래서 계약을 유지하고 아래의 가장 낮은 문자 수를 지정해야합니다 (재미있는 답변이지만 다른 방법), 답변 체크 표시. 참여해 주셔서 감사합니다.
밝게 돈

1

자바 스크립트 (ES6) 78

alert([...'1010011100101110111:120213756465240426735153410145763236'].join` `)

죄송하지만 입력없이 이러한 문제를 이해하지 못했습니다.


죄송합니다. 첫 골프 질문이었습니다. 지금 변경하기에는 너무 늦었다 고 생각합니다 ...
밝은

다음에 더 좋아. 어쨌든 내 투표권이 있습니다.
edc65

1

루비, 98 (106)

Reto Koradi에서 발견 된 오류를 수정했습니다.

s=sprintf'%024b',342391
6.times{|i|t='15462315'[i,3];t+=t.reverse;t[1+i%2*3]='07'[i%2];s+=t}
p s.split(//)

좌표가 필요하다는 점을 감안할 때, 유일한 모서리 번호 매기기 체계는 각 모서리가 좌표의 이진 표현 인 것으로 보였습니다. 그것은 다양한 번호 매기기 체계가 시도 된 관련 질문과는 상당히 다릅니다. 결국 나는 더러운 하드 코드로 좌표를 인쇄하기로 결정했습니다. 십진수 표현이 342391 인 s24 비트 숫자의 문자열 버전으로 초기화되었습니다. 000001010011100101110111실제로 좌표를 인쇄하는이 방법을 사용하면 정점의 번호 매기기가 유연하므로 유연 할 수 있습니다. 다른 답변을하십시오.

정육면체의 적도를 따라 가면서 정점 1,5,4,6,2,3을 찾은 다음이 목록의 연속 된 3 개의 숫자 중 각면에 대해 하나의 삼각형을 정의 할 수 있습니다 (끝에서 처음으로 줄 바꿈). ) 각면의 다른 삼각형은 숫자를 반대로하고 중간 숫자를 0 또는 7로 적절히 대체하여 정의됩니다.

필요한 모든 출력을 제공하지만 분리 문자가 없습니다. 이를 위해 간단히 문자 배열로 변환하고 다음과 같이 배열을 인쇄합니다 (스크롤을 방지하기 위해 줄 바꿈이 삽입 됨).

["0", "0", "0", "0", "0", "1", "0", "1", "0", "0", "1", "1", "1", "0", "0",
 "1", "0", "1", "1", "1", "0", "1", "1", "1", "1", "0", "4", "4", "5", "1",
 "5", "4", "6", "6", "7", "5", "4", "0", "2", "2", "6", "4", "6", "2", "3",
 "3", "7", "6", "2", "0", "1", "1", "3", "2", "3", "1", "5", "5", "7", "3"]

와인딩 순서가 일관성이 있습니까? 내 스케치를 기반으로 1, 5, 4CCW, 5, 4, 6CW입니다.
Reto Koradi

@RetoKoradi는 8 바이트의 비용으로 고정되었습니다. 감사. 또한 다른 번호 체계로 더 잘 할 수 있다는 것을 깨달았습니다.
Level River St

1

하스켈, 38 자

f=mapM(mapM print.show)"⭧勛囃勦⾽仵ᶌﻘꚱ쥎➡˻ì"

많은 수의 정크로 구분 된 올바른 숫자를 인쇄합니다.

'\''
'\\'
'1'
'1'
'1'
'1'
'1'
'\''
'\''
'\\'
'2'
'1'
'2'
'1'
'1'
...

큐브의 대각선은 (1, 1, 1)에서 (2, 2, 2)입니다.


1

CJam, 20 자

"⭧勛囃勦⾽仵ᶌﻘꚱ쥎➡˻ì":isS*

내 Haskell 답변과 동일한 아이디어입니다. 인쇄물:

1 1 1 1 1 2 1 2 1 1 2 2 2 1 1 2 1 2 2 2 1 2 2 2 1 2 0 2 1 3 7 5 6 4 6 5 2 4 0 4 2 6 7 3 5 1 5 3 4 1 0 1 4 5 7 6 3 2 3 6

1

루비, 개정판 1 62

29.downto(0){|c|p c>5?73888640>>c&1:[c,c^1,c|6,c|6,(c+3)%6,c]}

c-6매직 넘버에 64를 곱하여를 제거 했습니다.

좌표 할당은 다음과 같습니다. 100숫자 1에 할당하는 것이 이상합니다 . 축을 교환하고 001숫자 1에 할당 하여 rev 0에 바이트를 저장할 수있었습니다 . 그 이유는 원래 루프에서 카운트를 계산했기 때문입니다. 마법의 끈에 모든 것을 뒤집어 놓아야했습니다. 어쨌든, 지금 변경 한 내용으로 추가 저장 비용이 없으므로 좌표를 그대로 둡니다.

Cube rotated with 0163 face at back
Top layer from above
01   000 100
74   010 110    
Bottom layer from above
36   001 101   
25   011 111

루비, 레브 0 63

29.downto(0){|c|p c>5?1154510>>c-6&1:[c,c^1,c|6,c|6,(c+3)%6,c]}

좌표 데이터의 하드 코딩을 사용하여 코너 선택시 유연성을 제공합니다. 출력에 54 자리가 있는데, 이는 순진 솔루션이 코드에 63-54 = 9 바이트를 사용할 수 있음을 의미합니다. 공백을 9 바이트로 삽입하는 방법을 생각할 수 없으므로 이것이 순진한 솔루션보다 짧습니다.

번호 매기기 체계 (내 루비 답변에서 https://codegolf.stackexchange.com/a/48867/15599 링크 된 질문에 대한 답변 )

4---7
|  /|
| / |
|/  |
1---0---7
|  /|  /|
| / | / |
|/  |/  |
6---3---2---7
    |  /|  /|
    | / | / |
    |/  |/  |
    6---5---4
        |  /|
        | / |
        |/  |
        6---1

산출

0
0
0
1
0
0
0
1
1
0
0
1
1
1
0
1
1
1
0
0
1
1
1
0
[5, 4, 7, 7, 2, 5]
[4, 5, 6, 6, 1, 4]
[3, 2, 7, 7, 0, 3]
[2, 3, 6, 6, 5, 2]
[1, 0, 7, 7, 4, 1]
[0, 1, 6, 6, 3, 0]

정말의 결합처럼 Runer112의 방법 @
밝은 돈

@donbright 나는 이전 질문에서 적도에 처음 6 개의 정점과 극점에 마지막 2 개의 정점을 두는 것을 생각한 첫 번째 사람이었습니다. 그래서 내 C 답변이 가장 인기있는 답변입니다. 나는 6 개의 정점을 순차적으로 가지고있었습니다. Runer112는 적도에서 6 개의 정점을 다시 정렬 한 것으로 인정받을만한 가치가 있습니다. 이전 질문에서 Ruby의 얼굴 순서를 수정해야했지만 정점 순서는 실제로 Runer112와 동일합니다. 적도의 6 개 정점의 Phinotphi의 대안 재정렬 날 이전 질문에 길이를 같게 준 것이다, 그러나이 하나 이상이 될 것입니다
레벨 강 세인트에게

와우 대단해 ... 자세한 설명 감사합니다 ... 매우 흥미 롭습니다. 나는 입력을 허용해야했는데 그것은 더 나은 도전이었을 것입니다.
밝게
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.