C# 从一个位置跳到另一个位置
C# Lerping from position to position
我需要制作一个图片框以从一个位置移动到另一个位置(就像您可以在 unity 中那样做)。
我该怎么做,是否有内置功能?
谢谢:)
线性插值 (lerp) 实际上是一个非常容易实现的函数。等式是
float Lerp(float firstFloat, float secondFloat, float by)
{
return firstFloat * (1 - by) + secondFloat * by;
}
高阶 Lerp 只是包裹了低阶 Lerp:
Vector2 Lerp(Vector2 firstVector, Vector2 secondVector, float by)
{
float retX = Lerp(firstVector.x, secondVector.x, by);
float retY = Lerp(firstVector.y, secondVector.y, by);
return new Vector2(retX, retY);
}
DirectX SDK 具有像 Unity 一样的各种数学函数,但仅仅为 Lerp 带来的开销就很大。你可能最好只实现自己的。
Greg Bahm 写了反 lerp 方程 firstFloat * by + secondFloat * (1 - by)
,其中 firstFloat 是 secondFloat,secondFloat 是 firstFloat。
事实上,正确的 lerp 方程是:
firstFloat * (1 - by) + secondFloat * by
但是线性插值最快的方法是:
firstFloat + (secondFloat - firstFloat) * by
这是 2 additions/subtractions 和 1 次乘法,而不是 2 addition/subtractions 和 2 次乘法。
Vector2 的 Lerp 是正确的。
此外,最快的方法不太精确(谢谢,cid):
Imprecise method, which does not guarantee v = v1 when t = 1, due to floating-point arithmetic error. This method is monotonic
This form may be used when the hardware has a native fused multiply-add instruction.
https://en.wikipedia.org/wiki/Linear_interpolation#Programming_language_support
试试这个
float Lerp(float a, float b, float t)
{
//return firstFloat * by + secondFloat * (1 - by);
return (1f - t) * a + t * b;
}
PointF Lerp(PointF a, PointF b, float t)
{
float retX = Lerp(a.X, b.X, t);
float retY = Lerp(a.Y, b.Y, t);
return new PointF(retX, retY);
}
public static float CubicInterpolation(float v0, float v1, float v2, float v3, float t) {
//var v01 = Lerp( v0, v1, t );
//var v12 = Lerp( v1, v2, t );
//var v23 = Lerp( v2, v3, t );
//var v012 = Lerp( v01, v12, t );
//var v123 = Lerp( v12, v23, t );
//return Lerp( v012, v123, t );
var p = (v3 - v2) - (v0 - v1);
var q = (v0 - v1) - p;
var r = v2 - v0;
var s = v1;
return (p * t * 3) + (q * t * 2) + (r * t) + s;
//var r = 1f - t;
//var f0 = r * r * r;
//var f1 = r * r * t * 3;
//var f2 = r * t * t * 3;
//var f3 = t * t * t;
//return (v0 * f0) + (v1 * f1) + (v2 * f2) + (v3 * f3);
}
public static float QuadraticInterpolation(float v0, float v1, float v2, float t) {
var v01 = Lerp( v0, v1, t );
var v12 = Lerp( v1, v2, t );
return Lerp( v01, v12, t );
}
public static float Lerp(float v1, float v2, float t) {
return v1 + ((v2 - v1) * t);
}
public static float CosInterpolation(float t) {
t = (float) -Math.Cos( t * Math.PI ); // [-1, 1]
return (t + 1) / 2; // [0, 1]
}
public static float PerlinSmoothStep(float t) {
// Ken Perlin's version
return t * t * t * ((t * ((6 * t) - 15)) + 10);
}
public static float SmoothStep(float t) {
return t * t * (3 - (2 * t));
}
我需要制作一个图片框以从一个位置移动到另一个位置(就像您可以在 unity 中那样做)。
我该怎么做,是否有内置功能?
谢谢:)
线性插值 (lerp) 实际上是一个非常容易实现的函数。等式是
float Lerp(float firstFloat, float secondFloat, float by)
{
return firstFloat * (1 - by) + secondFloat * by;
}
高阶 Lerp 只是包裹了低阶 Lerp:
Vector2 Lerp(Vector2 firstVector, Vector2 secondVector, float by)
{
float retX = Lerp(firstVector.x, secondVector.x, by);
float retY = Lerp(firstVector.y, secondVector.y, by);
return new Vector2(retX, retY);
}
DirectX SDK 具有像 Unity 一样的各种数学函数,但仅仅为 Lerp 带来的开销就很大。你可能最好只实现自己的。
Greg Bahm 写了反 lerp 方程 firstFloat * by + secondFloat * (1 - by)
,其中 firstFloat 是 secondFloat,secondFloat 是 firstFloat。
事实上,正确的 lerp 方程是:
firstFloat * (1 - by) + secondFloat * by
但是线性插值最快的方法是:
firstFloat + (secondFloat - firstFloat) * by
这是 2 additions/subtractions 和 1 次乘法,而不是 2 addition/subtractions 和 2 次乘法。 Vector2 的 Lerp 是正确的。
此外,最快的方法不太精确(谢谢,cid):
Imprecise method, which does not guarantee v = v1 when t = 1, due to floating-point arithmetic error. This method is monotonic
This form may be used when the hardware has a native fused multiply-add instruction. https://en.wikipedia.org/wiki/Linear_interpolation#Programming_language_support
试试这个
float Lerp(float a, float b, float t)
{
//return firstFloat * by + secondFloat * (1 - by);
return (1f - t) * a + t * b;
}
PointF Lerp(PointF a, PointF b, float t)
{
float retX = Lerp(a.X, b.X, t);
float retY = Lerp(a.Y, b.Y, t);
return new PointF(retX, retY);
}
public static float CubicInterpolation(float v0, float v1, float v2, float v3, float t) {
//var v01 = Lerp( v0, v1, t );
//var v12 = Lerp( v1, v2, t );
//var v23 = Lerp( v2, v3, t );
//var v012 = Lerp( v01, v12, t );
//var v123 = Lerp( v12, v23, t );
//return Lerp( v012, v123, t );
var p = (v3 - v2) - (v0 - v1);
var q = (v0 - v1) - p;
var r = v2 - v0;
var s = v1;
return (p * t * 3) + (q * t * 2) + (r * t) + s;
//var r = 1f - t;
//var f0 = r * r * r;
//var f1 = r * r * t * 3;
//var f2 = r * t * t * 3;
//var f3 = t * t * t;
//return (v0 * f0) + (v1 * f1) + (v2 * f2) + (v3 * f3);
}
public static float QuadraticInterpolation(float v0, float v1, float v2, float t) {
var v01 = Lerp( v0, v1, t );
var v12 = Lerp( v1, v2, t );
return Lerp( v01, v12, t );
}
public static float Lerp(float v1, float v2, float t) {
return v1 + ((v2 - v1) * t);
}
public static float CosInterpolation(float t) {
t = (float) -Math.Cos( t * Math.PI ); // [-1, 1]
return (t + 1) / 2; // [0, 1]
}
public static float PerlinSmoothStep(float t) {
// Ken Perlin's version
return t * t * t * ((t * ((6 * t) - 15)) + 10);
}
public static float SmoothStep(float t) {
return t * t * (3 - (2 * t));
}