Skip to content

Instantly share code, notes, and snippets.

@StagPoint
Last active June 17, 2022 10:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save StagPoint/9a11a45507481acd583cffdb5182102c to your computer and use it in GitHub Desktop.
Save StagPoint/9a11a45507481acd583cffdb5182102c to your computer and use it in GitHub Desktop.
Implements a simplistic 3D curve smoother for Unity. Depending on the intended use case, best results might be achieved by preprocessing the curve to have equally-spaced points, or using the Ramer-Douglas-Peucker algorithm to remove unnecessary points. It wasn't needed for my use case, so I didn't include that code here. YMMV.
namespace StagPoint.Math
{
using Unity.Collections;
using Unity.Mathematics;
/// <summary>
/// Implements a simplistic 3D curve smoother
/// </summary>
public static class CurveSmoother
{
/// <summary>
/// Performs in-place curve smoothing on a closed curve (loop)
/// </summary>
/// <param name="curve">A list of points to smooth.</param>
/// <param name="iterations">The number of smoothing iterations to perform.</param>
/// <param name="alpha">The amount of change made to point positions during each iteration.</param>
public static void SmoothInPlaceLoop( NativeArray<float3> curve, int iterations = 1, float alpha = 0.25f )
{
int N = curve.Length;
for( int iter = 0; iter < iterations; ++iter )
{
for( int i = 0; i < N; ++i )
{
int index = ( i % N );
int iPrev = ( i == 0 ) ? N - 1 : i - 1;
int iNext = ( i + 1 ) % N;
var prev = curve[ iPrev ];
var next = curve[ iNext ];
var c = ( prev + next ) * 0.5f;
curve[ index ] = ( 1 - alpha ) * curve[ index ] + ( alpha ) * c;
}
}
}
/// <summary>
/// Performs in-place curve smoothing on an open curve (not looped)
/// </summary>
/// <param name="curve">A list of points to smooth.</param>
/// <param name="iterations">The number of smoothing iterations to perform.</param>
/// <param name="alpha">The amount of change made to point positions during each iteration.</param>
public static void SmoothInPlaceOpen( NativeArray<float3> curve, int iterations = 1, float alpha = 0.25f )
{
for( int iter = 0; iter < iterations; ++iter )
{
for( int i = 1; i < curve.Length - 1; ++i )
{
var prev = curve[ i - 1 ];
var next = curve[ i + 1 ];
var c = ( prev + next ) * 0.5f;
curve[ i ] = ( 1 - alpha ) * curve[ i ] + ( alpha ) * c;
}
}
}
}
}
@StagPoint
Copy link
Author

StagPoint commented Feb 16, 2021

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment