JD2022-TU1/main/tools/framework/JD.Timeline/View/Actions/Macros/CurveExtensions.cs

112 lines
No EOL
3.5 KiB
C#

using System;
using System.Drawing;
using System.Linq;
using JD.Maths.Utils;
using JD.Timeline.Model.Curves;
using JD.Serialization;
namespace JD.Timeline.View.Actions.Macros
{
public static class CurveExtensions
{
public static PointF ScaleX(this PointF point, float ratio)
{
return new PointF(point.X * ratio, point.Y);
}
public static void ScaleX(this BezierCurveFloat curve, float ratio)
{
using (curve.BeginScopedUpdate())
{
foreach (var key in curve.Keys)
{
key.Position = key.Position.ScaleX(ratio);
key.Out = key.Out.ScaleX(ratio);
key.In = key.In.ScaleX(ratio);
}
}
}
public static PointF ScaleY(this PointF point, float ratio, float offset)
{
return new PointF(point.X, (point.Y - offset) * ratio + offset);
}
public static void ScaleY(this BezierCurveFloat curve, float ratio, float offset)
{
using (curve.BeginScopedUpdate())
{
foreach (var key in curve.Keys)
{
key.Position = key.Position.ScaleY(ratio, offset);
key.Out = key.Out.ScaleY(ratio, offset);
key.In = key.In.ScaleY(ratio, offset);
}
}
}
public static PointF MirrorHorizontal(this PointF point, int duration)
{
return new PointF(duration - point.X, point.Y);
}
public static void MirrorVertical(this BezierCurveFloat curve, MirrorAxis axis)
{
if (curve.Keys.Any())
{
float min = curve.Keys.Min(point => point.Position.Y);
float max = curve.Keys.Max(point => point.Position.Y);
if (axis == MirrorAxis.Default)
{
axis = curve.Type.Infos().ValueRange.Min.EqualsWithEpsilon(0) ? MirrorAxis.MiddlePoint : MirrorAxis.Origin;
}
float axisPoint = FindAxis(min, max, axis);
using (curve.BeginScopedUpdate())
{
foreach (var key in curve.Keys)
{
key.Position = key.Position.MirrorVertical(axisPoint);
key.Out = key.Out.MirrorVertical(axisPoint);
key.In = key.In.MirrorVertical(axisPoint);
}
}
}
}
public static PointF MirrorVertical(this PointF point, float axisPoint)
{
return new PointF(point.X, ((point.Y - axisPoint) * -1f) + axisPoint);
}
private static float FindAxis(float min, float max, MirrorAxis axis)
{
switch (axis)
{
case MirrorAxis.Origin:
return 0;
case MirrorAxis.CurveMin:
return min;
case MirrorAxis.CurveMax:
return max;
case MirrorAxis.MiddlePoint:
return min + ((max - min) / 2f);
default:
throw new NotSupportedException("No case defined for " + axis);
}
}
public enum MirrorAxis
{
/// <summary>
/// Finds the right axis for the curve.
/// </summary>
Default,
Origin,
MiddlePoint,
CurveMin,
CurveMax,
}
}
}