<commit_before>﻿
// The files containing the tree of child classes of |Body| must be included in
// the order of inheritance to avoid circular dependencies.  This class will end
// up being reincluded as part of the implementation of its parent.
#ifndef PRINCIPIA_PHYSICS_MASSIVE_BODY_HPP_
#include "physics/massive_body.hpp"
#else
#ifndef PRINCIPIA_PHYSICS_ROTATING_BODY_HPP_
#define PRINCIPIA_PHYSICS_ROTATING_BODY_HPP_

#include <experimental/optional>
#include <vector>

#include "geometry/grassmann.hpp"
#include "geometry/rotation.hpp"
#include "quantities/named_quantities.hpp"
#include "quantities/quantities.hpp"

namespace principia {
namespace physics {
namespace internal_rotating_body {

using geometry::AngularVelocity;
using geometry::Instant;
using geometry::Rotation;
using geometry::Vector;
using quantities::Angle;
using quantities::AngularFrequency;
using quantities::Length;

template<typename Frame>
class RotatingBody : public MassiveBody {
  static_assert(Frame::is_inertial, "Frame must be inertial");

 public:
  class Parameters {
   public:
    // |reference_angle| is the angle of the prime meridian at
    // |reference_instant|.  |angular_frequency| gives the rate of rotation of
    // the body around the pole (it may be negative, as is the convention for
    // planets and satellites whose rotation is retrograde).  The direction of
    // the pole is specified in |Frame| using |right_ascension_of_pole| and
    // |declination_of_pole|.
    Parameters(Length const& mean_radius,
               Angle const& reference_angle,
               Instant const& reference_instant,
               AngularFrequency const& angular_frequency,
               Angle const& right_ascension_of_pole,
               Angle const& declination_of_pole);

   private:
    Length const mean_radius_;
    Angle const reference_angle_;
    Instant const reference_instant_;
    AngularFrequency const angular_frequency_;
    Angle const right_ascension_of_pole_;
    Angle const declination_of_pole_;
    template<typename F>
    friend class RotatingBody;
  };

  RotatingBody(MassiveBody::Parameters const& massive_body_parameters,
               Parameters const& parameters);
  ~RotatingBody() = default;

  // Returns the radius passed at construction.
  Length mean_radius() const override;

  // Returns the direction defined by the right ascension and declination passed
  // at construction.
  Vector<double, Frame> const& polar_axis() const;

  // Returns the right ascension passed at construction.
  Angle const& right_ascension_of_pole() const;

  // Returns the declination at construction.
  Angle const& declination_of_pole() const;

  // Returns the angular frequency passed at construction.
  AngularFrequency const& angular_frequency() const;

  // Returns the angular velocity defined by the right ascension, declination,
  // and angular frequency passed at construction.
  AngularVelocity<Frame> const& angular_velocity() const;

  // Returns the position at time |t|.
  Angle AngleAt(Instant const& t) const;

  // Returns the rotation relating the reference frame of the surface of this
  // body to |Frame|.  The reference frame of the surface is defined as follows:
  //   - the z axis is the |polar_axis|;
  //   - the x axis points from the centre of the body to the reference
  //     meridian;
  //   - the reference frame has the same handedness as |Frame|.
  // Following this definition,
  //   Displacement<SurfaceFrame>(RadiusLatitudeLongitude(r, φ, λ))
  // converts planetocentric coordinates to a displacement from the body centre
  // in the surface frame.  Note that RadiusLatitudeLongitude should *not* be
  // used for planetographic coordinates, which use a latitude defined from
  // a reference ellipsoid, and a longitude around the negative pole---except
  // for the Earth, the Moon, and the Sun.
  // In the case of the Earth, see geodetic vs. geocentric latitudes.
  template<typename SurfaceFrame>
  Rotation<SurfaceFrame, Frame> FromSurfaceFrame(Instant const& t) const;

  // Returns the rotation at time |t|.
  Rotation<Frame, Frame> RotationAt(Instant const& t) const;

  // Returns false.
  bool is_massless() const override;

  // Returns true.
  bool is_oblate() const override;

  void WriteToMessage(not_null<serialization::Body*> message) const override;

  void WriteToMessage(
      not_null<serialization::MassiveBody*> message) const override;

  // Fails if the |RotatingBody| extension is absent from the message.<commit_msg>why were there 7 deletes in that line O_o<commit_after>﻿
// The files containing the tree of child classes of |Body| must be included in
// the order of inheritance to avoid circular dependencies.  This class will end
// up being reincluded as part of the implementation of its parent.
#ifndef PRINCIPIA_PHYSICS_MASSIVE_BODY_HPP_
#include "physics/massive_body.hpp"
#else
#ifndef PRINCIPIA_PHYSICS_ROTATING_BODY_HPP_
#define PRINCIPIA_PHYSICS_ROTATING_BODY_HPP_

#include <experimental/optional>
#include <vector>

#include "geometry/grassmann.hpp"
#include "geometry/rotation.hpp"
#include "quantities/named_quantities.hpp"
#include "quantities/quantities.hpp"

namespace principia {
namespace physics {
namespace internal_rotating_body {

using geometry::AngularVelocity;
using geometry::Instant;
using geometry::Rotation;
using geometry::Vector;
using quantities::Angle;
using quantities::AngularFrequency;
using quantities::Length;

template<typename Frame>
class RotatingBody : public MassiveBody {
  static_assert(Frame::is_inertial, "Frame must be inertial");

 public:
  class Parameters {
   public:
    // |reference_angle| is the angle of the prime meridian at
    // |reference_instant|.  |angular_frequency| gives the rate of rotation of
    // the body around the pole (it may be negative, as is the convention for
    // planets and satellites whose rotation is retrograde).  The direction of
    // the pole is specified in |Frame| using |right_ascension_of_pole| and
    // |declination_of_pole|.
    Parameters(Length const& mean_radius,
               Angle const& reference_angle,
               Instant const& reference_instant,
               AngularFrequency const& angular_frequency,
               Angle const& right_ascension_of_pole,
               Angle const& declination_of_pole);

   private:
    Length const mean_radius_;
    Angle const reference_angle_;
    Instant const reference_instant_;
    AngularFrequency const angular_frequency_;
    Angle const right_ascension_of_pole_;
    Angle const declination_of_pole_;
    template<typename F>
    friend class RotatingBody;
  };

  RotatingBody(MassiveBody::Parameters const& massive_body_parameters,
               Parameters const& parameters);
  ~RotatingBody() = default;

  // Returns the radius passed at construction.
  Length mean_radius() const override;

  // Returns the direction defined by the right ascension and declination passed
  // at construction.
  Vector<double, Frame> const& polar_axis() const;

  // Returns the right ascension passed at construction.
  Angle const& right_ascension_of_pole() const;

  // Returns the declination at construction.
  Angle const& declination_of_pole() const;

  // Returns the angular frequency passed at construction.
  AngularFrequency const& angular_frequency() const;

  // Returns the angular velocity defined by the right ascension, declination,
  // and angular frequency passed at construction.
  AngularVelocity<Frame> const& angular_velocity() const;

  // Returns the position at time |t|.
  Angle AngleAt(Instant const& t) const;

  // Returns the rotation relating the reference frame of the surface of this
  // body to |Frame|.  The reference frame of the surface is defined as follows:
  //   - the z axis is the |polar_axis|;
  //   - the x axis points from the centre of the body to the reference
  //     meridian;
  //   - the reference frame has the same handedness as |Frame|.
  // Following this definition,
  //   Displacement<SurfaceFrame>(RadiusLatitudeLongitude(r, φ, λ))
  // converts planetocentric coordinates to a displacement from the body centre
  // in the surface frame.  Note that RadiusLatitudeLongitude should *not* be
  // used for planetographic coordinates, which use a latitude defined from
  // a reference ellipsoid, and a longitude around the negative pole---except
  // for the Earth, the Moon, and the Sun.
  // In the case of the Earth, see geodetic vs. geocentric latitudes.
  template<typename SurfaceFrame>
  Rotation<SurfaceFrame, Frame> FromSurfaceFrame(Instant const& t) const;

  // Returns the rotation at time |t|.
  Rotation<Frame, Frame> RotationAt(Instant const& t) const;

  // Returns false.
  bool is_massless() const override;

  // Returns true.
  bool is_oblate() const override;

  void WriteToMessage(not_null<serialization::Body*> message) const override;

  void WriteToMessage(
      not_null<serialization::MassiveBody*> message) const override;

  // Fails if the |RotatingBody| extension is absent from the message.
{'fraction_non_alphanumeric': 0.07573244886677723, 'fraction_numerical': 0.0001105583195135434, 'mean_word_length': 3.9567123287671233, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '208178', 'n_tokens_mistral': 2580, 'n_tokens_neox': 2430, 'n_words': 921}