2013-06-07 3 views
1

그래프의 STL 모델을 생성하는 그래프 그리기 프로그램 용 파이썬 기반 플러그인을 작성해야했습니다. 꼭지점과 가장자리로 구성된 개체로, 꼭지점은 3D 볼 (모자이크 모양의 20 면체)으로 표현되고 가장자리는 두 끝의 두 볼과 연결되는 원통으로 표시됩니다. 3D 모델의 최종 결과는 3D 인쇄를 위해 STL 파일로 버려지는 것입니다. 볼과 실린더의 3D 모델을 아무런 문제없이 생성 할 수 있지만, 전체 모델을 생성하고 볼과 실린더를 올바르게 연결하는 데 문제가 있습니다.볼과 실린더를 연결하는 3D 회전

필자의 원래 아이디어는 원점에 정사각형의 20 면체를 작성한 다음 정점의 위치로 변환하는 것이 었습니다. 이것은 잘 작동합니다. 그런 다음 각 가장자리에 대해 원점에 원통을 만들고 올바른 각도로 회전하여 올바른 각도로 점을 찍은 다음 두 꼭지점 사이의 중간 점으로 변환하여 원통의 끝이 포함되도록합니다. icosahedrons에서. 이것은 일이 잘못되고있는 곳입니다. 회전을 올바르게하는 데 어려움을 겪고 있습니다. 회전을 계산하려면 다음을 수행합니다.

먼저 두 점 사이의 각도를 찾습니다 (여기서 source와 target은 현재 처리중인 모서리에 속한 그래프의 정점입니다).) :

각도를 계산하는 것이 합리적인 것처럼 보입니다. 내가 알 수있는 한 실제로는 꼭지점 사이의 각도를 나타냅니다. 예를 들어, (1, 1, 0)에 꼭지점이 있고 (3, 3, 0)에 다른 꼭지점이있는 경우 그 꼭지점을 연결하는 각 변이 두 꼭지점 사이에 45도 각도로 표시됩니다. (즉, -135도, 어느 정점이 소스이고 어떤 것이 타겟인지에 따라 다릅니다.) C = 실린더() c.createCylinder을 (: I는 각 계산 일단

, I는 I 만든 다른 클래스를 사용하여 실린더를 생성과 같이, 계산 된 각도로 돌리 edgePosition 그래프의 두 정점 사이의 중간 지점이다 edgeThickness, edgeLength)

 c.rotateX(-yzAngle) 
     c.rotateY(xzAngle) 
     c.rotateZ(-xyAngle) 
     c.translate(edgePosition.x, edgePosition.y, edgePosition.z) 

은 (edgeThickness 실린더의 반경이 생성되고, 그리고 edgeLength 두 꼭지점 사이의 거리)이다.

언급 한 바와 같이, 예상대로 작동하지 않는 실린더의 회전. x/y 평면에서 올바른 회전을하는 것처럼 보이지만 가장자리에 세 개의 구성 요소 (x, y 및 z)에서 서로 다른 정점이 생기면 회전이 실패합니다. 여기서 상기 X 다르다 그래프와 y 성분의 예는 아니지만, Z 성분에 :

The graph in the application

및 여기 Makerware에서 볼 때를 전송하기 위해 사용되는 (생성 STL 파일의 3 차원 프린터로 3D 모델) :

Graph in Makerware

(왼쪽 아래에있는 여분의 실린더 찾고 비트 나는 현재 테스트 목적에 떠 났어요 뭔가 - z 축 방향으로 가리키는 실린더 , 원점에 위치).에서 쇼로

: 그 같은 그래프를 가지고 이제 모든 모서리는 세 축 각도를 포함, z 축에 중간 정점을 이동하면

, 나는 결과 다음과 같은 무언가를 얻을 응용 프로그램 :

enter image description here

결과 STL 파일, 쇼 등 Makerware에서 :

enter image description here

... 측면에서 볼 때 같은 모델 : 당신이 볼 수 있듯이 나는 그들이 생각했던 것처럼, 실린더 확실히 공을 함께 충족되지

enter image description here

. 제 질문은 이것입니다 :이 결함에 대한 나의 접근 방식은 결함이 있습니까, 아니면 제 회전 중에 어딘가에서 작고 중대한 실수가 있습니까? 회전 함수 자체에 문제가 없다는 것이 확실합니다. 예상대로 작동하는지 독립적으로 확인할 수 있었기 때문입니다. 나는 또한 요, 피치, 롤에 소요 한 번에 세 가지를 모두 수행하는 회전 기능을 작성했는데,이 같은 결과를 생성과 같이 듯 :

c.rotateYawPitchRoll(xzAngle, -yzAngle, -xyAngle) 

그래서이 ... 사람이 어떤이 내가 뭘 잘못하고 있을지에 대한 아이디어?

업데이트 : joojaa가 지적한대로 정확한 각도와 적용된 순서를 조합 한 것입니다. deltaVector 대상 및 소스 벡터 간의 차이

zyAngle = math.atan2(deltaVector.z, deltaVector.y) 

다음과 같이 작동하는 것을 얻기 위해, 먼저 I, X 축에 대한 회전을 계산한다. 이 회전은 아직 적용되지 않았습니다! 다음 단계는 다음과 같이 y 축의 회전을 계산하는 것입니다.

angle = vector.angleBetweenVectors(vector(target.x - source.x, target.y - source.y, target.z - source.z), vector(target.x - source.x, target.y - source.y, 0.0)) 

두 회전이 모두 계산되면 역순으로 적용됩니다! 첫째, X, 다음 y를 :

c.rotateY(angle) 
c.rotateX(-zyAngle) #... where c is a cylinder object 

여전히 몇 가지 버그가있는 것 같습니다,하지만이 간단한 테스트 케이스에 대한 최소 작동하는 것 같다.

답변

1

각도가 연속적으로 발생하므로 각도가 서로 영향을줍니다. 오일러 모델을 사용하여 한 번에 회전 할 수 없습니다. 이것이 첫 번째 정적 상황을 기반으로 회전을 계산할 수없는 이유입니다. 큐브를 똑바로 세워 큐브를 똑바로 세우는 것을 상상해보십시오. 첫 번째 회전은 45이지만 큐브가 이미 그 시점까지 회전했기 때문에 두 번째 회전이 아닙니다 (순서의 각 단계를 그려서 어떤 일이 발생하는지 확인하십시오). 우주 회전은 사소하지 않습니다.

그래서 한 각도를 회전 한 다음 두 번째 각도를 다시 계산해야합니다. 이것은 첫 번째 로테이션이 올바르게 작동하는 이유이기도합니다. 샤프트를 중심으로 한 회전이 일정한 방향을 유지하는 데 관심이 없다면 2 회전 만하면됩니다.

대신 축 각도 또는 행렬을 사용하는 것이 좋습니다. 주로 축 각도에서 이것은 사소한 것입니다. 왜냐하면 각도는 튜브 시작과 끝 벡터를 따르는 점 사이의 점이며, 축은 그 둘 사이의 교차점입니다. 그러면 필요한 경우 오일러 각도로 변환 할 수 있습니다. 하지만 아마 매트릭스를 직접 사용할 수 있습니다.전환 수와 순환 게재를 직접 계산할 수있는 방법에 대한 아이디어는 transformations.py Christoph Gohlke가 참조하십시오. 함께 제공되는 C 소스도 참조하십시오.

나는 내가이 답변 조금

모든 그리고 많은 다른 사람의 문제를 비켜이 질문에 대한 밖으로 정말 쉬운 방법이 있습니다를 확대 할 필요가 있다고 생각합니다. 대답은 오일러 각도 회전을 사용하지 않는 것입니다. 필자는 오일러 회전이 없으면 궁극적으로 더 쉽게 해결되는 문제에 대한 오일러 회전을 설명하기 위해 많은 양질의 지식을 사용했습니다. 당신이 더 많은 답변을 좀 더 생각하고 싶다면 나는 이것을 정당화하기위한 하나의 이유를 남겨 둘 것입니다.

오일러 회전 시퀀스를 가장 많이 사용하는 이유는 오일러 각을 이해하지 못했기 때문입니다. 실제로 좋은 상황이 몇 가지 있습니다. 자기 존중하는 프로그래머는 오일러 회전을 사용하여이 문제를 해결할 수 없습니다. 당신은 벡터 수학을 대신 사용합니다.

그래서 당신은 일반적으로 계산되는 대상으로 소스에서 방향 벡터가 :

along = normalize(target-source) 

이 단순히 매트릭스 행 중 하나입니다 (또는 열 표기법입니다 메이커 모델까지), 그 상당 하나를 실린더의 원래 방향 (행은 xyzw 임)으로 이동하면이 벡터에 수직 인 다른 벡터가 필요합니다. 위와 같은 임의의 벡터를 선택하십시오 (함께 따라 가면 왼쪽). 두 번째 행 방향에 따라이 위로 벡터를 곱하면됩니다. 마지막으로 소스를 마지막 열에 1을 넣으십시오. 실린더 프리즘을 설명하는 완전히 형성된 아핀 매트릭스를 완료합니다. 벡터를 그릴 수 있기 때문에 이해하기가 훨씬 쉽습니다.

더 짧은 방법이 있지만 이해하기 쉽습니다.

+0

순차적으로 발생하는 회전은 두 회전 (예 : X 축의 회전과 Y 축의 회전)을하는 것뿐만 아니라 의미가 있습니다. 한가지는 아직 명확하지 않습니다. X 축에서 회전을 완료하면 Y 축에서 회전에 필요한 각도를 다시 계산하려면 어떻게해야합니까? 그런 시도를하는 나의 시도는 지금까지 실패했습니다. 필자는 매트릭스를 사용하는 편이 낫지 만, 상당히 좁은 함수/클래스 세트로 작업하고 있으며, 외부 의존성을 최소화하려고 노력하고 있으므로 각도로 처리합니다. –

+0

나는 각도를 다시 계산할 때 여전히 혼란 스럽다. 꼭지점이 (1, 1, 1)과 (5, 5, 5) 인 모서리가 있다고 가정 해 봅시다. 위에 설명 된 각도 y/z 각도를 계산하고 x 축에서 그 양만큼 회전합니다. 어떻게 이러한 회전이 Y 축을 중심으로 회전해야하는 각도에 영향을 줍니까? 그 각도에 어떤 영향을 미치는지, 그리고 왜 다시 계산해야하는지, 그리고 그런 방식으로 잘못된 결과를 얻으려는 시도를하는 것을 볼 수 없습니다. –

+0

일반적으로 3D 그래픽 프로그래머는 보편적이기 때문에 행렬 곱셈을 사용합니다. 그러나 당신의 경우에는 y 축 (내 경우에는) 주위를 회전하면 다음 회전 각도가 원래 벡터와 원래 벡터 사이의 각도보다 더 큰 경우이 방법으로 상상해보십시오. 여기서 Z 구성 요소가 0 인 경우 원래 위치가 일치하는지 확인합니다. 이 생각의 라인. – joojaa