C++如何动态生成两点间多个路径点实现平滑传送移动
两点间平滑移动路径点生成方案
你可以直接用线性插值逻辑实现动态生成任意数量的路径点,不需要硬编码嵌套调用中点计算函数。
基础定义
现有两个POINT类型坐标,分别对应角色位置和目标点:
POINT a; // 角色当前位置 POINT b; // 地图目标位置
原先使用的中点计算逻辑仅能单次返回两点中点,嵌套调用的写法灵活性极差:
POINT midpoint(const POINT& a, const POINT& b) { POINT ret; ret.x = (a.x + b.x) / 2; ret.y = (a.y + b.y) / 2; return ret; } // 硬编码嵌套的写法,不推荐 POINT middlepoint = midpoint(a, b); POINT closerpoint = midpoint(a, middlepoint);
实现逻辑
核心用线性插值(Lerp)计算两点连线上任意位置的坐标:
- 用取值范围为
[0,1]的系数t表示移动进度,t=0对应起点a,t=1对应终点b - 任意进度下的坐标公式:
x = a.x + (b.x - a.x) * ty = a.y + (b.y - a.y) * t - 按照你需要的路径点总数量,均匀拆分t的步长,循环一次就能生成全部路径点,支持动态调整点数量,不需要修改核心逻辑。
可直接复用的代码
#include <vector> #include <Windows.h> // 引入Windows头文件以使用POINT类型,若有自定义POINT定义可移除 /** * 生成两点间的移动路径点 * @param a 起点坐标 * @param b 终点坐标 * @param totalPointCount 生成的路径点总数量(包含起点、终点),数值越大路径越平滑 * @return 按顺序排列的路径点集合 */ std::vector<POINT> generateSmoothPath(const POINT& a, const POINT& b, int totalPointCount) { std::vector<POINT> path; if (totalPointCount < 2) return path; // 路径至少需要包含起终点两个点 const float tStep = 1.0f / (totalPointCount - 1); for (int i = 0; i < totalPointCount; i++) { const float t = tStep * i; POINT currentPoint{}; // 针对整数坐标做四舍五入,避免截断导致的坐标偏移 currentPoint.x = static_cast<LONG>(a.x + (b.x - a.x) * t + 0.5f); currentPoint.y = static_cast<LONG>(a.y + (b.y - a.y) * t + 0.5f); path.push_back(currentPoint); } return path; }
扩展说明
- 调用时只需要传入你需要的路径点数量即可,比如想要拆成20段平滑移动,传
totalPointCount=21即可 - 如果需要实现加减速的缓动效果,只需要修改
t的计算逻辑,比如用t = t * t替换原来的线性t值,就能实现起步慢、逐渐加速的移动效果,不需要改动坐标计算部分 - 相比反复嵌套计算中点的写法,这个方案时间复杂度为O(n),没有冗余计算,点数量可以运行时动态调整,不需要硬编码逻辑。
内容的提问来源于stack exchange,提问作者Minseok Kim
相关产品推荐
相关产品推荐

