Functions/GenXdev.Helpers.Physics/Get-FreeFallTime.cs
|
using System.Management.Automation; namespace GenXdev.Helpers.Physics { [System.ComponentModel.Description(@" .SYNOPSIS Calculates the time required for an object to fall a given height during free fall. .DESCRIPTION Calculates the time duration required for an object to fall a specified height using a numerical method that accounts for air resistance and terminal velocity. The calculation uses small time steps to accurately model the physics of falling objects with realistic terminal velocity constraints. .LICENSE Copyright (C) 2026 René Vaessen / GenXdev This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. .EXAMPLE ```powershell Get-FreeFallTime -HeightInMeters 100 -TerminalVelocityInMs 53 ``` Calculates the time required to fall 100 meters with default human terminal velocity. .EXAMPLE ```powershell Get-FreeFallTime 50 ``` Calculates the time required to fall 50 meters using positional parameter and default terminal velocity. .EXAMPLE ```powershell Get-FreeFallTime -HeightInMeters 100 -As ""minutes"" ``` Calculates the time required to fall 100 meters and returns the result in minutes. ")] [Cmdlet(VerbsCommon.Get, "FreeFallTime")] [OutputType(typeof(double))] public class GetFreeFallTimeCommand : PSGenXdevCmdlet { /// <summary> /// The height to fall in meters for which to calculate the time duration. /// </summary> [Parameter( Mandatory = true, Position = 0, HelpMessage = "The height to fall in meters" )] public double HeightInMeters { get; set; } /// <summary> /// The terminal velocity in meters per second (default: 53 m/s for human). /// </summary> [Parameter( Mandatory = false, Position = 1, HelpMessage = ("The terminal velocity in meters per second " + "(default: 53 m/s for human)") )] public double TerminalVelocityInMs { get; set; } = 53; /// <summary> /// The unit for the output time. /// </summary> [Parameter( Mandatory = false, Position = 2, HelpMessage = "The unit for the output time" )] [ValidateSet("seconds", "minutes", "hours", "milliseconds", "days")] public string As { get; set; } = "seconds"; /// <summary> /// Begin processing - initialization logic /// </summary> protected override void BeginProcessing() { WriteVerbose( "Starting free fall time calculation for " + HeightInMeters + " meters " + "with terminal velocity " + TerminalVelocityInMs + " m/s" ); } /// <summary> /// Process record - main cmdlet logic /// </summary> protected override void ProcessRecord() { // Define the acceleration due to gravity in meters per second squared double gravity = 9.81; // Set up numerical integration parameters for accurate calculation double dt = 0.01; // Initialize time tracking variable double time = 0; // Initialize height accumulator double height = 0; // Initialize velocity tracker double velocity = 0; // Perform numerical integration using small time steps until height is reached while (height < HeightInMeters) { // Apply air resistance model by capping velocity at terminal velocity if (velocity >= TerminalVelocityInMs) { // Maintain constant terminal velocity when reached velocity = TerminalVelocityInMs; } else { // Accelerate under gravity when below terminal velocity velocity += gravity * dt; } // Calculate distance traveled in this time step height += velocity * dt; // Advance time by one step time += dt; // Prevent infinite loops with safety timeout if (time > 1000) { WriteError(new ErrorRecord( new Exception("Calculation timeout exceeded 1000 seconds"), "CalculationTimeout", ErrorCategory.OperationTimeout, null )); WriteObject((double)0); return; } } WriteVerbose("Calculated fall time: " + time + " seconds"); // Convert to desired unit using PowerShell function var scriptBlock = ScriptBlock.Create( "param($Value, $FromUnit, $ToUnit) " + "GenXdev\\Convert-PhysicsUnit -Value $Value -FromUnit $FromUnit -ToUnit $ToUnit" ); var results = scriptBlock.Invoke(time, "seconds", As); // Extract the result from PSObject double result = 0; if (results.Count > 0 && results[0].BaseObject is double) { result = (double)results[0].BaseObject; } // Return the calculated time as double WriteObject(result); } /// <summary> /// End processing - cleanup logic /// </summary> protected override void EndProcessing() { // No cleanup needed } } } |