惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
博客园 - 司徒正美
WordPress大学
WordPress大学
爱范儿
爱范儿
小众软件
小众软件
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
罗磊的独立博客
博客园_首页
V
V2EX
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Tailwind CSS Blog
大猫的无限游戏
大猫的无限游戏
The Cloudflare Blog
MyScale Blog
MyScale Blog
IT之家
IT之家
H
Help Net Security
Blog — PlanetScale
Blog — PlanetScale
Microsoft Security Blog
Microsoft Security Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Recent Announcements
Recent Announcements
F
Fortinet All Blogs
The GitHub Blog
The GitHub Blog
Y
Y Combinator Blog
人人都是产品经理
人人都是产品经理

博客园 - porter_代码工作者

给 codex 的长期任务,长沙一个定时任务,做保活功能 .net nupkgs 配置 Vibe Coding ---- 2026年3月 很火的词 bigemap 软件 godot 透明 与 混合模式 叠加使用效果 AI 回复 godot 描边插件 C# ScottPlot 高性能图表 高性能绘图库 godot + Avalonia 渲染第三方UI 判断左手坐标系和右手坐标系的方法 国产操作系统: 项目配置 .net 添加Nuget源 godot 通过代码程序化地生成一个三维数据场,然后使用光线步进(Ray Marching)着色器将其渲染出来。 godot shader 等高线的绘制 和 模型描边的绘制 和 shader 常用算法 godot shader 控制 颜色绘制的 金典公式 godot 四元数 旋转 godot 二维报表库 godot 5.4.4 线程安全的调用方法 godot FPS 第三人称教程 UE4脸部捕捉 LiveLink 数据 常用四元数的值 unity Avatar (化身) 使用electron-builder打包 vue3 项目 exe
godot 位置 和 角度 的平滑插值
porter_代码工作者 · 2025-08-19 · via 博客园 - porter_代码工作者

方案1
/// <summary>
/// Returns a transform interpolated between this transform and another
/// <paramref name="transform"/> by a given <paramref name="weight"/>
/// (on the range of 0.0 to 1.0).
/// </summary>
/// <param name="transform">The other transform.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The interpolated transform.</returns>
public readonly Transform3D InterpolateWith(Transform3D transform, real_t weight)
{
Vector3 sourceScale = Basis.Scale;
Quaternion sourceRotation = Basis.GetRotationQuaternion();
Vector3 sourceLocation = Origin;

Vector3 destinationScale = transform.Basis.Scale;
Quaternion destinationRotation = transform.Basis.GetRotationQuaternion();
Vector3 destinationLocation = transform.Origin;

var interpolated = new Transform3D();
Quaternion quaternion = sourceRotation.Slerp(destinationRotation, weight).Normalized();
Vector3 scale = sourceScale.Lerp(destinationScale, weight);
interpolated.Basis.SetQuaternionScale(quaternion, scale);
interpolated.Origin = sourceLocation.Lerp(destinationLocation, weight);

return interpolated;
}

方案2 欧拉角的方案(直线,不是球面) ,不使用 Lerp 函数 

public static class AngleExtensions

{

    public static Vector3 Clamp360(Vector3 eulerAngles)

    {

        return new Vector3(gTweens.Source.Extensions.AngleExtensions.Clamp360(eulerAngles.X), gTweens.Source.Extensions.AngleExtensions.Clamp360(eulerAngles.Y), gTweens.Source.Extensions.AngleExtensions.Clamp360(eulerAngles.Z));

    }

    public static Vector3 DeltaAngle(Vector3 current, Vector3 target)

    {

        return new Vector3(gTweens.Source.Extensions.AngleExtensions.DeltaAngle(current.X, target.X),gTweens.Source.Extensions.AngleExtensions.DeltaAngle(current.Y, target.Y), gTweens.Source.Extensions.AngleExtensions.DeltaAngle(current.Z, target.Z));

    }

    public static Vector3 GetDestinationAngleDegrees(Vector3 origin, Vector3 destination, RotationMode mode)

    {

        switch (mode)

        {

            case RotationMode.ShortestDistance:

                {

                    Vector3 current = Clamp360(origin);

                    Vector3 target = Clamp360(destination);

                    Vector3 vector = DeltaAngle(current, target);

                    return origin + vector;

                }

            default:

                return destination;

        }

    }

    public static Vector3 GetDestinationAngleRadiants(Vector3 origin, Vector3 destination, RotationMode mode)

    {

        return GetDestinationAngleDegrees(origin * 57.29578f, destination * 57.29578f, mode) * 0.01745329f;

    }

}