找回密码
 立即注册
首页 业界区 业界 HarmonyOS运动开发:如何绘制运动速度轨迹 ...

HarmonyOS运动开发:如何绘制运动速度轨迹

准挝 3 天前
前言
在户外运动应用中,绘制运动速度轨迹不仅可以直观地展示用户的运动路线,还能通过颜色变化反映速度的变化,帮助用户更好地了解自己的运动状态。然而,如何在鸿蒙系统中实现这一功能呢?本文将结合实际开发经验,深入解析从数据处理到地图绘制的全过程,带你一步步掌握如何绘制运动速度轨迹。
1.jpeg

一、核心工具:轨迹颜色与优化
绘制运动速度轨迹的关键在于两个工具类:PathGradientTool和PathSmoothTool。这两个工具类分别用于处理轨迹的颜色和优化轨迹的平滑度。
1.轨迹颜色工具类:PathGradientTool
PathGradientTool的作用是根据运动速度为轨迹点分配颜色。速度越快,颜色越接近青色;速度越慢,颜色越接近红色。以下是PathGradientTool的核心逻辑:
[code]export class PathGradientTool {  /**   * 获取路径染色数组   * @param points 路径点数据   * @param colorInterval 取色间隔,单位m,范围20-2000,多长距离设置一次颜色   * @returns 路径染色数组   */  static getPathColors(points: RunPoint[], colorInterval: number): string[] | null {    if (!points || points.length < 2) {      return null;    }    let interval = Math.max(20, Math.min(2000, colorInterval));    const pointsSize = points.length;    const speedList: number[] = [];    const colorList: string[] = [];    let index = 0;    let lastDistance = 0;    let lastTime = 0;    let maxSpeed = 0;    let minSpeed = 0;    // 第一遍遍历:收集速度数据    points.forEach(point => {      index++;      if (point.totalDistance - lastDistance > interval) {        let currentSpeed = 0;        if (point.netDuration - lastTime > 0) {          currentSpeed = (point.netDistance - lastDistance) / (point.netDuration - lastTime);        }        maxSpeed = Math.max(maxSpeed, currentSpeed);        minSpeed = minSpeed === 0 ? currentSpeed : Math.min(minSpeed, currentSpeed);        lastDistance = point.netDistance;        lastTime = point.netDuration;        // 为每个间隔内的点添加相同的速度        for (let i = 0; i < index; i++) {          speedList.push(currentSpeed);        }        // 添加屏障        speedList.push(Number.MAX_VALUE);        index = 0;      }    });    // 处理剩余点    if (index > 0) {      const lastPoint = points[points.length - 1];      let currentSpeed = 0;      if (lastPoint.netDuration - lastTime > 0) {        currentSpeed = (lastPoint.netDistance - lastDistance) / (lastPoint.netDuration - lastTime);      }      for (let i = 0; i < index; i++) {        speedList.push(currentSpeed);      }    }    // 确保速度列表长度与点数一致    if (speedList.length !== points.length) {      // 调整速度列表长度      if (speedList.length > points.length) {        speedList.length = points.length;      } else {        const lastSpeed = speedList.length > 0 ? speedList[speedList.length - 1] : 0;        while (speedList.length < points.length) {          speedList.push(lastSpeed);        }      }    }    // 生成颜色列表    let lastColor = '';    let hasBarrier = false;    for (let i = 0; i < speedList.length; i++) {      const speed = speedList;      if (speed === Number.MAX_VALUE) {        hasBarrier = true;        continue;      }      const color = PathGradientTool.getAgrSpeedColorHashMap(speed, maxSpeed, minSpeed);      if (hasBarrier) {        hasBarrier = false;        if (color.toUpperCase() === lastColor.toUpperCase()) {          colorList.push(PathGradientTool.getBarrierColor(color));          continue;        }      }      colorList.push(color);      lastColor = color;    }    // 确保颜色列表长度与点数一致    if (colorList.length !== points.length) {      if (colorList.length > points.length) {        colorList.length = points.length;      } else {        const lastColor = colorList.length > 0 ? colorList[colorList.length - 1] : '#FF3032';        while (colorList.length < points.length) {          colorList.push(lastColor);        }      }    }    return colorList;  }  /**   * 根据速度定义不同的颜色区间来绘制轨迹   * @param speed 速度   * @param maxSpeed 最大速度   * @param minSpeed 最小速度   * @returns 颜色值   */  private static getAgrSpeedColorHashMap(speed: number, maxSpeed: number, minSpeed: number): string {    const range = maxSpeed - minSpeed;    if (speed
您需要登录后才可以回帖 登录 | 立即注册