C语言如何按东向西方向分析地形数组筛选符合坡度要求的跳跃位点
从东向西方向跳跃位点筛选实现方案
基础逻辑说明
- 方向定义:从东向西即固定行索引
i,列索引j从大到小遍历,每移动一格水平距离为1,坡度值直接等于两点高程差(坡度=高程差/水平距离,水平距离为1) - 阈值说明:
- 45°上升坡度对应
tan(45°)=1,要求上升段每步高程差≥0且≤1 - -80°下降坡度对应
tan(-80°)≈-5.67,要求下降段每步高程差≤-6(因高程为整数,最小差值为-6即可满足要求)
- 45°上升坡度对应
- 序列长度要求:3格上升段对应3步连续路径、2格下降段对应2步连续路径,总共需要连续6个高程点组成完整候选序列
现有代码问题
当前代码仅计算了单点高程的正切值,未考虑连续序列的坡度校验,也未区分东西方向,也没有拆分上升、下降两段的规则校验。
修改后实现代码
#include <stdio.h> #include <stdlib.h> #include <math.h> // 数组行数、列数 int length = 5, width = 6; // 规则参数:上升段步数、下降段步数、上升坡度阈值、下降坡度阈值 const int ASC_STEP = 3; const int DESC_STEP = 2; const float ASC_SLOPE_THRESHOLD = tan(45 * M_PI / 180); // 45度转弧度计算正切 const float DESC_SLOPE_THRESHOLD = tan(-80 * M_PI / 180); // -80度转弧度计算正切 struct LandData { int height; }; // 检查单个序列是否符合要求 int is_valid_jump(struct LandData *arr, int row, int start_col) { // 先检查3格上升段 for (int s = 0; s < ASC_STEP; s++) { int east_h = (arr + row * width + (start_col - s))->height; int west_h = (arr + row * width + (start_col - s - 1))->height; float slope = (west_h - east_h) / 1.0f; // 水平距离为1 if (slope < 0 || slope > ASC_SLOPE_THRESHOLD) { return 0; } } // 再检查2格下降段,起始点为上升段的最后一个点 int desc_start = start_col - ASC_STEP; for (int s = 0; s < DESC_STEP; s++) { int east_h = (arr + row * width + (desc_start - s))->height; int west_h = (arr + row * width + (desc_start - s - 1))->height; float slope = (west_h - east_h) / 1.0f; if (slope > DESC_SLOPE_THRESHOLD) { return 0; } } return 1; } struct LandData* WritingData() { struct LandData *arr = (struct LandData*)malloc(length * width * sizeof(struct LandData)); // 模拟高程数据生成,也可替换为实际数据读取 for (int i = 0; i < length ; i++) { for (int j = 0; j < width; j++) { (arr + i * width + j)->height = rand() % 10; // 输出测试数据方便核对 if (j == 0) printf("%2d| ", i); printf("%d ", (arr + i * width + j)->height); } printf("\n"); } printf("\n符合要求的跳跃起点(东端坐标 i,j):\n"); // 遍历所有行 for (int i = 0; i < length; i++) { // 列起点需要足够容纳3+2步的序列,避免越界 for (int j = width - 1; j >= ASC_STEP + DESC_STEP; j--) { if (is_valid_jump(arr, i, j)) { printf("(%d, %d)\n", i, j); } } } return arr; } int main() { struct LandData *arr = WritingData(); // 释放申请的内存 free(arr); return 0; }
代码说明
- 增加了专门的序列校验函数
is_valid_jump,分两段校验坡度是否符合要求 - 遍历列索引时限制起始值,避免数组越界访问
- 角度转弧度后再计算正切值,符合C语言
tan函数的参数要求 - 增加了内存释放逻辑,避免内存泄漏
内容的提问来源于stack exchange,提问作者Moe
相关产品推荐
相关产品推荐

