找回密码
 立即注册
搜索
查看: 654|回复: 0

使用单位矢量平均法计算平均风向

[复制链接]

3

主题

190

回帖

433

积分

热带低压

积分
433
发表于 2024-8-6 19:40 | 显示全部楼层 |阅读模式
本帖最后由 浅冰Column 于 2024-8-25 17:33 编辑

搭建志愿站的过程中,查询国标得知计算平均风向需要采用单位矢量平均法。
网上关于该问题的帖子稀少,特用 LaTeX 整理公式和几种主要语言的实例代码,供各位使用。




公式

需要 LaTex 公式的朋友可以查看我的博客(https://blog.birdbird.fun/archives/63),因为论坛没有 LaTex,此处公式提供图片。






代码

1. Python
  1. import math

  2. # 单位矢量平均法计算平均风向
  3. def calculate_average_wind_direction(wind_directions):
  4.     # 转为弧度制
  5.     wind_directions_rad = [math.radians(d) for d in wind_directions]

  6.     # 计算平均值
  7.     X_avg = sum(math.sin(d) for d in wind_directions_rad) / len(wind_directions)
  8.     Y_avg = sum(math.cos(d) for d in wind_directions_rad) / len(wind_directions)

  9.     # 计算风向平均值的弧度
  10.     average_wind_direction_rad = math.atan2(X_avg, Y_avg)

  11.     # 转回角度制
  12.     average_wind_direction_deg = math.degrees(average_wind_direction_rad)

  13.     # 出界修正
  14.     if average_wind_direction_deg < 0:
  15.         average_wind_direction_deg += 360

  16.     return average_wind_direction_deg
复制代码

2. C++
  1. #include <vector>
  2. #include <cmath>
  3. #include <numeric>

  4. double calculate_average_wind_direction(const std::vector<double>& wind_directions) {
  5.     // 转为弧度制
  6.     std::vector<double> wind_directions_rad;
  7.     wind_directions_rad.reserve(wind_directions.size());
  8.     for (double d : wind_directions) {
  9.         wind_directions_rad.push_back(d * M_PI / 180.0);
  10.     }

  11.     // 计算平均值
  12.     double X_avg = std::accumulate(wind_directions_rad.begin(), wind_directions_rad.end(), 0.0,
  13.         [](double sum, double d) { return sum + std::sin(d); }) / wind_directions.size();

  14.     double Y_avg = std::accumulate(wind_directions_rad.begin(), wind_directions_rad.end(), 0.0,
  15.         [](double sum, double d) { return sum + std::cos(d); }) / wind_directions.size();

  16.     // 计算风向平均值的弧度
  17.     double average_wind_direction_rad = std::atan2(X_avg, Y_avg);

  18.     // 转回角度制
  19.     double average_wind_direction_deg = average_wind_direction_rad * 180.0 / M_PI;

  20.     // 出界修正
  21.     if (average_wind_direction_deg < 0) {
  22.         average_wind_direction_deg += 360.0;
  23.     }

  24.     return average_wind_direction_deg;
  25. }
复制代码

3. C#
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;

  4. public class WindDirectionCalculator
  5. {
  6.     public static double CalculateAverageWindDirection(List<double> windDirections)
  7.     {
  8.         // 转为弧度制
  9.         var windDirectionsRad = windDirections.Select(d => d * Math.PI / 180.0).ToList();

  10.         // 计算平均值
  11.         double X_avg = windDirectionsRad.Select(d => Math.Sin(d)).Average();
  12.         double Y_avg = windDirectionsRad.Select(d => Math.Cos(d)).Average();

  13.         // 计算风向平均值的弧度
  14.         double averageWindDirectionRad = Math.Atan2(X_avg, Y_avg);

  15.         // 转回角度制
  16.         double averageWindDirectionDeg = averageWindDirectionRad * 180.0 / Math.PI;

  17.         // 出界修正
  18.         if (averageWindDirectionDeg < 0)
  19.         {
  20.             averageWindDirectionDeg += 360.0;
  21.         }

  22.         return averageWindDirectionDeg;
  23.     }
  24. }
复制代码

4. Java
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;

  4. public class WindDirectionCalculator
  5. {
  6.     public static double CalculateAverageWindDirection(List<double> windDirections)
  7.     {
  8.         // 转为弧度制
  9.         var windDirectionsRad = windDirections.Select(d => d * Math.PI / 180.0).ToList();

  10.         // 计算平均值
  11.         double X_avg = windDirectionsRad.Select(d => Math.Sin(d)).Average();
  12.         double Y_avg = windDirectionsRad.Select(d => Math.Cos(d)).Average();

  13.         // 计算风向平均值的弧度
  14.         double averageWindDirectionRad = Math.Atan2(X_avg, Y_avg);

  15.         // 转回角度制
  16.         double averageWindDirectionDeg = averageWindDirectionRad * 180.0 / Math.PI;

  17.         // 出界修正
  18.         if (averageWindDirectionDeg < 0)
  19.         {
  20.             averageWindDirectionDeg += 360.0;
  21.         }

  22.         return averageWindDirectionDeg;
  23.     }
  24. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|TY_Board论坛

GMT+8, 2024-9-19 09:31 , Processed in 0.057395 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表