Browse Source

优化去重算法

wangyingjie 3 weeks ago
parent
commit
c38fa37ebd
2 changed files with 74 additions and 27 deletions
  1. 45 26
      line_vacuate/studio_geo_algo_c.c
  2. 29 1
      line_vacuate/studio_geo_algo_c.h

+ 45 - 26
line_vacuate/studio_geo_algo_c.c

@@ -1,16 +1,15 @@
 /**
-  ******************************************************************************
-  * @file           : studio_geo_algo_c.c
-  * @author         : wangyingjie
-  * @brief          : None
-  * @attention      : None
-  * @date           : 2025/5/11
-  ******************************************************************************
-  */
+ ******************************************************************************
+ * @file           : studio_geo_algo_c.c
+ * @author         : wangyingjie
+ * @brief          : None
+ * @attention      : None
+ * @date           : 2025/5/11
+ ******************************************************************************
+ */
 
 #include "studio_geo_algo_c.h"
 
-
 double point_line_dist_square_c(const studio_point_c *p, const studio_point_c *start, const studio_point_c *end)
 {
     double A = p->x - start->x;
@@ -84,33 +83,53 @@ void douglas_peucker_c(const studio_line_c *points, size_t start, size_t end, do
     }
 }
 
-void remove_duplicates(unsigned int **indices, unsigned int *size) {
-    if (*size == 0) return;
-    // 临时数组用于存储去重后的数据
+
+unsigned int hash(unsigned int value, unsigned int size)
+{
+    return value % size;
+}
+
+void remove_duplicates(unsigned int **indices, unsigned int *size)
+{
+    if (*size == 0)
+    {
+        return;
+    }
+
     unsigned int *unique_indices = (unsigned int *)malloc(*size * sizeof(unsigned int));
     unsigned int unique_count = 0;
-    for (unsigned int i = 0; i < *size; i++) {
-        unsigned int is_duplicate = 0;
-        // 检查当前元素是否已经在 unique_indices 中
-        for (unsigned int j = 0; j < unique_count; j++) {
-            if ((*indices)[i] == unique_indices[j]) {
-                is_duplicate = 1;
-                break;
-            }
-        }
-        // 如果没有重复,添加到 unique_indices
-        if (!is_duplicate) {
-            unique_indices[unique_count] = (*indices)[i];
-            unique_count++;
+
+    // 创建一个哈希表
+    unsigned int hash_table_size = *size * 4; // 哈希表大小可以稍微增大以减少冲突 这个可能有问题
+    bool *hash_table = (bool *)malloc(hash_table_size * sizeof(bool));
+    for (unsigned int i = 0; i < hash_table_size; i++)
+    {
+        hash_table[i] = false; // 初始化哈希表
+    }
+
+    for (unsigned int i = 0; i < *size; i++)
+    {
+        unsigned int current_value = (*indices)[i];
+        unsigned int hash_index = hash(current_value, hash_table_size);
+
+        // 检查该元素是否已经在哈希表中
+        if (!hash_table[hash_index])
+        {
+            hash_table[hash_index] = true;
+            unique_indices[unique_count++] = current_value;
         }
     }
-    // 释放原有的 indices
+
+    // 释放原有的 indices 和哈希表
     free(*indices);
+    free(hash_table);
+
     // 更新 indices 指针和大小
     *indices = unique_indices;
     *size = unique_count;
 }
 
+
 bool line_vacuate_c(const studio_line_c *line, const int max_points, const double epsilon, studio_line_c *vacuate_line)
 {
     // 初始化状态变量

+ 29 - 1
line_vacuate/studio_geo_algo_c.h

@@ -15,11 +15,39 @@
 
 /////////////////// 矢量(线)抽稀算法 ///////////////////
 
+/// 计算点到线段的距离的平方
+/// \param p 点
+/// \param start 线段起点
+/// \param end 线段终点
+/// \return 距离的平方
 double point_line_dist_square_c(const studio_point_c *p, const studio_point_c *start, const studio_point_c *end);
 
-// Douglas-Peucker算法,用于简化多边形或曲线
+/// Douglas-Peucker算法,线段压缩
+/// \param points 线段
+/// \param start 线段起点索引
+/// \param end 线段终点索引
+/// \param epsilon 抽稀容差,若某点到当前线段的最大垂直距离超过epsilon,则保留该点,单位与适量坐标系的单位一致
+/// \param indices 存储简化后的点索引
+/// \param index_count 存储简化后的点索引数量
 void douglas_peucker_c(const studio_line_c *points, size_t start, size_t end, double epsilon, unsigned int *indices, unsigned int *index_count);
 
+/// 矢量线段抽稀算法
+/// \param line 线段
+/// \param max_points 压缩后最大点
+/// \param epsilon 抽稀容差,若某点到当前线段的最大垂直距离超过epsilon,则保留该点,单位与适量坐标系的单位一致
+/// \param vacuate_line 抽稀后的线段
+/// \return
 bool line_vacuate_c(const studio_line_c *line, const int max_points, const double epsilon, studio_line_c *vacuate_line);
 
+/// 计算哈希值
+/// \param value
+/// \param size
+/// \return
+unsigned int hash(unsigned int value, unsigned int size);
+
+/// 移除重复点 保持原有顺序
+/// \param indices 点索引
+/// \param size 点索引数量
+void remove_duplicates(unsigned int **indices, unsigned int *size);
+
 #endif  // STUDIO_GEO_ALGO_C_H