그래프의 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 성분에 :
및 여기 Makerware에서 볼 때를 전송하기 위해 사용되는 (생성 STL 파일의 3 차원 프린터로 3D 모델) :
(왼쪽 아래에있는 여분의 실린더 찾고 비트 나는 현재 테스트 목적에 떠 났어요 뭔가 - z 축 방향으로 가리키는 실린더 , 원점에 위치).에서 쇼로
: 그 같은 그래프를 가지고 이제 모든 모서리는 세 축 각도를 포함, z 축에 중간 정점을 이동하면
, 나는 결과 다음과 같은 무언가를 얻을 응용 프로그램 :
결과 STL 파일, 쇼 등 Makerware에서 :
... 측면에서 볼 때 같은 모델 : 당신이 볼 수 있듯이 나는 그들이 생각했던 것처럼, 실린더 확실히 공을 함께 충족되지
. 제 질문은 이것입니다 :이 결함에 대한 나의 접근 방식은 결함이 있습니까, 아니면 제 회전 중에 어딘가에서 작고 중대한 실수가 있습니까? 회전 함수 자체에 문제가 없다는 것이 확실합니다. 예상대로 작동하는지 독립적으로 확인할 수 있었기 때문입니다. 나는 또한 요, 피치, 롤에 소요 한 번에 세 가지를 모두 수행하는 회전 기능을 작성했는데,이 같은 결과를 생성과 같이 듯 :
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
여전히 몇 가지 버그가있는 것 같습니다,하지만이 간단한 테스트 케이스에 대한 최소 작동하는 것 같다.
순차적으로 발생하는 회전은 두 회전 (예 : X 축의 회전과 Y 축의 회전)을하는 것뿐만 아니라 의미가 있습니다. 한가지는 아직 명확하지 않습니다. X 축에서 회전을 완료하면 Y 축에서 회전에 필요한 각도를 다시 계산하려면 어떻게해야합니까? 그런 시도를하는 나의 시도는 지금까지 실패했습니다. 필자는 매트릭스를 사용하는 편이 낫지 만, 상당히 좁은 함수/클래스 세트로 작업하고 있으며, 외부 의존성을 최소화하려고 노력하고 있으므로 각도로 처리합니다. –
나는 각도를 다시 계산할 때 여전히 혼란 스럽다. 꼭지점이 (1, 1, 1)과 (5, 5, 5) 인 모서리가 있다고 가정 해 봅시다. 위에 설명 된 각도 y/z 각도를 계산하고 x 축에서 그 양만큼 회전합니다. 어떻게 이러한 회전이 Y 축을 중심으로 회전해야하는 각도에 영향을 줍니까? 그 각도에 어떤 영향을 미치는지, 그리고 왜 다시 계산해야하는지, 그리고 그런 방식으로 잘못된 결과를 얻으려는 시도를하는 것을 볼 수 없습니다. –
일반적으로 3D 그래픽 프로그래머는 보편적이기 때문에 행렬 곱셈을 사용합니다. 그러나 당신의 경우에는 y 축 (내 경우에는) 주위를 회전하면 다음 회전 각도가 원래 벡터와 원래 벡터 사이의 각도보다 더 큰 경우이 방법으로 상상해보십시오. 여기서 Z 구성 요소가 0 인 경우 원래 위치가 일치하는지 확인합니다. 이 생각의 라인. – joojaa