Skip to content

Instantly share code, notes, and snippets.

@SolarianZ
Last active July 12, 2023 15:19
Show Gist options
  • Save SolarianZ/78f9b22d9663d77b6e6c1b0c60cc6322 to your computer and use it in GitHub Desktop.
Save SolarianZ/78f9b22d9663d77b6e6c1b0c60cc6322 to your computer and use it in GitHub Desktop.
{"category": "C#/Runtime/Utility/Math", "keywords": "Math, Physics, Simple Harmonic Motion, SHM, Second Order System"} An approximate simulator for Simple Harmonic Motion. Note: This is not a precise simulator.
// Visualizer(In Unity Engine): https://gist.github.com/SolarianZ/a53363f0994aa7858d9e0a08ecf3f014
using System;
using System.Numerics;
// Note: This is not a precise simulator.
public class SimpleHarmonicMotion
{
/// <summary>
/// The natural frequency of the system measured in Hz.
/// It describes the speed at which the system will respond to changes in the input,
/// as well as the frequency the system will tend to vibrate at,
/// but does not affect the shape of the resulting motion.
/// </summary>
public float Frequency { get; set; }
/// <summary>
/// The damping cofficient. It describes how the system comes to settle at the desitination.
/// When the damping is 0, the system will vibrate indefinitely.
/// When the damping is between 0 and 1, the system is underdamped, and will vibrate before settling at the desitination.
/// When the damping greater than 1, the system is overdamped, and will settle at the desitination without vibrating.
/// </summary>
public float Damping { get; set; }
public Vector3 Position { get; set; }
public Vector3 Velocity { get; set; }
/// <summary>
/// Creates a new simple harmonic motion simulator.
/// </summary>
/// <param name="frequency">
/// The natural frequency of the system measured in Hz.
/// It describes the speed at which the system will respond to changes in the input,
/// as well as the frequency the system will tend to vibrate at,
/// but does not affect the shape of the resulting motion.
/// </param>
/// <param name="damping">
/// The damping cofficient. It describes how the system comes to settle at the desitination.
/// When the damping is 0, the system will vibrate indefinitely.
/// When the damping is between 0 and 1, the system is underdamped, and will vibrate before settling at the desitination.
/// When the damping greater than 1, the system is overdamped, and will settle at the desitination without vibrating.
/// </param>
/// <param name="initialPosition"></param>
public SimpleHarmonicMotion(float frequency, float damping, Vector3 initialPosition)
{
Frequency = frequency;
Damping = damping;
Position = initialPosition;
Velocity = Vector3.Zero;
}
public void ResetPosition(Vector3 initialPosition)
{
Position = initialPosition;
Velocity = Vector3.Zero;
}
/// <summary>
/// Updates the system and returns the new position.
/// </summary>
/// <param name="deltaTime">The delta time since the last update.</param>
/// <param name="destination">The destination of the system.</param>
/// <returns></returns>
public Vector3 Tick(float deltaTime, Vector3 destination)
{
// Calculate the angular frequency
float omega = 2 * MathF.PI * Frequency;
// Calculate the damping ratio
float zeta = Damping;
// Calculate the natural response coefficient
float k1 = 2 * zeta * omega;
float k2 = omega * omega;
// Calculate the acceleration based on the current position, velocity, and destination
Vector3 acceleration = (destination - Position) * k2 - (k1 * Velocity);
// Update the velocity and position based on the deltaTime
Velocity += acceleration * deltaTime;
Position += Velocity * deltaTime;
return Position;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment