Catholic Info

Traditional Catholic Faith => Fighting Errors in the Modern World => The Earth God Made - Flat Earth, Geocentrism => Topic started by: Struthio on October 08, 2018, 10:59:52 PM

Title: Reentry possible?
Post by: Struthio on October 08, 2018, 10:59:52 PM
The ISS (International Space Station) takes roughly 90 minutes to orbit the earth. That's a relative speed with respect to the resting earth of roughly 42,000km per 90minutes or 28,000km/h. A spaceship picking up astronots [sic] and bringing them back to earth basically falls down to earth like a meteor and should burn completely while trying to reach earth passing through the atmosphere, given the high initial radial velocity.

To prevent this, apollo command modules had a heat shield made of phenolic epoxy resin (see wiki: Atmospheric entry / Ablative heat shield (https://en.wikipedia.org/wiki/Atmospheric_entry#Ablative)).

I admit that I don't believe that such a shield makes a big difference, but for the sake of the argument let's assume that it protects the command module and the astronots inside.

Then, we have the Russian Vostok programme (https://en.wikipedia.org/wiki/Vostok_programme) (Yuri Gagarin). Well, they just had a tin can. No heat shield made of phenolic epoxy resin or whatever. How could they return to earth without any shield?

1.) Why don't NASA experts reject the Vostok programme as a conspiracy?
2.) How do ICBMs (intercontinental ballistic missiles) return to earth without burning completely in the atmosphere? (they have no heat shield and a high radial velocity before reentry)
Title: Re: Reentry possible?
Post by: Stanley N on October 08, 2018, 11:56:58 PM
1.) Why don't NASA experts reject the Vostok programme as a conspiracy?
2.) How do ICBMs (intercontinental ballistic missiles) return to earth without burning completely in the atmosphere? (they have no heat shield and a high radial velocity before reentry)
1) why? Did the Vostok missions not happen?
2) are you sure they have "no" heat management? ICBMs payloads can be designed to handle higher temperatures than people could.
Title: Re: Reentry possible?
Post by: Struthio on October 09, 2018, 01:00:53 AM
1) why? Did the Vostok missions not happen?
2) are you sure they have "no" heat management? ICBMs payloads can be designed to handle higher temperatures than people could.

1.) Well, as I explained in the OP, I assume that NASA experts would think they could not happen.
2.) There is no known heat management, while impact speed is up to 7 km/s.
Title: Re: Reentry possible?
Post by: Neil Obstat on October 09, 2018, 03:12:21 AM
.
The Russian Soyuz system has two compartments: one for the cosmonauts the other for the space junk they're going to let burn up in the re-entry. It's a sort of figure-8 arrangement with the cosmonauts in the bottom part and the junk in the top part, falling downward.
.
You can see this figure-8 shaped Soyuz in the unit attached to the ISS. Soyuz is the dark gray thing in the following image:
.
(https://s17-us2.startpage.com/cgi-bin/serveimage?url=https%3A%2F%2Fthenypost.files.wordpress.com%2F2018%2F09%2F180919-russian-spacewalk-probe-leak-feature.jpg%3Fquality%3D90%26amp%3Bstrip%3Dall%26amp%3Bw%3D618%26amp%3Bh%3D410%26amp%3Bcrop%3D1&sp=389c24b9fbd571ad52e2ae4aa0968500)
.
.
The following diagram shows 6 visiting vehicles in Feb 2011; two Soyuz modules (TMA-01M and TMA-20) as well as a Progress M-09M, HTV-2, ATV-2, and STS-133 Discovery (Space Shuttle), all attached to the ISS:

.
(https://s16-us2.startpage.com/cgi-bin/serveimage?url=https%3A%2F%2Fhistoricspacecraft.com%2FDiagrams%2FS%2FISS_Visiting_Vehicles_Feb2011_RK2011.jpg&sp=cca9963c60617eac8f20e9d912623092)

.
.
There is a heat shield on one end of the crew's compartment:
(https://s16-us2.startpage.com/cgi-bin/serveimage?url=http%3A%2F%2Fsnappa.static.pressassociation.io%2Fassets%2F2016%2F06%2F14082904%2F1465889343-324280e221fc4f764fabb0f5802e0dc9-1366x1057.jpg&sp=4385e0581a3bc98cdcf8f59d12897211)
.
The internal quarters for the cosmonauts is very cramped, but they say it's "comfortable." The seats are custom-molded to the shape of each man's body, but they don't have much room to move around inside:
(https://s16-us2.startpage.com/cgi-bin/serveimage?url=http%3A%2F%2Fspaceflight101.com%2Fiss-expedition-46%2Fwp-content%2Fuploads%2F2017%2F01%2FCcA-f8EVAAEj-PX.jpg-orig.jpg&sp=7d8f6caffdfde89151e9736f5d9b43e7)
.
.
When it's all over, the Soyuz re-entry unit gets quite charred on the outside from the hot air friction of re-entry:
(https://s16-us2.startpage.com/cgi-bin/serveimage?url=https%3A%2F%2Fi.stack.imgur.com%2FDcnq1.jpg&sp=78198260fcc32d22301bd361aa14e2df)
Title: Re: Reentry possible?
Post by: Neil Obstat on October 09, 2018, 03:32:16 AM
.
Woops. Now I see you're asking about the Vostok system, not the Soyuz.
I found this diagram online:
.
(https://s17-us2.startpage.com/cgi-bin/serveimage?url=https:%2F%2Fimg.purch.com%2Fw%2F660%2FaHR0cDovL3d3dy5zcGFjZS5jb20vaW1hZ2VzL2kvMDAwLzAwOC8zMjkvb3JpZ2luYWwvdm9zdG9rX2RpYWdyYW1fMDIwLmpwZw%3D%3D&sp=ca18ee55eec76fdeba5e8805ca10ff6b)
.
.
Just how the heat shield works they don't make very clear, but here are some photos:
.
(https://s17-us2.startpage.com/cgi-bin/serveimage?url=http%3A%2F%2Fwww.planet4589.org%2Fspace%2Fmisc%2Fmoscow%2Fp0239.JPG&sp=8638a2db4b4cbd0bc70d573988e615f6)  (https://s17-us2.startpage.com/cgi-bin/serveimage?url=http%3A%2F%2Fhowitworks.wpengine.com%2Fwp-content%2Fuploads%2F2011%2F04%2FCredit-ESA.jpg&sp=0ae36da5cfabde6e7b20013c1d0fa37a)
.
I have no idea how anyone would want to have Yuri Gagarin's job.
The Soyuz system looks bad enough but this looks like a death trap.
With the Space Shuttle there was a bit of breathing room between the tiles and the astronauts.
But here it's like you're a baby chick in an eggshell -- creepy.
Title: Re: Reentry possible?
Post by: Stanley N on October 09, 2018, 05:56:27 AM
1.) Well, as I explained in the OP, I assume that NASA experts would think they could not happen.
2.) There is no known heat management, while impact speed is up to 7 km/s.
1) Again, why? As far as I know the vostok capsules did have a heat shield - a resin - but the composition was a little different. The vostok capsules were also spherical (as Neil's pictures show) and designed for limited control, so the heat shielding had to be on all sides. This increased weight. (Some Soviet systems also used metal heat shields which dispersed heat by radiation.) Just because the vostok program used a somewhat different technology does not mean it couldn't work.
2) ICBMs have reentry vehicles - vehicles designed for reentry. Usually MIRVs, multiple independent reentry vehicles per one ICBM. They are not protecting people, though, so they can use less shielding.
Title: Re: Reentry possible?
Post by: Struthio on October 09, 2018, 06:02:51 AM
Nice comments Neil Obstat, with many images. Thank you.

I didn't take much time to find out that you are not addressing the questions of the opening post. Your first comment is completely off topic, your second mentions one of the keywords, but then it is as off topic as the first. You keep avoiding to even mention the questions of the opening post.

The following is a photo of a scientific satellite burning up on reentry in the earth's atmosphere:

(http://www.slate.com/content/dam/slate/blogs/bad_astronomy/2013/11/01/GOCE_reenters_atmosphere.jpg.CROP.original-original.jpg) (http://spaceinimages.esa.int/Images/2013/11/GOCE_reenters_atmosphere)
GOCE re-enters Earth's atmosphere.
Photo by Bill Chater / ESA
Title: Re: Reentry possible?
Post by: Neil Obstat on October 10, 2018, 01:36:42 AM
.
I remember watching a re-entry satellite burning up in the sky many years ago.
I was surprised to see that it went across the sky in a very long arc, and broke up into pieces along the way.
Even the pieces continued to burn and leave a smoke trail. 
I had been expecting to see parts falling to the ground, but everything kept moving horizontally, not downward.
It was a strong showing of how much kinetic energy is in satellites when they're in orbit.
When the Space Shuttle broke up on re-entry it crossed several states while still going sideways.
Title: Re: Reentry possible?
Post by: Neil Obstat on October 10, 2018, 02:03:58 AM
.
I found this 40-minute video explaining the Soyuz re-entry experience. 
I guess it's pretty reliable but it looks like quite an other-worldly ride.
This one is a lot better than another one I saw a few months go:
.
https://www.youtube.com/watch?v=-l7MM9yoxII
Title: Re: Reentry possible?
Post by: Neil Obstat on October 10, 2018, 10:23:21 AM
.
At min. 6:10 ESA astronaut Paolo Nespoli describes Soyuz detachment from the space station and how that felt, then later describes the explosive bolts (10:30) that separate the Soyuz parts as being like someone outside is smashing the capsule with a sledge hammer, "...really interesting, actually." Okay, interesting. So we're in this eggshell out here in a vacuum and we could explode and get the bends and our blood boil and our temperature drop to 200 below zero, and that's "really interesting, actually."
.
It takes a special breed to be an astronaut.
.
At min. 8:10 they describe the braking as Soyuz begins its descent through the atmosphere.
.
At 8:30, ESA astronaut Frank De Winne explains what happens if they don't burn enough ("...we can actually skip off the atmosphere ... and that of course would not be successful re-entry") -- More like "Oh sh*t, WE'RE DOOMED!" They would be sent back out above the atmosphere in a completely random trajectory toward some unchosen destination which could be just about anywhere on earth, even the Arctic Ocean, but with possibly insufficient fuel to properly control a second attempt. But De Winne calmly omits that part and goes on to talk about the other possibility, what happens if they burn too much.
.
At 8:43, "On the other hand if we burn too much and we come in too steep, then we would have too much speed when we are in the lower parts of the atmosphere. The heat which is normally around two-three thousand degrees Celsius (!?), would be much higher and we have risk of burning up." At that point, they are TOAST. Or as a hospital worker I know says, crispy critters. "So also therefore, it is very critical that we do the correct de-orbit burn, and that we really fix this around 120 meters per second."
.
Two or three thousand degrees Celsius is 3,600 to 5,400 degrees Fahrenheit. And that's "normal?" That's hot enough to melt titanium. Maybe there's a mistake there.
Title: Re: Reentry possible?
Post by: Struthio on October 10, 2018, 08:48:45 PM
1) Again, why? As far as I know the vostok capsules did have a heat shield - a resin - but the composition was a little different. The vostok capsules were also spherical (as Neil's pictures show) and designed for limited control, so the heat shielding had to be on all sides. This increased weight. (Some Soviet systems also used metal heat shields which dispersed heat by radiation.) Just because the vostok program used a somewhat different technology does not mean it couldn't work.
2) ICBMs have reentry vehicles - vehicles designed for reentry. Usually MIRVs, multiple independent reentry vehicles per one ICBM. They are not protecting people, though, so they can use less shielding.

A resin? Which type of resin?

Concerning the ICBM reentry vehicles, it's not about 50°C or 500°C or 1000°C. Its about temperatures no known material can stand.

See my following post.
Title: Re: Reentry possible?
Post by: Struthio on October 10, 2018, 09:05:55 PM
I made a simulation of Yuri Gagarins reentry. Below the results as well as the source code of the software.

Gagarin is said to have reentered the atmosphere in a sperical capsule of 2400kg and 2.3m diameter. Reentry starts at 130km height at a tangential velocity of 8000m/s (28800km/h). The plot shows:

(https://www.cathinfo.com/the-earth-god-made-flat-earth-geocentrism/reentry-possible/?action=dlattach;attach=12149;image)


More comments to follow.

Here's the Java source code. Copy into a single file named GagarinsReentry.java and run from your IDE.
Code: [Select]

import static java.awt.BasicStroke.CAP_ROUND;
import static java.awt.BasicStroke.JOIN_ROUND;
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
import static java.lang.Math.PI;
import static java.lang.Math.abs;
import static java.lang.Math.atan2;
import static java.lang.Math.cos;
import static java.lang.Math.exp;
import static java.lang.Math.sin;
import static java.lang.Math.sqrt;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Desktop;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.HeadlessException;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.imageio.ImageIO;

/**
 * Simulation of the re-entry of Yuri Gagarin.
 *
 * <pre>
 *                                     time    accel  max power  max temp
 * Result:                             04'39"  23.5g  2879.84MW  7435K
 * Horizontal initial speed 0m/s:      03'51"   4.2g    88.73MW  3115K
 * Drag coefficient ten times:         08'52"  20.4g  2469.70MW  7155K
 * </pre>
 *
 * <ul>
 * <li>Re-entry takes four times less time than said 20min.</li>
 * <li>Horizontal distance is three and a half times shorter than 4000km.</li>
 * <li>Maximum temperature is much too high.</li>
 * <li>With constant drag coefficient of 0.47 re-entry is a few percent faster.</li>
 * <li>15cm diameter and 10kg: virtually same result (power is four times higher though)</li>
 * </ul>
 *
 * @see https://en.wikipedia.org/wiki/Vostok_1
 * @see https://de.wikipedia.org/wiki/Fall_mit_Luftwiderstand#Fall_mit_Luftwiderstand:_Newton-Reibung
 * @see https://de.wikipedia.org/wiki/Methode_der_kleinen_Schritte
 * @see https://de.wikipedia.org/wiki/Barometrische_Höhenformel
 * @see https://de.wikipedia.org/wiki/Stefan-Boltzmann-Gesetz
 * @see http://www.astronautix.com/v/vostok1.html
 * @see http://www.spacefacts.de/mission/english/vostok-1.htm
 * @see http://heiwaco.tripod.com/moontravelw1.htm#REE
 *
 * @author Struthio
 * @since October 2018
 *
 */
public class GagarinsReentry
{
   @Doc("Diameter of the spherical capsule in m.")
   private static final double d = 2.3;

   @Doc("Weight of the spherical capsule in kg.")
   private static final double m = 2400;

   @Doc("Sectional area of the spherical capsule in m^2.")
   private static final double Asectional = PI * sqr(0.5 * d);

   @Doc("Surface area of the spherical capsule in m^2.")
   private static final double Asurface = 4 * Asectional;

   @Doc("Gravitational acceleration at sea level in m/s^2.")
   private static final double g = 9.81;

   @Doc("Radius of the earth in m.")
   private static final double r = 6370000;

   @Doc("Mass density of air at sea level in kg/m^3.")
   private static final double rho0 = 1.293;

   @Doc("Speed of sound in m/s.")
   private static final double cAir = 331.5;

   @Doc("Calculation time interval in s.")
   private static final double dt = 0.01;

   @Doc("Current time in s.")
   private double t = 0;

   @Doc("Horizontal distance m.")
   private double x = 0;

   @Doc("Height above sea level in m.")
   private double y = 130000;

   @Doc("Horizontal speed in m/s.")
   private double vx = 8000;

   @Doc("Vertical speed in m/s.")
   private double vy = 0;

   @Doc("Horizontal acceleration in m/s.")
   private double ax = 0;

   @Doc("Vertical acceleration in m/s.")
   private double ay = 0;

   @Doc("Mass density of air at current height above sea level in kg/m^3.")
   private double rho = 0;

   @Doc("Drag coefficient.")
   private double cw = 0;

   @Doc("Braking force in N")
   private double F = 0;

   @Doc("Braking power in W")
   private double P = 0;

   @Doc("Maximum braking force in N")
   private double Pmax = 0;

   @Doc("Maximum acceleration in m/s^2")
   private double aMax = 0;

   private final DragCoefficient dragCoefficient = new DragCoefficient();

   private final List<List<Double>> signals = new ArrayList<>();
   {
      signals.add(new ArrayList<>());
      signals.add(new ArrayList<>());
      signals.add(new ArrayList<>());
      signals.add(new ArrayList<>());
      signals.add(new ArrayList<>());
      signals.add(new ArrayList<>());
   }

   /**
    * Program entry point.
    * <p>
    * prints text to stdout and opens a *.png-image in the systems image viewer.
    *
    * @param args
    *           arguments are ignored.
    */
   public static void main(final String... args)
   {

      try
      {
         final GagarinsReentry reentry = new GagarinsReentry();
         reentry.run();
         final Plotter.Config config = new Plotter.Config("Re-entry Yuri Gagarin", "",
               "y, Cw, T, \u03C1, y', y\"", reentry.time());
         new Plotter(config, reentry.signals).openRasterImageInEditor();
      }
      catch (final Throwable t)
      {
         t.printStackTrace();
      }
   }

   public GagarinsReentry()
   {

   }

   private void run()
   {

      step(true);
      printDoc();
      out("\n");
      out(" t[s]    ax      ay     rho        cw         F           vx           vy         x        h        P    \n");
      out("------ ------- ------- -------- -------- ----------- ------------ ------------ -------- -------- --------\n");
      print();
      int noOfSteps;
      for (noOfSteps = 0; y > 0; noOfSteps++)
      {
         step(false);
         if (noOfSteps % 10 == 0)
         {
            print();
         }
      }
      if (noOfSteps % 10 != 0)
      {
         print();
      }
      out("noOfSteps: %d\n", noOfSteps);
      out("%s  %.1fg  %.2fMW  %.0fK\n", time(), aMax / g, 1E-6 * Pmax, temperatureInK(Pmax));
   }

   private void printDoc()
   {

      for (final Field field : GagarinsReentry.class.getDeclaredFields())
      {
         final Doc doc = field.getAnnotation(Doc.class);
         if (doc != null)
         {
            final boolean accessible = field.isAccessible();
            try
            {
               field.setAccessible(true);
               final double value = (Double) field.get(this);
               String sValue;
               if (value == 0)
               {
                  sValue = String.format(Locale.US, "%12s", "0");
               }
               else if (abs(value) < 0.001 || abs(value) > 1E8)
               {
                  sValue = String.format(Locale.US, "%12.3E", value);
               }
               else
               {
                  sValue = String.format(Locale.US, "%12.3f", value);
               }
               out("%12s = %s %s\n", field.getName(), sValue, doc.value());
            }
            catch (final Exception e)
            {
               throw new IllegalStateException("unreached", e);
            }
            finally
            {
               field.setAccessible(accessible);
            }
         }
      }
   }

   private void print()
   {

      out("%s %7.2f %7.2f %8.2E %8.2f %10.2fN %8.2fkm/h %8.2fkm/h %7.0fm %7.0fm %6.1fMW\n", time(),
          ax, ay, rho, cw, F, 3.6 * vx, 3.6 * vy, x, y, 1E-6 * P);
   }

   private String time()
   {
      final int s = (int) (t + 0.5);
      return String.format("%02d'%02d\"", s / 60, s % 60);
   }

   private void step(final boolean initialize)
   {

      rho = rho0 * exp(-y / 8400);
      final double v = sqrt(sqr(vx) + sqr(vy));
      F = airFrictionForceInN(rho, y, v);
      final double alpha = atan2(vy, vx);
      final double Fx = F * cos(alpha);
      final double Fy = F * sin(alpha);
      ax = Fx / m;
      ay = Fy / m - g * (r / (r + y));
      if (!initialize)
      {
         t += dt;
         vx += ax * dt;
         vy += ay * dt;
         x += vx * dt;
         y += vy * dt;
      }
      final double a = sqrt(ax * ax + ay * ay);
      if (aMax < a)
      {
         aMax = a;
      }
      P = m * v * a;
      if (Pmax < P)
      {
         Pmax = P;
      }
      signals.get(0).add(y);
      signals.get(1).add(vy);
      signals.get(2).add(ay);
      signals.get(3).add(cw);
      signals.get(4).add(rho);
      signals.get(5).add(temperatureInK(P));
   }

   /**
    * Returns the temperature in Kelvin of the black sphere emitting the given power.
    */
   private static double temperatureInK(final double powerInWatts)
   {

      // https://de.wikipedia.org/wiki/Stefan-Boltzmann-Gesetz
      final double sigma = 5.670367E-8;
      return sqrt(sqrt(powerInWatts / (sigma * Asurface)));
   }

   /**
    * Returns the air friction force is Newtons.
    *
    * @param rho
    *           The mass desity of the air in kg/m^3.
    * @param h
    *           The height above sea level.
    * @param v
    *           The speed in m/s.
    * @return the air friction force is Newtons.
    * @throws IllegalArgumentException
    *            If the height above sea level exceeds 150km.
    * @see https://de.wikipedia.org/wiki/Str%C3%B6mungswiderstandskoeffizient
    */
   private double airFrictionForceInN(final double rho, final double h, final double v)
         throws IllegalArgumentException
   {

      if (h > 150000)
      {
         throw new IllegalArgumentException("formula valid up to 150km height only");
      }
      cw = dragCoefficient.getValue(abs(v / cAir));
      return -0.5 * rho * cw * Asectional * sqr(v);
   }

   private static double sqr(final double x)
   {
      return x * x;
   }

   private static void out(final String format, final Object... args)
   {

      System.out.format(Locale.US, format, args);
   }

   // unused - extract curve points from image
   public static void _main(final String... args) throws IOException
   {

      final double dx = 6;
      final double dy = 1.2;
      final BufferedImage image = ImageIO.read(new File("drag.png"));
      final int width = image.getWidth();
      final int height = image.getHeight();
      for (int x = 0; x < width; x += width / 100)
      {
         int y = 0;
         for (int yy = height - 1; yy > 0; yy--, y++)
         {
            final int rgb = image.getRGB(x, yy);
            final int brightness = (rgb & 0xFF) + (rgb >> 8 & 0xFF) + (rgb >> 16 & 0xFF);
            if (brightness < 0x180)
            {
               break;
            }
         }
         final double px = x * dx / width;
         final double py = y * dy / height;
         System.out.format(Locale.US, "    { %7.5f, %7.5f },\n", px, py);
      }
   }
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
@interface Doc {
   String value();
}

/**
 * A function defined by a polygon.
 */
class Function
{
   private final double[][] xyValues;

   public Function(final double[][] xyValues)
   {

      this.xyValues = xyValues;
   }

   /**
    * Returns {@code f(x)}.
    */
   public double getValue(final double x)
   {

      double[] point = xyValues[0];
      if (x <= point[0])
      {
         return point[1];
      }
      final int N = xyValues.length;
      point = xyValues[N - 1];
      if (x >= point[0])
      {
         return point[1];
      }
      for (int k = 1; k < N; k++)
      {
         point = xyValues[k];
         if (x <= point[0])
         {
            final double[] prev = xyValues[k - 1];
            final double dx = point[0] - prev[0];
            final double dy = point[1] - prev[1];
            return prev[1] + dy * (x - prev[0]) / dx;
         }
      }
      throw new IllegalStateException("unreached");
   }
}

/**
 * The drag coefficient as a function of the mach number.
 *
 * Values generated semi-automatically from the image at
 * {@code https://de.wikipedia.org/wiki/Str%C3%B6mungswiderstandskoeffizient}.
 */
class DragCoefficient extends Function
{

   public DragCoefficient()
   {
      super(new double[][] { //
            { 0.00000, 0.46595 }, { 0.05928, 0.46965 }, { 0.11855, 0.47519 }, { 0.17783, 0.47889 },
            { 0.23710, 0.48259 }, { 0.29638, 0.48629 }, { 0.35565, 0.49183 }, { 0.41493, 0.49738 },
            { 0.47420, 0.50108 }, { 0.53348, 0.51032 }, { 0.59276, 0.52142 }, { 0.65203, 0.54176 },
            { 0.71131, 0.57319 }, { 0.77058, 0.61941 }, { 0.82986, 0.68043 }, { 0.88913, 0.74700 },
            { 0.94841, 0.80986 }, { 1.00768, 0.86533 }, { 1.06696, 0.90971 }, { 1.12623, 0.94299 },
            { 1.18551, 0.96518 }, { 1.24479, 0.97997 }, { 1.30406, 0.98737 }, { 1.36334, 0.99476 },
            { 1.42261, 0.99846 }, { 1.48189, 1.00031 }, { 1.54116, 1.00216 }, { 1.60044, 1.00216 },
            { 1.65971, 1.00216 }, { 1.71899, 1.00031 }, { 1.77827, 1.00031 }, { 1.83754, 0.99846 },
            { 1.89682, 0.99661 }, { 1.95609, 0.99476 }, { 2.01537, 0.99291 }, { 2.07464, 0.99106 },
            { 2.13392, 0.98921 }, { 2.19319, 0.98552 }, { 2.25247, 0.98367 }, { 2.31175, 0.98182 },
            { 2.37102, 0.97812 }, { 2.43030, 0.97627 }, { 2.48957, 0.97257 }, { 2.54885, 0.97072 },
            { 2.60812, 0.96703 }, { 2.66740, 0.96518 }, { 2.72667, 0.96148 }, { 2.78595, 0.95963 },
            { 2.84523, 0.95778 }, { 2.90450, 0.95593 }, { 2.96378, 0.95408 }, { 3.02305, 0.95223 },
            { 3.08233, 0.95039 }, { 3.14160, 0.94854 }, { 3.20088, 0.94669 }, { 3.26015, 0.94484 },
            { 3.31943, 0.94299 }, { 3.37870, 0.94114 }, { 3.43798, 0.93929 }, { 3.49726, 0.93744 },
            { 3.55653, 0.93559 }, { 3.61581, 0.93559 }, { 3.67508, 0.93374 }, { 3.73436, 0.93190 },
            { 3.79363, 0.93005 }, { 3.85291, 0.93005 }, { 3.91218, 0.92820 }, { 3.97146, 0.92635 },
            { 4.03074, 0.92635 }, { 4.09001, 0.92450 }, { 4.14929, 0.92265 }, { 4.20856, 0.92265 },
            { 4.26784, 0.92080 }, { 4.32711, 0.92080 }, { 4.38639, 0.91895 }, { 4.44566, 0.91895 },
            { 4.50494, 0.91710 }, { 4.56422, 0.91710 }, { 4.62349, 0.91525 }, { 4.68277, 0.91525 },
            { 4.74204, 0.91341 }, { 4.80132, 0.91341 }, { 4.86059, 0.91341 }, { 4.91987, 0.91156 },
            { 4.97914, 0.91156 }, { 5.03842, 0.91156 }, { 5.09769, 0.90971 }, { 5.15697, 0.90971 },
            { 5.21625, 0.90971 }, { 5.27552, 0.90971 }, { 5.33480, 0.90786 }, { 5.39407, 0.90786 },
            { 5.45335, 0.90786 }, { 5.51262, 0.90786 }, { 5.57190, 0.90786 }, { 5.63117, 0.90786 },
            { 5.69045, 0.90786 }, { 5.74973, 0.90786 }, { 5.80900, 0.90786 }, { 5.86828, 0.90786 },
            { 5.92755, 0.90786 }, { 5.98683, 0.90601 }, });
   }
}

/**
 * Plotter to show an image in the systems image viewer.
 *
 * @author Struthio
 * @since October 2018
 */
class Plotter
{

   private final int width;

   private final int height;

   private final Config config;

   private final double[][] signals;

   private final double samplesPerDiv;

   public Plotter(final Config config, final List<List<Double>> signals)
   {

      this.config = config;
      this.signals = new double[signals.size()][];
      int maxLength = 0;
      for (int n = 0; n < signals.size(); n++)
      {
         final List<Double> signal = signals.get(n);
         final int N = signal.size();
         if (maxLength < N)
         {
            maxLength = N;
         }
         this.signals[n] = new double[N];
         for (int k = 0; k < N; k++)
         {
            this.signals[n][k] = signal.get(k);
         }
         normalize(this.signals[n]);
      }
      this.width = (2 * config.noOfMarginDivsX + config.noOfDivsX) * config.divWidth;
      this.height = (2 * config.noOfMarginDivsY + config.noOfDivsY) * config.divHeight;
      this.samplesPerDiv = maxLength / (double) config.noOfDivsX;

   }

   public void openRasterImageInEditor()
   {

      try
      {
         final File file = File.createTempFile(Plotter.class.getName(), ".png");
         createRasterImageFile(file);
         Desktop.getDesktop().edit(file);
      }
      catch (final IOException e)
      {
         throw new IllegalStateException("failed to create temporary image file", e);
      }
      catch (final HeadlessException e)
      {
         throw new IllegalStateException("platform not supported", e);
      }
      catch (final UnsupportedOperationException e)
      {
         throw new IllegalStateException("platform not supported", e);
      }
   }

   private void createRasterImageFile(final File file) throws IOException
   {

      final RenderedImage image = createRasterImage();
      ImageIO.write(image, "PNG", file);
   }

   private BufferedImage createRasterImage()
   {

      final BufferedImage image = new BufferedImage(width, height, TYPE_4BYTE_ABGR);
      final Graphics2D graphics2D = image.createGraphics();
      try
      {
         paint(graphics2D);
      }
      finally
      {
         graphics2D.dispose();
      }
      return image;
   }

   private void paint(final Graphics2D graphics2D)
   {

      graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING,
                                  RenderingHints.VALUE_RENDER_QUALITY);
      graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                  RenderingHints.VALUE_ANTIALIAS_ON);
      paintBackground(graphics2D);
      paintGrid(graphics2D);
      paintCurves(graphics2D);
   }

   private void paintBackground(final Graphics2D graphics2D)
   {

      graphics2D.setColor(config.bgColor);
      graphics2D.fill(new Rectangle2D.Double(0d, 0d, width, height));
   }

   private void paintGrid(final Graphics2D graphics2D)
   {

      final String spd = String.valueOf((int) samplesPerDiv);
      final String abscissaeText = String.format("%staps/div, %dtaps", spd, signals[0].length);
      final String ordinatesText = String.format("%s/div", String.valueOf(2.0 / config.noOfDivsY));
      final GridPlotter plotter = new GridPlotter(config, abscissaeText, ordinatesText);
      plotter.plot(graphics2D);
   }

   private void paintCurves(final Graphics2D graphics2D)
   {

      final float penWidth = config.signalPenWidth * config.divWidth / 32f;
      graphics2D.setStroke(new BasicStroke(penWidth, BasicStroke.CAP_ROUND, BasicStroke.CAP_ROUND));
      final double x0 = config.noOfMarginDivsX * config.divWidth;
      final double y0 = (config.noOfMarginDivsY + 0.5f * config.noOfDivsY) * config.divHeight;
      final double scale = 0.5 * (config.noOfDivsY * config.divHeight);
      for (int kSignal = 0; kSignal < signals.length; kSignal++)
      {
         plotCurve(graphics2D, kSignal, x0, y0, scale);
      }
   }

   private void plotCurve(final Graphics2D graphics2D, final int kSignal, final double x0,
         final double y0, final double scale)
   {

      final boolean samples = samplesPerDiv <= 10;
      final Shape originalClip = graphics2D.getClip();
      try
      {
         final Rectangle2D signalClip;
         {
            final double x = config.noOfMarginDivsX * config.divWidth - 0.25 * config.divWidth;
            final double y = config.noOfMarginDivsY * config.divHeight - 0.25 * config.divHeight;
            final double w = config.noOfDivsX * config.divWidth + 0.50 * config.divWidth;
            final double h = config.noOfDivsY * config.divHeight + 0.50 * config.divHeight;
            signalClip = new Rectangle2D.Double(x - 2, y - 2, w + 4, h + 4);
         }
         graphics2D.clip(signalClip);
         plotSamplesOrCurve(graphics2D, kSignal, samples, x0, y0, scale, samplesPerDiv, signalClip,
                            originalClip);
      }
      finally
      {
         graphics2D.setClip(originalClip);
      }
   }

   private void plotSamplesOrCurve(final Graphics2D graphics2D, final int kSignal,
         final boolean samples, final double x0, final double y0, final double scale,
         final double samplesPerDiv, final Shape signalClip, final Shape originalClip)
   {

      final double rx = 0.12 * config.divWidth;
      final double ry = 0.12 * config.divHeight;
      graphics2D.setColor(config.signalColors[kSignal % config.signalColors.length]);
      final double[] signal = signals[kSignal];
      double xPrev = 0;
      double yPrev = 0;
      for (int n = 0; n <= signal.length; n++)
      {
         final double value = signal[n % signal.length];
         final double x = x0 + n * config.divWidth / samplesPerDiv;
         final double y = y0 - scale * value;
         if (samples)
         {
            if (0 <= n && n < signal.length)
            {
               graphics2D.draw(new Line2D.Double(x, y0, x, y));
               if (signalClip.contains(x, y))
               {
                  graphics2D.setClip(originalClip);
                  graphics2D.draw(new Ellipse2D.Double(x - 0.5 * rx, y - 0.5 * ry, rx, ry));
                  graphics2D.fill(new Ellipse2D.Double(x - 0.5 * rx, y - 0.5 * ry, rx, ry));
                  graphics2D.clip(signalClip);
               }
            }
         }
         else
         {
            graphics2D.clip(new Rectangle2D.Double(0, 0, width, height));
            if (0 < n && n < signal.length)
            {
               graphics2D.draw(new Line2D.Double(xPrev, yPrev, x, y));
            }
         }
         xPrev = x;
         yPrev = y;
      }
   }

   private static void normalize(final double[] array)
   {

      final int N = array.length;
      if (N > 0)
      {
         double max = 0;
         for (final double value : array)
         {
            final double c = abs(value);
            if (max < c)
            {
               max = c;
            }
         }
         if (max > 0 && max != 1)
         {
            final double scale = 1d / max;
            for (int k = 0; k < N; k++)
            {
               array[k] *= scale;
            }
         }
      }
   }

   private static final class GridPlotter
   {

      private final Config config;

      private final String abscissaeText;

      private final String ordinatesText;

      public GridPlotter(final Config config, final String abscissaeText,
            final String ordinatesText)
      {

         this.config = config;
         this.abscissaeText = abscissaeText;
         this.ordinatesText = ordinatesText;
      }

      public void plot(final Graphics2D graphics2D)
      {

         graphics2D.setColor(config.gridColor);
         final double x0 = config.noOfMarginDivsX * config.divWidth;
         final double x1 = (config.noOfMarginDivsX + config.noOfDivsX) * config.divWidth;
         final double y0 = config.noOfMarginDivsY * config.divHeight;
         final double y1 = (config.noOfMarginDivsY + config.noOfDivsY) * config.divHeight;
         plot(graphics2D, x0, y0, x1, y1, abscissaeText, ordinatesText);
      }

      private void plot(final Graphics2D graphics2D, final double x0, final double y0,
            final double x1, final double y1, final String abscissaeText,
            final String ordinatesText)
      {

         final Composite composite = graphics2D.getComposite();
         try
         {
            final float penWidth = config.framePenWidth * config.divWidth / 32f;
            graphics2D.setStroke(new BasicStroke(penWidth, CAP_ROUND, JOIN_ROUND));
            final double xm = (x0 + x1) / 2;
            final double ym = (y0 + y1) / 2;
            graphics2D.draw(new Line2D.Double(x0, y0, x1, y0));
            graphics2D.draw(new Line2D.Double(x0, y1, x1, y1));
            graphics2D.draw(new Line2D.Double(x0, y0, x0, y1));
            graphics2D.draw(new Line2D.Double(x1, y0, x1, y1));
            graphics2D.draw(new Line2D.Double(x0, ym, x1, ym));
            graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                                                               config.gridOpacity));
            for (double x = x0; x <= x1; x += config.divWidth)
            {
               graphics2D.draw(new Line2D.Double(x, y0, x, y1));
            }
            for (double y = y0; y <= y1; y += config.divHeight)
            {
               graphics2D.draw(new Line2D.Double(x0, y, x1, y));
            }
            final Font font = config.font.deriveFont(0.40f * config.divHeight);
            final FontRenderContext frc = graphics2D.getFontRenderContext();
            graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                                                               config.textOpacity));
            if (config.topLeft != null && !config.topLeft.isEmpty())
            {
               final String text = config.topLeft;
               final double x = x0;
               graphics2D.setFont(font);
               final TextLayout layout = new TextLayout(text, font, frc);
               final Rectangle2D bounds = layout.getBounds();
               final double h = bounds.getHeight();
               final double dy = 0.5 * (config.divHeight - h)
                     + (config.noOfDivsY + 1) * config.divHeight;
               final double dx = 0;
               graphics2D.drawString(text, (float) (x - dx), (float) (y1 + config.divHeight - dy));
            }
            if (config.topCenter != null && !config.topCenter.isEmpty())
            {
               final String text = config.topCenter;
               final double x = xm;
               graphics2D.setFont(font);
               final TextLayout layout = new TextLayout(text, font, frc);
               final Rectangle2D bounds = layout.getBounds();
               final double h = bounds.getHeight();
               final double dy = 0.5 * (config.divHeight - h)
                     + (config.noOfDivsY + 1) * config.divHeight;
               final double dx = 0.5 * bounds.getWidth();
               graphics2D.drawString(text, (float) (x - dx), (float) (y1 + config.divHeight - dy));
            }
            if (config.topRight != null && !config.topRight.isEmpty())
            {
               final String text = config.topRight;
               final double x = x1;
               graphics2D.setFont(font);
               final TextLayout layout = new TextLayout(text, font, frc);
               final Rectangle2D bounds = layout.getBounds();
               final double h = bounds.getHeight();
               final double dy = 0.5 * (config.divHeight - h)
                     + (config.noOfDivsY + 1) * config.divHeight;
               final double dx = bounds.getWidth();
               graphics2D.drawString(text, (float) (x - dx), (float) (y1 + config.divHeight - dy));
            }
            if (config.bottomRight != null && !config.bottomRight.isEmpty())
            {
               final String text = config.bottomRight;
               final double x = x1;
               graphics2D.setFont(font);
               final TextLayout layout = new TextLayout(text, font, frc);
               final Rectangle2D bounds = layout.getBounds();
               final double h = bounds.getHeight();
               final double dy = 0.5 * (config.divHeight - h);
               final double dx = bounds.getWidth();
               graphics2D.drawString(text, (float) (x - dx), (float) (y1 + config.divHeight - dy));
            }
            if (abscissaeText != null && !abscissaeText.isEmpty())
            {
               final String text = abscissaeText;
               final double x = x0;
               graphics2D.setFont(font);
               final TextLayout layout = new TextLayout(text, font, frc);
               final Rectangle2D bounds = layout.getBounds();
               final double h = bounds.getHeight();
               final double dy = 0.5 * (config.divHeight - h);
               final double dx = x == xm ? 0.5 * bounds.getWidth() : 0;
               graphics2D.drawString(text, (float) (x - dx), (float) (y1 + config.divHeight - dy));
            }
            if (ordinatesText != null && !ordinatesText.isEmpty())
            {
               final String text = ordinatesText;
               graphics2D.setFont(font.deriveFont(AffineTransform.getQuadrantRotateInstance(-1)));
               final TextLayout layout = new TextLayout(text, font, frc);
               final Rectangle2D bounds = layout.getBounds();
               final double h = bounds.getHeight();
               final double d = 0.5 * (config.divHeight - h);
               graphics2D.drawString(text, (float) (x0 - d), (float) y1);
            }
         }
         finally
         {
            graphics2D.setComposite(composite);
         }
      }
   }

   public static class Config
   {
      public final int divWidth = 48;

      public final int divHeight = 48;

      public final int noOfDivsX = 14;

      public final int noOfDivsY = 8;

      public final int noOfMarginDivsX = 1;

      public final int noOfMarginDivsY = 1;

      public final Color bgColor = new Color(0xEF, 0xFF, 0xEF);

      public final Color gridColor = Color.LIGHT_GRAY;

      public final Color[] signalColors = new Color[] { //
            //
            new Color(0xE0, 0x00, 0x00), //
            new Color(0xE0, 0x00, 0x40), //
            new Color(0xE0, 0x00, 0x80), //
            new Color(0x00, 0x70, 0xE0), //
            new Color(0x70, 0x00, 0xE0), //
            new Color(0x70, 0xE0, 0x70), //
      };

      public final Font font = new Font("Comic Sans MS", Font.PLAIN, 1);

      public final float framePenWidth = 1.0f;

      public final float gridPenWidth = 0.3f;

      public final float signalPenWidth = 0.8f;

      public final float gridOpacity = 1.f;

      public final float textOpacity = 1.f;

      public final String topLeft;

      public final String topCenter;

      public final String topRight;

      public final String bottomRight;

      public Config(final String topLeft, final String topCenter, final String topRight,
            final String bottomRight)
      {

         this.topLeft = topLeft;
         this.topCenter = topCenter;
         this.topRight = topRight;
         this.bottomRight = bottomRight;
      }
   }
}
Title: Re: Reentry possible?
Post by: Struthio on October 10, 2018, 09:35:21 PM
The simulation shows, that the capsule falls rather like a stone. No known heat shield can survive a temperature of 7438K. Also, beside heat problems, the capsule reaches earth after less than 5mins and not as reported after 20mins. The tangetial distance is 1182km and not as reported 4000km.

The formula for air friction and the velocity-dependent coefficient may not be accurate for great heights and high hypersonic speeds. On the other hand, using 10.0 times or 0.1 times air resistance does indeed increase/reduce the time needed to reach sea level, but then, the kinematic energy given at 130km height has to be dissipated anyway. Experimenting with functions and parameters shows that the maximum temperature can't be reduced significantly. More friction imlies slower speed but temperature stays high because of high friction. Less friction imlies higher speed while temperature stays high because of higher friction caused by higher speed.

Theoretically, the best way to reduce maximum temperature would be to make braking power constant. The product of speed and acceleration had to be constant. But given physical laws, that is not allowed/realistic. Thus, there has to be an acceleration peak at some rather high velocity, where temperature is very high. We know that meteorites break up when passing the atmosphere.

Title: Re: Reentry possible?
Post by: Struthio on October 11, 2018, 02:35:03 PM
A Reentry Breakup Recorder (https://en.wikipedia.org/wiki/Reentry_Breakup_Recorder) is used to record data while an unmanned spacecraft breaks up when returning from a Low Earth Orbit re-entering the atmosphere.

A Comparison of Reentry Breakup Measurements for Three Atmospheric Reentries (http://www.iaassconference2013.space-safety.org/wp-content/uploads/sites/32/2013/06/1600_Feistel.pdf) (PDF) has been presented in A.D. 2013.

The three vehicles are cylindrical, about 10m long and 4.5m diameter, weight more than 10 metric tons.

On page 11 the authors show altitude in km over time in seconds, as well as acceleration in g (=9.81m/s^2).

(https://www.cathinfo.com/index.php?action=dlattach;topic=50195.0;attach=12155;image)

All three altitude-curves for the three vehicles start with a nearly linear section from 120km down to 70km. Accordingly the vehicles have a constant vertical velocity and zero vertical acceleration. The diagram shows that for the first 100 seconds the acceleration vector is zero.

But that is impossible. Air friction deceleration cannot on the one hand cancel gravity in the vertical direction and at the same time be zero in the horizontal direction. The air friction deceleration vector points against the flight path direction. The flight path angle stays constant at -1.663° (for ATV-3/REBR4), see page 10. The graph obviously has little to do with reality.

Also, mass density ρ of air is proportional to e-h/8400m. We have e-70000m/8400m / e-120000m/8400m =  e50/8.4 = 384. Mass density ρ of air at 70km is 384 times higher than at 120km. Gravity on the other hand increases by 2% from 120km down to 70km. How can a 384 times thicker air cause virtually the same amount of friction, while velocity doesn't change? That's ridiculous!

Something is rotten in space flight.


P.S.: A more detailed version of the above linked docuмent can be found here (http://articles.adsabs.harvard.edu/cgi-bin/nph-iarticle_query?2013ESASP.715E..75F&amp;data_type=PDF_HIGH&amp;whole_paper=YES&amp;type=PRINTER&amp;filetype=.pdf).
Title: Re: Reentry possible?
Post by: Neil Obstat on October 12, 2018, 02:45:32 AM
.
Where you have: "We know that meteorites break up when passing the atmosphere." 
.
Don't you mean meteors (not meteorites)? 
Meteors are asteroids or other materials when they are passing through the earth's atmosphere.
Meteorites are the solid physical remnants of meteors that are found on the ground after they survived the burning fall.
Meteors become meteorites after they land on the earth.
.
Therefore, it would be correct to say, "We know that meteors break up when passing [through] the atmosphere."
Title: Re: Reentry possible?
Post by: Neil Obstat on October 12, 2018, 10:23:07 AM
I made a simulation of Yuri [Gagarin's re-entry]. Below [are] the results as well as the source code of the software.

Gagarin is said to have [re-entered] the atmosphere in a [spherical] capsule of 2,400kg and 2.3m diameter. Re-entry starts at 130km height at a tangential velocity of 8,000m/s (28,800km/h). The plot shows:

(https://www.cathinfo.com/the-earth-god-made-flat-earth-geocentrism/reentry-possible/?action=dlattach;attach=12149;image)

  • • time from 130km height down to sea level: 04'43" (history reports 20mins)
  • • upper red curve: height over sea level
  • • lower red curve: vertical speed (derivative of height)
  • • red curve with peak up: vertical acceleration (2nd derivative of height)
  • • green curve: Boltzmann-temperature (max 7438K) corresponding braking power (max  2885MW)
  • • blue curve: speed dependent drag coefficient for newtonian air friction (0.47 at sea level)
  • • purple curve: mass density of the atmosphere
  • • horizontal speed not in plot, goes from 8000m/s to 0. Distance: 1182km (history reports 4000km).

More comments to follow.
.
.
The graph has two red plots, with slightly different hues, but not enough to distinguish them from red.
.
What you refer to as "4. red curve with peak up" is a purple curve (mostly red + some blue).
.
Mass density of the atmosphere is a violet curve (mostly blue + some red); you have "7. purple..." which is incorrect.
Both violet and purple are a blend of blue and red, but violet has more blue in it, and purple has more red.
.
(https://s17-us2.startpage.com/cgi-bin/serveimage?url=http%3A%2F%2Ft0.gstatic.com%2Fimages%3Fq%3Dtbn%3AANd9GcQuxTk3ppDBxTmqL5ESYEfcGvmSucX8YDl3q_oW0dxsHoK7HZm7Gw&sp=14887f52dfc79f50a6bd32f47083a045&anticache=196813)
.
From top to bottom on the left side, the beginning of the graph, the colors are:
Red
Blue
Green
Violet
Red
Purple
.
Title: Re: Reentry possible?
Post by: Neil Obstat on October 12, 2018, 01:26:45 PM
.
The website .pdf you're referencing has a number of oddities that seem to contradict itself:
http://istwww.iaassconference2013.space-safety.org/wp-content/uploads/sites/32/2013/06/1600_Feel.pdf
.
I wonder if they don't have deliberate disinformation for security purposes or whatever.
You'd think the purpose of the site, to promote public safety regarding falling space debris, would mean the information is reliable.
Title: Re: Reentry possible?
Post by: Struthio on October 13, 2018, 08:46:54 PM
The source code I posted above had an error. Therefore below a corrected version.

The corrected results still yield a travel time less than half of the reported one and a temperature of more than 5000K.

Code: [Select]
import static java.awt.BasicStroke.CAP_ROUND;
import static java.awt.BasicStroke.JOIN_ROUND;
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
import static java.lang.Math.PI;
import static java.lang.Math.abs;
import static java.lang.Math.atan2;
import static java.lang.Math.cos;
import static java.lang.Math.exp;
import static java.lang.Math.sin;
import static java.lang.Math.sqrt;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Desktop;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.HeadlessException;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.imageio.ImageIO;

/**
 * Simulation of the re-entry of Yuri Gagarin.
 *
 * @see https://en.wikipedia.org/wiki/Vostok_1
 * @see https://de.wikipedia.org/wiki/Fall_mit_Luftwiderstand#Fall_mit_Luftwiderstand:_Newton-Reibung
 * @see https://de.wikipedia.org/wiki/Methode_der_kleinen_Schritte
 * @see https://de.wikipedia.org/wiki/Barometrische_Höhenformel
 * @see https://de.wikipedia.org/wiki/Stefan-Boltzmann-Gesetz
 * @see http://www.astronautix.com/v/vostok1.html
 * @see http://www.spacefacts.de/mission/english/vostok-1.htm
 * @see http://heiwaco.tripod.com/moontravelw1.htm#REE
 *
 * @see http://www.iaassconference2013.space-safety.org/wp-content/uploads/sites/32/2013/06/1600_Feistel.pdf
 * @see http://articles.adsabs.harvard.edu/cgi-bin/nph-iarticle_query?2013ESASP.715E..75F&amp;data_type=PDF_HIGH&amp;whole_paper=YES&amp;type=PRINTER&amp;filetype=.pdf
 *
 * @author Struthio
 * @since October 2018
 *
 */
public class GagarinsReentry
{
   /** Whether to use ATV-3 and not Gagarin. */
   private static boolean ATV3 = false;

   /** Title of output. */
   private static final String title = "Re-entry " + (ATV3 ? "ATV-3" : "Yuri Gagarin");

   @Doc("Drag coefficient of the shape of the capsule.")
   private static final double cwShape = ATV3 ? 1.0 : 0.47;

   @Doc("Length of cylidrical ATV-3 capsule in m.")
   private static final double l = 10.27;

   @Doc("Diameter of the spherical or cylindrical capsule in m.")
   private static final double d = ATV3 ? 4.48 : 2.3;

   @Doc("Weight of the capsule in kg.")
   private static final double m = ATV3 ? 10470 : 2400;

   @Doc("Sectional area of the capsule in m^2.")
   private static final double Asectional = PI * sqr(0.5 * d);

   @Doc("Surface area of the capsule in m^2.")
   private static final double Asurface = ATV3 ? 2 * Asectional + PI * d * l : 4 * Asectional;

   @Doc("Gravitational acceleration at sea level in m/s^2.")
   private static final double g = 9.81;

   @Doc("Radius of the earth in m.")
   private static final double r = 6370000;

   @Doc("Mass density of air at sea level in kg/m^3.")
   private static final double rho0 = 1.293;

   @Doc("Speed of sound in m/s.")
   private static final double cAir = 331.5;

   @Doc("Calculation time interval in s.")
   private static final double dt = 0.01;

   @Doc("Current time in s.")
   private double t = 0;

   @Doc("Horizontal distance m.")
   private double x = 0;

   @Doc("Height above sea level in m.")
   private double y = ATV3 ? 120000d : 130000d;

   @Doc("Initial flight path angle in rad.")
   private static final double argV = (ATV3 ? -1.663 : -2.0) * PI / 180d;

   @Doc("Initial velocity.")
   private static final double absV = ATV3 ? 7593.0 : 8000;

   @Doc("Horizontal velocity in m/s.")
   private double vx = absV * cos(argV);

   @Doc("Vertical velocity in m/s.")
   private double vy = absV * sin(argV);

   @Doc("Horizontal acceleration in m/s.")
   private double ax = 0;

   @Doc("Vertical acceleration in m/s.")
   private double ay = 0;

   @Doc("Mass density of air at current height above sea level in kg/m^3.")
   private double rho = 0;

   @Doc("Drag coefficient.")
   private double cw = 0;

   @Doc("Braking force in N")
   private double F = 0;

   @Doc("Braking power in W")
   private double P = 0;

   @Doc("Maximum braking force in N")
   private double Pmax = 0;

   @Doc("Maximum acceleration in m/s^2")
   private double aMax = 0;

   private final DragCoefficient dragCoefficient = new DragCoefficient();

   private final List<List<Double>> signals = new ArrayList<>();
   {
      signals.add(new ArrayList<>());
      signals.add(new ArrayList<>());
      signals.add(new ArrayList<>());
      signals.add(new ArrayList<>());
      signals.add(new ArrayList<>());
      signals.add(new ArrayList<>());
      signals.add(new ArrayList<>());
   }

   /**
    * Program entry point.
    * <p>
    * prints text to stdout and opens a *.png-image in the systems image viewer.
    *
    * @param args
    *           arguments are ignored.
    */
   public static void main(final String... args)
   {

      try
      {
         final GagarinsReentry reentry = new GagarinsReentry();
         reentry.run();
         final Plotter.Config config = new Plotter.Config(title, "", "y, Cw, T, \u03C1, y', y\"",
               reentry.time());
         new Plotter(config, reentry.signals).openRasterImageInEditor();
      }
      catch (final Throwable t)
      {
         t.printStackTrace();
      }
   }

   public GagarinsReentry()
   {

   }

   private void run()
   {

      final double Ekin = 0.5 * m * (sqr(vx) + sqr(vy));
      step(true);
      out("%s\n", title);
      out("\n");
      printDoc();
      out("\n");
      out(" t[s]    ax      ay     rho        cw         F           vx           vy         x        h        P    \n");
      out("------ ------- ------- -------- -------- ----------- ------------ ------------ -------- -------- --------\n");
      print();
      int noOfSteps;
      for (noOfSteps = 0; y > 0; noOfSteps++)
      {
         step(false);
         if (noOfSteps % 100 == 0)
         {
            print();
         }
      }
      if (noOfSteps % 10 != 0)
      {
         print();
      }
      out("noOfSteps: %d\n", noOfSteps);
      out("%s  %.1fg  %.2fMW  %.0fK\n", time(), aMax / g, 1E-6 * Pmax, temperatureInK(Pmax));
      out("\n");
      final double P = Ekin / t;
      out("mean:          %.2fMW  %.0fK\n", 1E-6 * P, temperatureInK(P));
      out("total energy:  %.2fGJ\n", 1E-9 * Ekin);
   }

   private void printDoc()
   {

      for (final Field field : GagarinsReentry.class.getDeclaredFields())
      {
         final Doc doc = field.getAnnotation(Doc.class);
         if (doc != null)
         {
            final boolean accessible = field.isAccessible();
            try
            {
               field.setAccessible(true);
               final double value = (Double) field.get(this);
               String sValue;
               if (value == 0)
               {
                  sValue = String.format(Locale.US, "%12s", "0");
               }
               else if (abs(value) < 0.001 || abs(value) > 1E8)
               {
                  sValue = String.format(Locale.US, "%12.3E", value);
               }
               else
               {
                  sValue = String.format(Locale.US, "%12.3f", value);
               }
               out("%12s = %s %s\n", field.getName(), sValue, doc.value());
            }
            catch (final Exception e)
            {
               throw new IllegalStateException("unreached", e);
            }
            finally
            {
               field.setAccessible(accessible);
            }
         }
      }
   }

   private void print()
   {

      out("%s %7.2f %7.2f %8.2E %8.2f %10.2fN %8.2fkm/h %8.2fkm/h %7.0fm %7.0fm %6.1fMW\n", time(),
          ax, ay, rho, cw, F, 3.6 * vx, 3.6 * vy, x, y, 1E-6 * P);
   }

   private String time()
   {
      final int s = (int) (t + 0.5);
      return String.format("%02d'%02d\"", s / 60, s % 60);
   }

   private void step(final boolean initialize)
   {

      rho = rho0 * exp(-y / 8400);
      final double absV = sqrt(sqr(vx) + sqr(vy));
      final double argV = atan2(vy, vx);
      F = airFrictionForceInN(rho, y, absV);
      final double aF = F / m; // air friction acceleration
      final double aG = -g * (r / (r + y)); // gravitational acceleration
      final double aC = sqr(vx) / (r + y); // centrifugal acceleration
      ax = aF * cos(argV);
      ay = aF * sin(argV) + aG + aC;
      if (!initialize)
      {
         t += dt;
         vx += ax * dt;
         vy += ay * dt;
         x += vx * dt;
         y += vy * dt;
      }
      final double a = sqrt(ax * ax + ay * ay);
      if (aMax < a)
      {
         aMax = a;
      }
      P = m * absV * a;
      if (Pmax < P)
      {
         Pmax = P;
      }
      signals.get(0).add(y);
      // signals.get(1).add(vy);
      // signals.get(2).add(ay);
      signals.get(1).add(sqrt(sqr(vx) + sqr(vy)));
      signals.get(2).add(sqrt(sqr(ax) + sqr(ay)));
      signals.get(3).add(cw);
      signals.get(4).add(rho);
      signals.get(5).add(temperatureInK(P));
      // signals.get(6).add(x);
   }

   /**
    * Returns the temperature in Kelvin of the black sphere emitting the given power.
    */
   private static double temperatureInK(final double powerInWatts)
   {

      // https://de.wikipedia.org/wiki/Stefan-Boltzmann-Gesetz
      final double sigma = 5.670367E-8;
      return sqrt(sqrt(powerInWatts / (sigma * Asurface)));
   }

   /**
    * Returns the air friction force is Newtons.
    *
    * @param rho
    *           The mass desity of the air in kg/m^3.
    * @param h
    *           The height above sea level.
    * @param v
    *           The speed in m/s.
    * @return the air friction force is Newtons.
    * @throws IllegalArgumentException
    *            If the height above sea level exceeds 150km.
    * @see https://de.wikipedia.org/wiki/Str%C3%B6mungswiderstandskoeffizient
    */
   private double airFrictionForceInN(final double rho, final double h, final double v)
         throws IllegalArgumentException
   {

      if (h > 150000)
      {
         throw new IllegalArgumentException("formula valid up to 150km height only");
      }
      cw = cwShape / 0.47 * dragCoefficient.getValue(abs(v / cAir));
      return -0.5 * rho * cw * Asectional * sqr(v);
   }

   private static double sqr(final double x)
   {
      return x * x;
   }

   private static void out(final String format, final Object... args)
   {

      System.out.format(Locale.US, format, args);
   }
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
@interface Doc {
   String value();
}

/**
 * A function defined by a polygon.
 */
class Function
{
   private final double[][] xyValues;

   public Function(final double[][] xyValues)
   {

      this.xyValues = xyValues;
   }

   /**
    * Returns {@code f(x)}.
    */
   public double getValue(final double x)
   {

      double[] point = xyValues[0];
      if (x <= point[0])
      {
         return point[1];
      }
      final int N = xyValues.length;
      point = xyValues[N - 1];
      if (x >= point[0])
      {
         return point[1];
      }
      for (int k = 1; k < N; k++)
      {
         point = xyValues[k];
         if (x <= point[0])
         {
            final double[] prev = xyValues[k - 1];
            final double dx = point[0] - prev[0];
            final double dy = point[1] - prev[1];
            return prev[1] + dy * (x - prev[0]) / dx;
         }
      }
      throw new IllegalStateException("unreached");
   }
}

/**
 * The drag coefficient as a function of the mach number.
 *
 * Values generated semi-automatically from the image at
 * {@code https://de.wikipedia.org/wiki/Str%C3%B6mungswiderstandskoeffizient}.
 */
class DragCoefficient extends Function
{

   public DragCoefficient()
   {
      super(new double[][] { //
            { 0.00000, 0.46595 }, { 0.05928, 0.46965 }, { 0.11855, 0.47519 }, { 0.17783, 0.47889 },
            { 0.23710, 0.48259 }, { 0.29638, 0.48629 }, { 0.35565, 0.49183 }, { 0.41493, 0.49738 },
            { 0.47420, 0.50108 }, { 0.53348, 0.51032 }, { 0.59276, 0.52142 }, { 0.65203, 0.54176 },
            { 0.71131, 0.57319 }, { 0.77058, 0.61941 }, { 0.82986, 0.68043 }, { 0.88913, 0.74700 },
            { 0.94841, 0.80986 }, { 1.00768, 0.86533 }, { 1.06696, 0.90971 }, { 1.12623, 0.94299 },
            { 1.18551, 0.96518 }, { 1.24479, 0.97997 }, { 1.30406, 0.98737 }, { 1.36334, 0.99476 },
            { 1.42261, 0.99846 }, { 1.48189, 1.00031 }, { 1.54116, 1.00216 }, { 1.60044, 1.00216 },
            { 1.65971, 1.00216 }, { 1.71899, 1.00031 }, { 1.77827, 1.00031 }, { 1.83754, 0.99846 },
            { 1.89682, 0.99661 }, { 1.95609, 0.99476 }, { 2.01537, 0.99291 }, { 2.07464, 0.99106 },
            { 2.13392, 0.98921 }, { 2.19319, 0.98552 }, { 2.25247, 0.98367 }, { 2.31175, 0.98182 },
            { 2.37102, 0.97812 }, { 2.43030, 0.97627 }, { 2.48957, 0.97257 }, { 2.54885, 0.97072 },
            { 2.60812, 0.96703 }, { 2.66740, 0.96518 }, { 2.72667, 0.96148 }, { 2.78595, 0.95963 },
            { 2.84523, 0.95778 }, { 2.90450, 0.95593 }, { 2.96378, 0.95408 }, { 3.02305, 0.95223 },
            { 3.08233, 0.95039 }, { 3.14160, 0.94854 }, { 3.20088, 0.94669 }, { 3.26015, 0.94484 },
            { 3.31943, 0.94299 }, { 3.37870, 0.94114 }, { 3.43798, 0.93929 }, { 3.49726, 0.93744 },
            { 3.55653, 0.93559 }, { 3.61581, 0.93559 }, { 3.67508, 0.93374 }, { 3.73436, 0.93190 },
            { 3.79363, 0.93005 }, { 3.85291, 0.93005 }, { 3.91218, 0.92820 }, { 3.97146, 0.92635 },
            { 4.03074, 0.92635 }, { 4.09001, 0.92450 }, { 4.14929, 0.92265 }, { 4.20856, 0.92265 },
            { 4.26784, 0.92080 }, { 4.32711, 0.92080 }, { 4.38639, 0.91895 }, { 4.44566, 0.91895 },
            { 4.50494, 0.91710 }, { 4.56422, 0.91710 }, { 4.62349, 0.91525 }, { 4.68277, 0.91525 },
            { 4.74204, 0.91341 }, { 4.80132, 0.91341 }, { 4.86059, 0.91341 }, { 4.91987, 0.91156 },
            { 4.97914, 0.91156 }, { 5.03842, 0.91156 }, { 5.09769, 0.90971 }, { 5.15697, 0.90971 },
            { 5.21625, 0.90971 }, { 5.27552, 0.90971 }, { 5.33480, 0.90786 }, { 5.39407, 0.90786 },
            { 5.45335, 0.90786 }, { 5.51262, 0.90786 }, { 5.57190, 0.90786 }, { 5.63117, 0.90786 },
            { 5.69045, 0.90786 }, { 5.74973, 0.90786 }, { 5.80900, 0.90786 }, { 5.86828, 0.90786 },
            { 5.92755, 0.90786 }, { 5.98683, 0.90601 }, });
   }
}

/**
 * Plotter to show an image in the systems image viewer.
 *
 * @author Struthio
 * @since October 2018
 */
class Plotter
{

   private final int width;

   private final int height;

   private final Config config;

   private final double[][] signals;

   private final double[] xValues;

   private final double samplesPerDiv;

   public Plotter(final Config config, final List<List<Double>> signals)
   {

      this.config = config;
      this.signals = new double[signals.size()][];
      this.xValues = null;
      int maxLength = 0;
      for (int n = 0; n < signals.size(); n++)
      {
         final List<Double> signal = signals.get(n);
         final int N = signal.size();
         if (maxLength < N)
         {
            maxLength = N;
         }
         this.signals[n] = new double[N];
         for (int k = 0; k < N; k++)
         {
            this.signals[n][k] = signal.get(k);
         }
         normalize(this.signals[n]);
      }
      this.width = (2 * config.noOfMarginDivsX + config.noOfDivsX) * config.divWidth;
      this.height = (2 * config.noOfMarginDivsY + config.noOfDivsY) * config.divHeight;
      this.samplesPerDiv = maxLength / (double) config.noOfDivsX;
   }

   public void openRasterImageInEditor()
   {

      try
      {
         final File file = File.createTempFile(Plotter.class.getName(), ".png");
         createRasterImageFile(file);
         Desktop.getDesktop().edit(file);
      }
      catch (final IOException e)
      {
         throw new IllegalStateException("failed to create temporary image file", e);
      }
      catch (final HeadlessException e)
      {
         throw new IllegalStateException("platform not supported", e);
      }
      catch (final UnsupportedOperationException e)
      {
         throw new IllegalStateException("platform not supported", e);
      }
   }

   private void createRasterImageFile(final File file) throws IOException
   {

      final RenderedImage image = createRasterImage();
      ImageIO.write(image, "PNG", file);
   }

   private BufferedImage createRasterImage()
   {

      final BufferedImage image = new BufferedImage(width, height, TYPE_4BYTE_ABGR);
      final Graphics2D graphics2D = image.createGraphics();
      try
      {
         paint(graphics2D);
      }
      finally
      {
         graphics2D.dispose();
      }
      return image;
   }

   private void paint(final Graphics2D graphics2D)
   {

      graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING,
                                  RenderingHints.VALUE_RENDER_QUALITY);
      graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                  RenderingHints.VALUE_ANTIALIAS_ON);
      paintBackground(graphics2D);
      paintGrid(graphics2D);
      paintCurves(graphics2D);
   }

   private void paintBackground(final Graphics2D graphics2D)
   {

      graphics2D.setColor(config.bgColor);
      graphics2D.fill(new Rectangle2D.Double(0d, 0d, width, height));
   }

   private void paintGrid(final Graphics2D graphics2D)
   {

      final String spd = String.valueOf((int) samplesPerDiv);
      final String abscissaeText = String.format("%staps/div, %dtaps", spd, signals[0].length);
      final String ordinatesText = String.format("%s/div", String.valueOf(2.0 / config.noOfDivsY));
      final GridPlotter plotter = new GridPlotter(config, abscissaeText, ordinatesText);
      plotter.plot(graphics2D);
   }

   private void paintCurves(final Graphics2D graphics2D)
   {

      final float penWidth = config.signalPenWidth * config.divWidth / 32f;
      graphics2D.setStroke(new BasicStroke(penWidth, BasicStroke.CAP_ROUND, BasicStroke.CAP_ROUND));
      final double x0 = config.noOfMarginDivsX * config.divWidth;
      final double y0 = (config.noOfMarginDivsY + 0.5f * config.noOfDivsY) * config.divHeight;
      for (int kSignal = 0; kSignal < signals.length; kSignal++)
      {
         plotCurve(graphics2D, kSignal, x0, y0);
      }
   }

   private void plotCurve(final Graphics2D graphics2D, final int kSignal, final double x0,
         final double y0)
   {

      final boolean samples = samplesPerDiv <= 10;
      final Shape originalClip = graphics2D.getClip();
      try
      {
         final Rectangle2D signalClip;
         {
            final double x = config.noOfMarginDivsX * config.divWidth - 0.25 * config.divWidth;
            final double y = config.noOfMarginDivsY * config.divHeight - 0.25 * config.divHeight;
            final double w = config.noOfDivsX * config.divWidth + 0.50 * config.divWidth;
            final double h = config.noOfDivsY * config.divHeight + 0.50 * config.divHeight;
            signalClip = new Rectangle2D.Double(x - 2, y - 2, w + 4, h + 4);
         }
         graphics2D.clip(signalClip);
         plotSamplesOrCurve(graphics2D, kSignal, samples, x0, y0, samplesPerDiv, signalClip,
                            originalClip);
      }
      finally
      {
         graphics2D.setClip(originalClip);
      }
   }

   private void plotSamplesOrCurve(final Graphics2D graphics2D, final int kSignal,
         final boolean samples, final double x0, final double y0, final double samplesPerDiv,
         final Shape signalClip, final Shape originalClip)
   {

      final double rx = 0.12 * config.divWidth;
      final double ry = 0.12 * config.divHeight;
      graphics2D.setColor(config.signalColors[kSignal % config.signalColors.length]);
      final double scaleX = 0.5 * (config.noOfDivsX * config.divHeight);
      final double scaleY = 0.5 * (config.noOfDivsY * config.divHeight);
      final double[] signal = signals[kSignal];
      if (signal.length < 2)
      {
         return;
      }
      double xPrev = 0;
      double yPrev = 0;
      for (int n = 0; n <= signal.length; n++)
      {
         final int k = n % signal.length;
         final double vx = xValues != null ? scaleX * xValues[k]
               : k * config.divWidth / samplesPerDiv;
         final double vy = scaleY * signal[k];
         final double x = x0 + vx;
         final double y = y0 - vy;
         if (samples)
         {
            if (0 <= n && n < signal.length)
            {
               graphics2D.draw(new Line2D.Double(x, y0, x, y));
               if (signalClip.contains(x, y))
               {
                  graphics2D.setClip(originalClip);
                  graphics2D.draw(new Ellipse2D.Double(x - 0.5 * rx, y - 0.5 * ry, rx, ry));
                  graphics2D.fill(new Ellipse2D.Double(x - 0.5 * rx, y - 0.5 * ry, rx, ry));
                  graphics2D.clip(signalClip);
               }
            }
         }
         else
         {
            graphics2D.clip(new Rectangle2D.Double(0, 0, width, height));
            if (0 < n && n < signal.length)
            {
               graphics2D.draw(new Line2D.Double(xPrev, yPrev, x, y));
            }
         }
         xPrev = x;
         yPrev = y;
      }
   }

   private static void normalize(final double[] array)
   {

      final int N = array.length;
      if (N > 0)
      {
         double max = 0;
         for (final double value : array)
         {
            final double c = abs(value);
            if (max < c)
            {
               max = c;
            }
         }
         if (max > 0 && max != 1)
         {
            final double scale = 1d / max;
            for (int k = 0; k < N; k++)
            {
               array[k] *= scale;
            }
         }
      }
   }

   private static final class GridPlotter
   {

      private final Config config;

      private final String abscissaeText;

      private final String ordinatesText;

      public GridPlotter(final Config config, final String abscissaeText,
            final String ordinatesText)
      {

         this.config = config;
         this.abscissaeText = abscissaeText;
         this.ordinatesText = ordinatesText;
      }

      public void plot(final Graphics2D graphics2D)
      {

         graphics2D.setColor(config.gridColor);
         final double x0 = config.noOfMarginDivsX * config.divWidth;
         final double x1 = (config.noOfMarginDivsX + config.noOfDivsX) * config.divWidth;
         final double y0 = config.noOfMarginDivsY * config.divHeight;
         final double y1 = (config.noOfMarginDivsY + config.noOfDivsY) * config.divHeight;
         plot(graphics2D, x0, y0, x1, y1, abscissaeText, ordinatesText);
      }

      private void plot(final Graphics2D graphics2D, final double x0, final double y0,
            final double x1, final double y1, final String abscissaeText,
            final String ordinatesText)
      {

         final Composite composite = graphics2D.getComposite();
         try
         {
            final float penWidth = config.framePenWidth * config.divWidth / 32f;
            graphics2D.setStroke(new BasicStroke(penWidth, CAP_ROUND, JOIN_ROUND));
            final double xm = (x0 + x1) / 2;
            final double ym = (y0 + y1) / 2;
            graphics2D.draw(new Line2D.Double(x0, y0, x1, y0));
            graphics2D.draw(new Line2D.Double(x0, y1, x1, y1));
            graphics2D.draw(new Line2D.Double(x0, y0, x0, y1));
            graphics2D.draw(new Line2D.Double(x1, y0, x1, y1));
            graphics2D.draw(new Line2D.Double(x0, ym, x1, ym));
            graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                                                               config.gridOpacity));
            for (double x = x0; x <= x1; x += config.divWidth)
            {
               graphics2D.draw(new Line2D.Double(x, y0, x, y1));
            }
            for (double y = y0; y <= y1; y += config.divHeight)
            {
               graphics2D.draw(new Line2D.Double(x0, y, x1, y));
            }
            final Font font = config.font.deriveFont(0.40f * config.divHeight);
            final FontRenderContext frc = graphics2D.getFontRenderContext();
            graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                                                               config.textOpacity));
            if (config.topLeft != null && !config.topLeft.isEmpty())
            {
               final String text = config.topLeft;
               final double x = x0;
               graphics2D.setFont(font);
               final TextLayout layout = new TextLayout(text, font, frc);
               final Rectangle2D bounds = layout.getBounds();
               final double h = bounds.getHeight();
               final double dy = 0.5 * (config.divHeight - h)
                     + (config.noOfDivsY + 1) * config.divHeight;
               final double dx = 0;
               graphics2D.drawString(text, (float) (x - dx), (float) (y1 + config.divHeight - dy));
            }
            if (config.topCenter != null && !config.topCenter.isEmpty())
            {
               final String text = config.topCenter;
               final double x = xm;
               graphics2D.setFont(font);
               final TextLayout layout = new TextLayout(text, font, frc);
               final Rectangle2D bounds = layout.getBounds();
               final double h = bounds.getHeight();
               final double dy = 0.5 * (config.divHeight - h)
                     + (config.noOfDivsY + 1) * config.divHeight;
               final double dx = 0.5 * bounds.getWidth();
               graphics2D.drawString(text, (float) (x - dx), (float) (y1 + config.divHeight - dy));
            }
            if (config.topRight != null && !config.topRight.isEmpty())
            {
               final String text = config.topRight;
               final double x = x1;
               graphics2D.setFont(font);
               final TextLayout layout = new TextLayout(text, font, frc);
               final Rectangle2D bounds = layout.getBounds();
               final double h = bounds.getHeight();
               final double dy = 0.5 * (config.divHeight - h)
                     + (config.noOfDivsY + 1) * config.divHeight;
               final double dx = bounds.getWidth();
               graphics2D.drawString(text, (float) (x - dx), (float) (y1 + config.divHeight - dy));
            }
            if (config.bottomRight != null && !config.bottomRight.isEmpty())
            {
               final String text = config.bottomRight;
               final double x = x1;
               graphics2D.setFont(font);
               final TextLayout layout = new TextLayout(text, font, frc);
               final Rectangle2D bounds = layout.getBounds();
               final double h = bounds.getHeight();
               final double dy = 0.5 * (config.divHeight - h);
               final double dx = bounds.getWidth();
               graphics2D.drawString(text, (float) (x - dx), (float) (y1 + config.divHeight - dy));
            }
            if (abscissaeText != null && !abscissaeText.isEmpty())
            {
               final String text = abscissaeText;
               final double x = x0;
               graphics2D.setFont(font);
               final TextLayout layout = new TextLayout(text, font, frc);
               final Rectangle2D bounds = layout.getBounds();
               final double h = bounds.getHeight();
               final double dy = 0.5 * (config.divHeight - h);
               final double dx = x == xm ? 0.5 * bounds.getWidth() : 0;
               graphics2D.drawString(text, (float) (x - dx), (float) (y1 + config.divHeight - dy));
            }
            if (ordinatesText != null && !ordinatesText.isEmpty())
            {
               final String text = ordinatesText;
               graphics2D.setFont(font.deriveFont(AffineTransform.getQuadrantRotateInstance(-1)));
               final TextLayout layout = new TextLayout(text, font, frc);
               final Rectangle2D bounds = layout.getBounds();
               final double h = bounds.getHeight();
               final double d = 0.5 * (config.divHeight - h);
               graphics2D.drawString(text, (float) (x0 - d), (float) y1);
            }
         }
         finally
         {
            graphics2D.setComposite(composite);
         }
      }
   }

   public static class Config
   {
      public final int divWidth = 48;

      public final int divHeight = 48;

      public final int noOfDivsX = 16;

      public final int noOfDivsY = 10;

      public final int noOfMarginDivsX = 1;

      public final int noOfMarginDivsY = 1;

      public final Color bgColor = new Color(0xEF, 0xFF, 0xEF);

      public final Color gridColor = Color.LIGHT_GRAY;

      public final Color[] signalColors = new Color[] { //
            //
            new Color(0xE0, 0x00, 0x00), //
            new Color(0xE0, 0x00, 0x40), //
            new Color(0xE0, 0x00, 0x80), //
            new Color(0x00, 0x70, 0xE0), //
            new Color(0x70, 0x00, 0xE0), //
            new Color(0x70, 0xE0, 0x70), //
            new Color(0x00, 0x00, 0xE0), //
      };

      public final Font font = new Font("Comic Sans MS", Font.PLAIN, 1);

      public final float framePenWidth = 1.0f;

      public final float gridPenWidth = 0.3f;

      public final float signalPenWidth = 0.8f;

      public final float gridOpacity = 1.f;

      public final float textOpacity = 1.f;

      public final String topLeft;

      public final String topCenter;

      public final String topRight;

      public final String bottomRight;

      public Config(final String topLeft, final String topCenter, final String topRight,
            final String bottomRight)
      {

         this.topLeft = topLeft;
         this.topCenter = topCenter;
         this.topRight = topRight;
         this.bottomRight = bottomRight;
      }
   }
}

Title: Re: Reentry possible?
Post by: Struthio on October 13, 2018, 09:06:22 PM
A.D. 2015 information about a heat shield have been published:


Quote
Heat Shield
(http://104.131.251.97/spacecraft/wp-content/uploads/sites/18/2015/09/7140970_orig-512x384.jpg)Photo: NASA
To withstand re-entry heating of up to 2,800 degrees Celsius when returning from Mars, the Orion spacecraft is equipped with the world’s most powerful heat shield which also is the largest ever built with a diameter of just over five meters.
The heat shield uses a titanium skeleton that provides the interface points with the crew module and adds strength to the heat shield required for it to withstand the impact with the water at splashdown. The skeleton is held in place by six brackets on the CM aft bulkhead. Fitted atop the skeleton is a carbon fiber skin that provides additional strength and acts as mounting surface for the AVCOAT ablative heat shield material. This structure consists of one center, 18 gore and 18 shoulder panels.
Originally developed by Avco, the AVCOAT technology is currently being provided by Textron and consists of an empty fiberglass-phenolic honeycomb structure that is attached to the carbon fiber structure and contains over 330,000 empty cells.
These cells within the honeycomb are then filled with the AVCOAT material using a hand gun. The AVCOAT layer is about 4 centimeters thick, 20% of that are expected to burn away during entry. The ablative material itself is an epoxy novolac resin with a number of additives to create a substance with a low density of 0.51g/cm³. During the re-entry process, pyrolysis of the material converts the material into a mixture of carbon and silica.
Titanium Skeleton, Heat Shield Skin & Skin-Skeleton Mate
(http://104.131.251.97/spacecraft/wp-content/uploads/sites/18/2015/09/Heat-Shield-Components-1024x235.jpg)Photos: NASA
 
(http://104.131.251.97/spacecraft/wp-content/uploads/sites/18/2015/09/2413374_orig-512x342.jpg)AVCOAT Application Technique – Photo: NASA
The principle behind ablative heat shield technology is to create a boundary layer between the shield’s outer wall and the extremely hot shock layer gas by allowing the heat shield material to slowly burn away and, in the process, generate gaseous reaction products that flow out of the heat shield and keep the shock layer at a separation distance, reducing the overall heat flux experienced by the outer shell of the spacecraft.
The processes occurring at the heat shield material include a charring, melting and sublimation on the one hand and pyrolysis on the other. Pyrolysis creates the product gases that are blowing outward and create the desired blockage of convective and catalytic heat flux. Radiative heat flux is reduced by introducing carbon compounds into the boundary layer gas which make it optically opaque.
Orion’s heat shield is launched with a reflective cover installed over it to protect it from the cold temperatures encountered in space. This cover burns away in the initial stages of re-entry.
The current heat shield design may require modifications to the manufacturing process since the hand-filled AVCOAT material was more uneven than desired when Orion’s first heat shield rolled off the manufacturing line. Changes may also be necessary to fully certify the heat shield for re-entry energies occurring in Mars missions as the current version is only suitable for entry energies of lunar flights.

Source (http://spaceflight101.com/spacecraft/orion/)


According to these claims, "the world’s most powerful heat shield" (published 2015)  is to "withstand re-entry heating of up to 2,800°C".

I don't believe in materials that don't vaporize or at least desintegrate at max 2,000°C and pressures of like 100kN.
Title: Re: Reentry possible?
Post by: Struthio on October 13, 2018, 09:52:59 PM
Gagarin's spherical capsule:

m = 2400kg (mass)
d = 2.3m  (diameter)
A = π d2 = 16.62m2 (surface area)

In an orbit at
h = 120km (altitude above sea level)

Radius of the earth:
r = 6370km

Gravitational acceleration at sea level:
g = 9.81m/s2

Gravitational acceleration as a function of altitude:
g(h) = g (r / (r + h))

Centrifugal acceleration:
az = v2 / (r + h)

The speed of the capsule in the given orbit is [resolving: g(h) = v2 / (r + h)]
v = sqrt((r + h) g(h)) = 7905m/s

The kinetic energy of the capsule is
Ekin = 0.5 m v2 = 75GJ

To get an idea what 75GJ are. A German ICE train with 8 waggons is 200m long and has a weight of 450000kg. At a speed of 250km/h it has 1.1GJ. We need 68 such trains of 200m length, or a train of 13.6km length at 250km/h to imagine the kinetic energy of Gagarin's tiny capsule.


Now let's descend down to sea level. Given the unrealistically high 20min or 1200s of travel time, and assuming unrealistically that braking power is constant, braking power is

P = 75GJ / 1200s = 62.5MW

The corresponding temperature (Stefan Boltzmann law (https://en.wikipedia.org/wiki/Stefan%E2%80%93Boltzmann_law)) is

2854K or 2580°C.

The heat shield of the Orion spacecraft (see post above) promises protection against 2800°C. Did Gagarin have such a high-tech heat shield of the third millenium?

The assumptions are not realistic. Given the curves of the Reentry Breakup Recorder of The Aerospace Corporation (see post above), we see that maximum speed is at least the double of average speed and acceleration has a peak of more than 7 g (Gagarin is said to have had 8g), being around 3g where speed is max.

Braking power is the time derivative of kinetic Energy 0.5 m v2(t)

P = m v(t) a(t)

Peak braking power is

P = 2400kg 2*7905m/s 3*9.81m/s2 = 1.12GW

The corresponding temperature is

5897K or 5595°C.

What type of heat shield did Gagarin have?


Title: Re: Reentry possible?
Post by: Neil Obstat on October 16, 2018, 11:03:22 AM
.
The heat shield uses a titanium skeleton that provides the interface points with the crew module and adds strength to the heat shield required for it to withstand the impact with the water at splashdown.
.
Why does the heat shield need to survive impact with water at splashdown? Isn't the purpose of the heat shield to survive re-entry heat of friction with the atmosphere? When splashdown occurs, there is no more atmosphere friction to be concerned with, so why is the heat shield still important?
.
Title: Re: Reentry possible?
Post by: Stanley N on October 17, 2018, 11:27:00 PM
Now let's descend down to sea level. Given the unrealistically high 20min or 1200s of travel time, and assuming unrealistically that braking power is constant, braking power is

P = 75GJ / 1200s = 62.5MW

The corresponding temperature (Stefan Boltzmann law (https://en.wikipedia.org/wiki/Stefan%E2%80%93Boltzmann_law)) is

2854K or 2580°C.
This is, I think, the place you should look into more. You're using the equation for radiative heat transfer, as if the reentry vehicle heats up to this temperature and disperses heat by black body radiation.

The vehicle heats up from the heat generated by the bow shock (of a blunt body reentry vehicle). This happens over a large area. Heat is transferred to the vehicle mostly by convection, with some by radiation. The heat load the vehicle has to handle is only a fraction of the overall energy dissipated in losing kinetic energy - most of that energy goes to the atmosphere.
Title: Re: Reentry possible?
Post by: Struthio on October 17, 2018, 11:56:00 PM
This is, I think, the place you should look into more. You're using the equation for radiative heat transfer, as if the reentry vehicle heats up to this temperature and disperses heat by black body radiation.

The vehicle heats up from the heat generated by the bow shock (of a blunt body reentry vehicle). This happens over a large area. Heat is transferred to the vehicle mostly by convection, with some by radiation. The heat load the vehicle has to handle is only a fraction of the overall energy dissipated in losing kinetic energy - most of that energy goes to the atmosphere.

I assume that the heat shield is ideal and emits all friction energy in form of radiation. Doing this, the surface of the heat shield has the Boltzmann-temperature.

Alternatively, part of the energy/power may heat the vehicle. But that would have to be a small fraction of the 62.5MW which does not really make difference.
Title: Re: Reentry possible?
Post by: happenby on October 18, 2018, 12:22:36 PM
Origen called the firmament “without doubt firm and solid” (First Homily on Genesis, FC 71). Ambrose, commenting on Genesis 1:6, said, “the specific solidity of this exterior firmament is meant” (Hexameron, FC 42.60). And Saint Augustine said the word firmament was used “to indicate not that it is motionless but that it is solid and that it constitutes an impassible boundary between the waters above and the waters below” (The Literal Meaning of Genesis, ACW 41.1.61).  
Title: Re: Reentry possible?
Post by: Struthio on October 18, 2018, 04:57:51 PM
Origen called the firmament “without doubt firm and solid” (First Homily on Genesis, FC 71). Ambrose, commenting on Genesis 1:6, said, “the specific solidity of this exterior firmament is meant” (Hexameron, FC 42.60). And Saint Augustine said the word firmament was used “to indicate not that it is motionless but that it is solid and that it constitutes an impassible boundary between the waters above and the waters below” (The Literal Meaning of Genesis, ACW 41.1.61).  

What does that have to do with the question whether a reentry from a low orbit is possible?
Title: Re: Reentry possible?
Post by: Stanley N on October 18, 2018, 06:24:16 PM
I assume that the heat shield is ideal and emits all friction energy in form of radiation. Doing this, the surface of the heat shield has the Boltzmann-temperature.

Alternatively, part of the energy/power may heat the vehicle. But that would have to be a small fraction of the 62.5MW which does not really make difference.
I believe some early ICBMs and Soviet testing used radiative heat shields, but I believe all manned missions from Gagarin on used ablative heat shields. Part of the heat shield melts and that is where a lot of the heat goes. Much more than goes to radiative heat transfer.
Title: Re: Reentry possible?
Post by: happenby on October 19, 2018, 03:25:34 PM
What does that have to do with the question whether a reentry from a low orbit is possible?
There is no such thing as "re entry".  Especially from low earth "orbit".  The firmament sits as a dome over the earth and nothing gets outside of it because there's water on the upper side of it.   Low earth orbit suggests there is an "outer space" where rockets go, and moon landings are done, but that has never been proven and is counter to what we know about the upper atmosphere which is an ether and not "space".   Much of what NASA and RASA talk about regarding rockets and space is provably garbage.  
Title: Re: Reentry possible?
Post by: Neil Obstat on October 21, 2018, 01:27:53 AM
I believe some early ICBMs and Soviet testing used radiative heat shields, but I believe all manned missions from Gagarin on used ablative heat shields. Part of the heat shield melts and that is where a lot of the heat goes. Much more than goes to radiative heat transfer.
.
They're saying that the vast majority of the heat energy gets dissipated to the atmosphere. Since heat radiating energy takes TIME, and ends up being very SLOW, the melting material leaving the heat shield would make more sense, since it happens quickly. The effect would be a bright streaking light in the sky trailed by a cloud like exhaust, which is exactly what we see when re-entry occurs, similar to a meteor's action in the sky. 
.
The Space Shuttle lost a measurable thickness off its tiles each time it re-entered.