As naves espaciais do meu jogo deveriam ser construídas por jogadores, com uma quantidade arbitrária de propulsores conectados a qualquer lugar com qualquer rotação. Atualmente, tenho algum código sujo para girar o navio para um determinado ângulo (acelerando e desacelerando).
Aqui está um exemplo de um navio simétrico voltado para onde a linha vermelha aponta, sendo instruído a girar para a esquerda.
No entanto, como você pode imaginar, dependendo de onde o jogador colocou os propulsores, às vezes forças lineares indesejadas estão afetando o navio. Nesse caso, o navio começa a avançar.
Estou analisando se é possível encontrar o impulso máximo que um propulsor pode aplicar para não causar velocidade linear. (No caso acima, não haveria, pois não há nada para neutralizar as forças dos propulsores traseiros, e os da frente se matam).
O que eu vim até agora é uma fórmula para determinar a "eficiência da rotação", por exemplo, quanta rotação é causada em relação ao movimento linear.
a - vetor de posição para o propulsor a b - vetor de posição para o propulsor b v1 - força do propulsor a v2 - força do propulsor b
eficiênciaDelta = a.cross (v1) / | v1 | - (a.cross (v1) + b.cross (v2)) / | v1 + v2 |
, basicamente "a.cross (v1 * t) / | v1 |" é suposto ser a eficiência da curva. E então subtraímos pela eficiência de rotação dos propulsores combinados, para ver se vale a pena disparar o novo propulsor.
O problema surge quando percebo que os propulsores não podem ser ligados / desligados, mas podem variar de 0 a 1. E como proceder quando o jogador deseja que o navio avance. Obviamente, haveria um equilíbrio de quanto girar / mover.
Como não sou cientista de foguetes, espero que alguém possa me dizer se é possível calcular o acelerador de cada propulsor dessa maneira e me empurrar na direção certa.
Obrigado por tomar o tempo! / Kim
Respostas:
Assumirei que você tenha movimento fisicamente correto para sua nave, caso contrário, essa análise não será válida. Você precisa de algo mais forte que a eficiência para resolver esse problema corretamente.
Cada propulsor produzirá dois efeitos no movimento do navio: linear e angular. Estes podem ser considerados independentemente. Se o propulsor produz uma força
f
em uma direçãodir
e é deslocado do centro de massa por um vetorr
(não é o centro geométrico ou o centro do sprite!), O efeito no componente linear é:O efeito na velocidade angular é dado pelo torque:
t
é um vetor de força (ou seja, o impulso linear).tau
é um escalar assinado que, quando dividido pelo momento de inércia da massa, dará a aceleração angular. É importante quedir
er
estão ambos no mesmo espaço de coordenadas, ou seja, tanto em coordenadas locais ou ambos em coordenadas mundiais.A aceleração linear geral do navio é dada pela soma dos
t
's' para cada propulsor dividido pela massa do navio. Da mesma forma, a aceleração angular é apenas a soma dos torques divididos pelo momento de inércia da massa (que é outro escalar).O navio não girará se o torque total for zero. Da mesma forma, ele não se moverá se o impulso total for zero. O torque de rechamada é escalar, mas o empuxo (a soma dost
) é um vetor 2D.O objetivo desta exposição é que agora podemos escrever nosso problema como um programa linear . Digamos primeiro que queremos que nosso navio gire sem se mover . Temos uma variável para cada propulsor, $ x_1, x_2, ... $, que é a quantidade de empuxo que o propulsor fornecerá. Um conjunto de restrições é:
onde
fmax
está a força máxima para esse propulsor (isso nos permite ter forças mais fortes ou mais fracas). Em seguida, dizemos que ambas as igualdades:Isso codifica a restrição de que não aplicaremos uma aceleração linear, dizendo que o impulso total é zero (impulso é um vetor, portanto, apenas dizemos que cada parte é zero).
Agora queremos que nosso navio gire. Presumivelmente, queremos fazê-lo o mais rápido possível, e queremos:
Resolução para o
x_i
enquanto satisfaz as desigualdades e igualdades acima, enquanto maximiza a soma acima, nos dará o impulso desejado. A maioria das linguagens de programação possui uma biblioteca de LP disponível para elas. Basta colocar o problema acima e ele produzirá sua resposta.Um problema semelhante nos permitirá avançar sem virar. Digamos que reescrevemos nosso problema em um sistema de coordenadas no qual queremos avançar na direção x positiva. Então as restrições são:
Com a restrição de que os propulsores só podem produzir impulso em uma única direção, haverá limites para o tipo de rotações e velocidades lineares que você será capaz de atingir. Isso se manifestará como a solução sendo
0 = x_1 = x_2 = ... = x_n
, o que significa que você nunca chegará a lugar algum. Para mitigar isso, sugiro adicionar um par de propulsores pequenos e fracos (digamos 5% ou 10%) para cada jogador colocado o propulsor a 45 graus de cada lado. Isso dará à solução mais flexibilidade, pois elas podem ser usadas para neutralizar os efeitos secundários fracos dos propulsores principais.Finalmente, para até 100 propulsores, a solução para o LP é rápida o suficiente para ser feita por quadro. No entanto, como a solução não depende da localização ou do estado atual, você pode pré-calcular a solução para cada combinação razoável de entradas do controlador sempre que a forma for alterada (isso inclui adicionar não propulsores que alteram o momento de inércia ou a massa do navio, porque então os propulsores estão em um local diferente em relação ao centro de massa!). São 24 possibilidades (ie 8 direções vezes (rotação à esquerda, sem rotação, rotação à direita)).
fonte
Sum_i
significa neste contexto?Meu primeiro pensamento foi uma solução puramente empírica, que é simular a sonda em um ambiente de sandbox para diferentes graus de empuxo para descobrir como ela se comporta. Em vez de equilibrar muita matemática complexa na busca de uma solução determinística, você pode alcançá-la numericamente, por exemplo, usando o método de newtons. Exemplo:
O intervalo de empuxo é de 0 a 1000, onde 1000 é MUITO.
Passo 1
Simule com confiança (0 + 1000) / 2 = 500. Resultado: muita confiança
Passo 2
O intervalo agora é de 0 a 500 Simule com confiança (0 + 500) / 2 = 250. Resultado: muita confiança
Etapa 3
O intervalo agora é de 0 a 250 Simular com confiança (0 + 250) / 2 = 125 Resultado: confiança insuficiente
Passo 4
O intervalo agora é de 125 a 250 Simule com confiança (125 + 250) /2=187.5 Resulte em muita confiança
Etapa # 5 O intervalo agora é de 125 a 187,5 Simule com confiança (125 + 187,5) /2=156,25 O resultado é pouca confiança
Etapa 6: o intervalo agora é de 156,25 a 187,5 O intervalo está abaixo do limite de 35, o que significa que é uma estimativa suficientemente boa.
Resultado final = (187.5 + 156.25) / 2 = 171.875
fonte