선박의 구성은 동적으로 변경되므로 선박을 시계 방향 또는 시계 반대 방향으로 회전 할 때 켜야 할 추진기를 결정해야합니다. 스러 스터는 항상 선박과 축을 일직선으로 정렬하고 (각도는 아님) 켜거나 끕니다. 가능한 설정 중 하나는 다음과 같습니다.
지금까지 시도한 것은 발사 벡터와 방향 벡터를 선박의 질량 중심으로 시각화하는 것입니다.
불행히도, 나는 그렇게 멀지 않았습니다.
선박의 구성은 동적으로 변경되므로 선박을 시계 방향 또는 시계 반대 방향으로 회전 할 때 켜야 할 추진기를 결정해야합니다. 스러 스터는 항상 선박과 축을 일직선으로 정렬하고 (각도는 아님) 켜거나 끕니다. 가능한 설정 중 하나는 다음과 같습니다.
지금까지 시도한 것은 발사 벡터와 방향 벡터를 선박의 질량 중심으로 시각화하는 것입니다.
불행히도, 나는 그렇게 멀지 않았습니다.
답변:
성공! 여기 있습니다. 그리고 회전해야합니다 :
내가 한 것은 다음과 같습니다. 각 스러 스터마다 질량 중심과 관련하여 토크의 크기를 계산합니다.
private function thrustTorque():Float
{
// distToCom is the distance vector between the thruster and center of mass
// fire angle is a unit vector representing the direction of the thruster
var distAngle = Math.atan2(distToCOM.y, distToCOM.x);
var fireAngle = Math.atan2(dir.y, dir.x);
var theta = fireAngle - distAngle;
var torque = distToCOM.length * Math.sin(theta);
return torque;
}
Wikipedia에 따르면 토크의 크기에 대한 방정식은 다음 T = rF sin(theta)
과 같습니다.
플레이어가 왼쪽을 누르면 해당 스러 스터의 토크 표시를 확인합니다. 0보다 작 으면 스러 스터를 발사합니다. 시계 방향으로 돌리는 것은 반대입니다.
이것은 내적을 사용하여 벡터 사이의 각도의 코사인을 계산함으로써 향상 될 수 있지만 내일까지 기다려야합니다.
마지막으로, 여기에 데모 데모가 있습니다.
: 토크에 대한 일반적인 표현은 3 차원 변위 및 힘의 외적이다 T = R ⨯ F . 2 차원에서, 토크에 대한 스칼라 값으로 충분하며, 스러 스터에 대해 4 개의 직교 방향 만 제공하면 조각 형태로 쓸 수 있습니다.
여기서, F는 스러 스터에 의해 생성 된 힘의 크기이며, rx 및 ry는 피벗 점에서 스러 스터까지 벡터의 x 및 y 성분입니다. 양의 토크는 배를 시계 반대 방향으로 회전시키는 경향이 있습니다. 위의 4 가지 공식을 사용하면 각 스러 스터가 생성하는 토크의 신호를 추론하는 것이 쉽지 않습니다.
적당히 정확한 물리 표현을 위해서는 추력의 표시뿐만 아니라 총 크기와 회전 관성을 알아야합니다. 또한 회전을하기 위해 올바르게 정렬 된 모든 스러 스터를 활성화하고 싶지 않을 수도 있습니다.
그림과 같이 스러 스터 B, D 및 E에 대한 최대 출력은 회전을 최대화하지만 선박을 오른쪽으로 가속시킵니다. D를 종료하면이를 방지 할 수 있습니다. 대신, 가속 가속이 의도되었지만 시계 방향 회전이 아닌 경우 가장 효율적인 방법은 D와 함께 최대 전력의 2/3에서 C와 F를 모두 활성화하는 것입니다.
이것이 당신이하려는 일의 범위를 벗어나지 않는다면, 간단한 작업이 아니라 운동 방정식에 대한 일종의 솔버를 작성해야합니다.
몇 가지 다른 것들. 먼저, 이것이 제한적인 문제라는 것을 인식해야합니다. 즉, 같은 방향으로 회전하기 위해 발사 할 수있는 많은 다른 스러 스터 조합이 있습니다. 나는 당신의 상황에서 스러 스터에 대해 "온"과 "오프"의 두 가지 상태 만 있고 모든 스러 스터는 동일한 힘을 출력한다고 가정합니다.
둘째, 모델을 시선을 사로 잡으면 "질량 중심"이 실제로 질량 중심이 아닌 것처럼 보입니다. 운 좋게도 토크 계산에는 영향을 미치지 않습니다. 그러나 질량 변위 중심에 대한 계산에는 영향을 미칩니다. 그래도 "질량 중심"이 실제 질량 중심에 가장 가까운 사각형이기 때문에 그 수준의 정확도에 관심이 있는지 확실하지 않습니다.
셋째, 특정 스러 스터가 회전에 어떤 영향을 미치는지 계산하려면 비효율적 인 공식을 사용하고 있지만 올바르게 작동합니다. 토크 r x F
는 크기를 갖는 로 계산할 수 있습니다 r*F*sin(theta)
. 그러나이 경우 각도를 계산하는 것은 비효율적 인 방법입니다. 대신, 토크에 대한 교차 제품 정의를 직접 사용해야합니다. 이는 표현을 사용하는 것이 훨씬 간단하기 때문입니다. 모든 벡터에는 z 성분이 없으므로 교차 곱의 수식이 크게 단순화됩니다.
계산 결과를 전혀 변경하지 않고도 코드를 업데이트 할 수 있습니다
private function thrustTorque():Float
{
var torque = distToCOM.x*dir.y-distToCOM.y*dir.x;
return torque;
}
훨씬 더 좋고 빠릅니다.
당신은 당신의 해결책은 모든 추진기를 올바른 방향으로 토크로 발사하는 것입니다. 자, 그것은 당신이 묻는 질문을 거의 해결합니다. 그러나 사용자가 "회전"버튼을 누른 상태에서 양의 토크를 가진 모든 스러 스터가 회전하여 잠재적으로 맨 위로 이동하면 전략이 만족스럽지 않다는 것을 알게 될 것입니다. (추력기의 힘을 실제로 계산하거나 시각적으로 발사하는 것을 보여주고 일정한 가속도 또는 다른 것으로 모델을 회전시키는 경우 시뮬레이션의 세부 수준은 확실하지 않습니다. 방법으로, 스러 스터가 최소한 대략 정확하게 발사되기를 원합니다).
당신은 배의 순 힘을 고려하지 않습니다. 임의의 스러 스터 양이 있다면 이것은 매우 복잡한 문제로 바뀔 수 있습니다. 그러나 스러 스터에는 상태가 두 개뿐이므로 분석하기가 매우 간단합니다. 나는 우리의 목표가 정확히 무엇인지 확실하지 않으므로 두 가지 다른 것을 상상할 수 있습니다. 먼저, 우리는 총 힘을 최소화하면서 토크를 원하는 방향으로 계속 유지하려고합니다. 둘째, 총 힘에 대한 토크의 비율을 최대화하려고합니다.
게다가, 모든 스러 스터 의 힘에 동시에 영향을 미치는 추가 "스러 스터 볼륨"컨트롤을 상상할 수 있다면 , 두 솔루션이 동일한 토크를 갖도록이 컨트롤을 설정할 수 있고 두 번째 솔루션은 첫 번째보다 작은 변위. 그러나 스러 스터를 발사하여 회전 만하고 전혀 움직이지 않으면 두 솔루션이 동일하다는 것을 기억해야합니다.
따라서 이전 단락의 주장에 따라 두 번째 해결책을 살펴 보겠습니다. 이제 총 힘을 분석 할 때 엔진이 지시 할 수있는 방향은 4 가지에 불과하다는 것을 알 수 있습니다. 따라서 x 방향의 총 힘은 왼쪽을 가리키는 추진기의 수에서 오른쪽을 가리키는 수를 뺀 것과 마찬가지로 y 방향입니다.
지금까지 작성한 후에는 알고리즘을 최적화하기 위해 알고리즘에 대해 더 생각해야합니다. 내 게시물의 나머지 부분이 그대로 도움이된다고 생각하므로 게시하고 있지만이 구성을 최적화하는 가장 좋은 방법을 알아 낼 때 업데이트 할 것입니다 (근사한 답변을 얻는 몇 가지 방법을 생각했지만 그들 중 누구도 정확하지 않습니다).