2015-01-05 11 views
6

Sto lavorando ad un piccolo programma che mostra le barche a remi in movimento. Il seguente mostra un semplice codice di esempio (Python 2.x):Codice per assomigliare ad una corsa a remi

import time 
class Boat: 
    def __init__(self, pace, spm): 
     self.pace = pace #velocity of the boat in m/s 
     self.spm = spm #strokes per minute 
     self.distance = 0 #distance travelled 

    def move(self, deltaT): 
     self.distance = self.distance + (self.pace * deltaT) 

boat1 = Boat(3.33, 20) 
while True: 
    boat1.move(0.1) 
    print boat1.distance 
    time.sleep(0.1) 

Come si può vedere una barca ha un ritmo e le righe con un numero di colpi al minuto. Ogni volta che viene chiamato il metodo move(deltaT), si sposta di una certa distanza in base al ritmo.

L'imbarcazione precedente viaggia a un ritmo costante che non è realistico. Una vera barca a remi accelera all'inizio di un colpo e poi decelera dopo che le lame di canottaggio hanno lasciato l'acqua. Ci sono molti grafici on-line che mostrano una tipica curva a remi (forza mostrata qui, la velocità è simile):

Rowing Stroke Graph Fonte

: highperformancerowing.net

Il ritmo deve essere costante nel tempo, ma dovrebbe cambiare durante la corsa.

Qual è il modo migliore per modificare la velocità costante in una curva che (almeno in pratica) assomiglia ad una corsa a remi più realistica?

Nota: qualche idea su come taggare meglio questa domanda? È un problema di algoritmo?

+1

Utilizzare l'interpolazione spline, ad es. Da SciPy. – nwk

+0

Vedere anche il sito SE per le statistiche http://stats.stackexchange.com – smci

+0

E la trasformazione smoothing stat_smooth nella libreria ggplot. – smci

risposta

2

Se il vostro obiettivo è quello di venire semplicemente con qualcosa di visivamente plausibile e non di fare una simulazione fisica completa, si può semplicemente aggiungere una sinusoide alla posizione.

class Boat: 
    def __init__(self, pace, spm, var=0.5): 
     self.pace = pace #average velocity of the boat in m/s 
     self.sps = spm/60.0 #strokes per second 
     self.var = var  #variation in speed from 0-1 
     self.totalT = 0  #total time 
     self.distance = 0 #distance traveled 

    def move(self, deltaT): 
     self.totalT += deltaT 
     self.distance = self.pace * (self.totalT + self.var * math.sin(self.totalT * self.sps * 2*math.pi) 

Devi essere attenti con la variazione var, se diventa troppo alta la barca potrebbe andare avanti e distruggere l'illusione.

+0

Il risultato del codice funziona, come ho provato un vogatore con una velocità di 10 m/se un SPM di 20 righe di 30 m in un colpo: https://ideone.com/wHjZs3 La velocità durante la corsa sembra comunque saltare avanti e indietro. Qualche idea cosa c'è di sbagliato nel calcolo? Non dobbiamo mettere il ritmo in un'onda sinusoidale invece del tempo? – MOnsDaR

+0

@ MOnsDaR scusate, ho avuto una correzione che ho apportato ma non ho copiato nella risposta. '/ Self.sps' dovrebbe essere' * self.sps'. –

+0

Questo ha fatto il trucco, i valori ora stanno aumentando/diminuendo lungo un'onda sinusoidale: https://ideone.com/2Cb6u8 Tuttavia la curva è esattamente inversa a quello che mi aspetterei: inizia veloce, va più lentamente, finisce velocemente. Dovrebbe essere il contrario. Ho giocato con l'equazione ma non riuscivo a farlo funzionare correttamente, potresti aiutarmi un'ultima volta? – MOnsDaR

1

È possibile convertire una curva come questa in un'equazione polinomiale per la velocità.

Una descrizione/esempio di come fare questo sono disponibili all'indirizzo:

python numpy/scipy curve fitting

Questo vi mostra come prendere un insieme di coordinate x, y (che si può ottenere mediante ispezione del vostro esistente trama o da dati reali) e creare una funzione polinomiale.

Se si utilizza la stessa curva per ogni oggetto Barca, è possibile semplicemente codificarlo nel programma. Ma potresti anche avere un'equazione polinomiale separata per ogni oggetto della Barca, assumendo che ogni vogatore o barca abbia un profilo diverso.

+1

Appena notato che il tuo grafico ha Forza sull'asse y. La forza è l'accelerazione di massa *. Poiché la tua massa è costante, è essenzialmente una trama di accelerazione (non di velocità). – jrel

+0

Questo è un buon approccio avanzato, è probabilmente un po 'complesso per ora. Prenderò in considerazione questo aspetto quando la mia applicazione richiede una soluzione più sofisticata – MOnsDaR

1

È possibile eseguire una semplice integrazione dell'equazione differenziale del movimento. (Questo è quello che stai già facendo per ottenere lo spazio in funzione del tempo, con velocità costante, x' = x + V.dt.)

Assumere un modello semplice con una forza costante durante la corsa e nessuna forza durante la planata, e trascinare proporzionale a la velocità.

Quindi l'accelerazione è a = P - D.v durante la corsa e - D.v durante la planata (decelerazione).

La velocità è approssimata a v' = v + a.dt.

Lo spazio è approssimato a x' = x + v.dt.

Se dt è sufficientemente piccolo, questo movimento dovrebbe apparire realistico. È possibile perfezionare il modello con una legge della forza più accurata e tecniche di integrazione migliori come Runge-Kutta, ma non sono sicuro che ne valga la pena.

Sotto un grafico di esempio di velocità e spazio contro tempo utilizzando questa tecnica.Mostra oscillazioni di velocità che stabiliscono rapidamente un regime periodico e spostamenti quasi-lineari con ondulazioni.

enter image description here

+0

Immagino che questa sia una soluzione globale abbastanza valida. Comunque la mia domanda è più intenzionale per chiedere "Come posso modellare la curva per essere come un colpo di canottaggio, ma mantenere il ritmo generale". – MOnsDaR

Problemi correlati