EMdrive: Énergie cinétique VS énergie consommée

Soyez le premier à donner votre avis sur cette source.

Vue 3 419 fois - Téléchargée 299 fois

Description

Un possible propulseur spatial, l'EMdrive proposé par Roger Shawyer, serait capable de générer une poussée sans propulsion par réaction. Ainsi j'ai voulu faire un petit programme donnant le temps T (à partir d'un temps T0=0) quand l'énergie cinétique de ce propulseur devient supérieur ou égale à l'énergie consommée.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
4
Date d'inscription
vendredi 5 mars 2010
Statut
Membre
Dernière intervention
1 juin 2016

Bien pour le using namespace, je ne savait pas!
Merci encore.
Messages postés
4
Date d'inscription
vendredi 5 mars 2010
Statut
Membre
Dernière intervention
1 juin 2016

Merci pour le code, il va falloir étudier tout cela.
Messages postés
3813
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
12 juin 2020
108
Bonjour.

La finalité du code est intéressante, mais la technique/design de code est améliorable. On sent que tu viens du C, et que tu te mets au C++, et tu commets quelques maladresses classiques.

Quelques conseils/critiques:
  • Évite les using namespace, voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace
  • Les typedef partent d'une bonne intention, mais ils ne sont pas nécessaires. D'une part parce qu'au final, seul le type double est utilisée, d'autre part, car ces redéfinitions existent déjà dans <cstdint> (je t'invite à jeter un coup d'oeil, tu y trouveras uint64_t, uint32_t, etc...).
  • Tous les includes en *.h ne sont pas nécessaires en C++. On préfère généralement les versions préfixées par "c" (cstring, cmath, etc...). De plus, on peut s'en passer (voir proposition de correction ci-dessous).
  • L'enum "type_reponse" n'est pas nécessaire. C'est au final une émulation d'un booléen.
  • Quand tu nommes une classe, inutile de préfixer par "class_", on sait déjà que c'en est une :). Idem pour "obj_". En C++, on met par convention une majuscule aux classes.
  • Les attributs d'une classe sont généralement préfixées par "_" pour les différencier de variables locales.
  • Plutôt que de répéter le même motif partout (copier-coller), il est préférable de factoriser le code. Par exemple, les fonctions de demande de valeur peuvent toute être écrite en une seule fonction générique.
  • Il faut "protéger" tes std::cin ! Si je mets "coucou" comme valeur, ton programme va boucler infiniment car tu ne détectes pas l'entrée d'un mauvais type (voir genericAsk ci-dessous).
  • Quand du code n'a pas vocation a être exporté ailleurs, on le met dans un namespace anonyme.
  • Préfère les listes d'initialisation plutôt que d'affecter des valeurs dans le corps du constructeur.
  • Au niveau design, il faut séparer le calcul et l'affichage, qui sont deux tâches distinctes.
  • Une méthode qui n'a pas vocation à modifier les attributs de la classe doit être marquée "const".
  • Plutôt que de faire une méthode "calcul" (qui porte mal son nom car elle est censée uniquement calculer et non afficher), on préférera fournir à notre classe le moyen d'être affichée comme un vrai type via "operator<<".
  • Au lieu de faire plein de std::cout, chaîne-les ! Ça t'évite la création de plein d'objets std::cout pour rien (std::cout est une classe !). Remarque aussi que "cou" "cou" et "coucou" en C et en C++ c'est pareil (le compilateur concatène les constantes). Dans la même optique, préfère écrire "\ntoto" plutôt que "\n" << "toto", ce qui t'évite un appel de fonction pour rien (le "<<" est en fait une fonction, le compilateur transforme ça en: operator<<(operator(out, "\n"), "toto").
  • Évite les magic number. C'est-à-dire les nombres compliquées qui sortent de nulle part (je pense à 31536000 et à 299792458 que j'aurais remplacé par des constantes).


Voici une proposition de réécriture:
#include <iostream>
#include <string>
#include <limits>

namespace
{
  const double LIGHT_SPEED = 299792458;
  const double YEAR = 31536000;

  double genericAsk(const std::string& msg,
            const std::string& err_msg,
            double min, double max)
  {
    bool valid = true;
    double value = 0;

    do
    {
      valid = true;
      while (std::cout << '\n' << msg && !(std::cin >> value))
      {
        std::cin.clear(); // Clear bad input flag
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Discard input
        std::cout << "Invalid input; please re-enter.\n";
      }

      if (value < min || value > max)
      {
        std::cout << "\nATTENTION\n" << err_msg;
        valid = false;
      }
    }
    while (!valid);

    return value;
  }

  class EMDrive
  {
  public:
    EMDrive();
    void askMasse();
    void askPower();
    void askPouss();
    void compute();
    void print(std::ostream& out) const;

  private:
    double _mas_emd;
    double _ene_emd;
    double _pou_emd;
    double _temps;
    double _vitesse;
    double _distance;
    double _energie_cinetique;
    double _energie_consommee;
  };

  EMDrive::EMDrive()
    : _mas_emd(100), // Masse de 100 kg
      _ene_emd(300), // Consommation de 300 watt
      _pou_emd(0.01) // Poussee de 0.01 Newton
  {
    compute(); // Calcul par défaut
  }

  void EMDrive::askMasse()
  {
    _mas_emd = genericAsk("Masse de l'emdrive en kg [1;1000] => ",
              "La masse doit etre entre [1 et 1000] kg",
              1, 1000);
  }

  void EMDrive::askPower()
  {
    _ene_emd = genericAsk("Puissance de l'emdrive en watt [10;10000] => ",
              "la puissance doit etre entre [10 et 10000] watt",
              10, 10000);
  }

  void EMDrive::askPouss()
  {
    _pou_emd = genericAsk("Poussee de l'emdrive en newton [0.000001;100] => ",
              "La poussee doit etre entre [0.000001 et 100] newton",
              0.000001, 100);
  }

  void EMDrive::compute()
  {
    _temps = (2 * _mas_emd * _ene_emd) / (_pou_emd * _pou_emd);
    _vitesse = (_pou_emd / _mas_emd) * _temps;
    _distance = 0.5 * (_pou_emd / _mas_emd) * _temps * _temps;
    _energie_cinetique = 0.5 * (_pou_emd * _temps * _pou_emd * _temps) / _mas_emd;
    _energie_consommee = _ene_emd * _temps;
  }

  void EMDrive::print(std::ostream& out) const
  {
    out <<
      "\n--------------------------------------------------------------"
      "\n*** Au-dela de ce temps, E. cinetique > E. consommee ***"
    << "\nTemps en seconde  = " << _temps
    << "\nTemps en minute   = " << _temps / 60.0
    << "\nTemps en heure    = " << _temps / 3600.0
    << "\nTemps en jour     = " << _temps / 86400.0
    << "\nTemps en annee    = " << _temps / YEAR

    << "\n\nVitesse en m/s    = " << _vitesse
    << "\nVitesse en km/s   = " << _vitesse / 1000.0

    << "\n\nDistance en m     = " << _distance
    << "\nDistance en km    = " << _distance / 1000.0
    << "\nDistance en s.Lu  = " << _distance / LIGHT_SPEED

    << "\n\nEnergie cinetique en joule   = " << _energie_cinetique
    << "\nEnergie cinetique en K.joule = " << _energie_cinetique / 1000.0
    << "\nEnergie cinetique en M.joule = " << _energie_cinetique / 1000000.0
    << "\nEnergie cinetique en G.joule = " << _energie_cinetique / 1000000000.0

    << "\n\nEnergie consommee en joule   = " << _energie_consommee
    << "\nEnergie consommee en K.joule = " << _energie_consommee / 1000.0
    << "\nEnergie consommee en M.joule = " << _energie_consommee / 1000000.0
    << "\nEnergie consommee en G.joule = " << _energie_consommee / 1000000000.0
    << "\n--------------------------------------------------------------";
  }

  std::ostream& operator<<(std::ostream& out, const EMDrive& emdrive)
  {
    emdrive.print(out);
    return out;
  }
} // namespace

int main()
{
  EMDrive emdrive;

  do
  {
    emdrive.askMasse();
    emdrive.askPower();
    emdrive.askPouss();
    emdrive.compute();

    std::cout << emdrive << std::endl;
  }
  while (genericAsk("Voulez-vous recommencer (0 c'est non, autre c'est oui) => ",
            "Nombre invalide!", 0, std::numeric_limits<double>::max()) != 0);

  return 0;
}

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.