尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

mark 增量式 Douglas-Peucker 算法

mark 增量式 Douglas-Peucker 算法
📅 发布时间:2026/6/18 21:32:39

mark 增量式 Douglas-Peucker 算法

use egui::Pos2;


struct IncrementalSimplifier {
simplified: Vec<Pos2>, // 简化后的关键节点
buffer: Vec<Pos2>, // 缓存新增的临时点
epsilon: f32, // 误差阈值
buffer_limit: usize, // 缓存点数量上限
}

impl IncrementalSimplifier {
fn feed(&mut self, new_point: Pos2) {
self.buffer.push(new_point);

// 缓存点达到上限时触发局部简化
if self.buffer.len() >= self.buffer_limit {
self.simplify_buffer();
}
}

fn simplify_buffer(&mut self) {
if self.buffer.is_empty() {
return;
}
// 以简化集的最后一个点和缓存的第一个点为起点,局部应用Douglas-Peucker
let start = self.simplified.last().copied().unwrap_or(self.buffer[0]);
let mut local_points = vec![start];
local_points.extend(self.buffer.drain(..));

let local_simplified = douglas_peucker(&local_points, self.epsilon);
// 合并结果(排除重复的起点)
self.simplified.pop();
self.simplified.extend(local_simplified);
}
}

/// 计算点 p 到线段 (a, b) 的垂直距离
fn distance_point_to_segment(p: Pos2, a: Pos2, b: Pos2) -> f32 {
if a == b {
return (p - a).length(); // 线段为点时,直接返回两点距离
}

// 向量 AB 和 AP
let ab = b - a;
let ap = p - a;

// 计算 AP 在 AB 上的投影比例( clamp 到 [0, 1] 确保在 segment 上)
let t = ap.dot(ab) / ab.dot(ab);
let t = t.clamp(0.0, 1.0);

// 投影点
let projection = a + ab * t;

// 点到投影点的距离
(p - projection).length()
}

/// Douglas-Peucker 算法简化点集
fn douglas_peucker(points: &[Pos2], epsilon: f32) -> Vec<Pos2> {
if points.len() <= 2 {
return points.to_vec(); // 少于 2 个点直接返回
}

let start = 0;
let end = points.len() - 1;
let a = points[start];
let b = points[end];

// 找到最远点
let mut max_dist = 0.0;
let mut max_idx = 0;
for (i, &p) in points.iter().enumerate().take(end).skip(start + 1) {
let dist = distance_point_to_segment(p, a, b);

// 递归简化
if max_dist > epsilon {
let mut left = douglas_peucker(&points[start..=max_idx], epsilon);
let mut right = douglas_peucker(&points[max_idx..=end], epsilon);
left.pop(); // 移除重复的 max_idx 点
left.extend(right);
left
} else {
vec![a, b] // 保留起点和终点
}
}

// 示例用法
fn main() {
// 原始点集(模拟一条曲线)
let original_points = vec![
Pos2::new(0.0, 0.0),
Pos2::new(1.0, 1.0),
Pos2::new(2.0, 0.5),
Pos2::new(3.0, 2.0),
Pos2::new(4.0, 2.0),
Pos2::new(5.0, 2.0),
Pos2::new(6.0, 2.0),
Pos2::new(7.0, 1.0),
Pos2::new(8.0, 1.0),
Pos2::new(9.0, 1.0),
Pos2::new(10.0, 1.0),
Pos2::new(11.0, 3.0),
Pos2::new(12.0, 3.0),
Pos2::new(13.0, 3.0),
Pos2::new(14.0, 3.0),
];

// 简化(阈值 ε=0.5)
let simplified = douglas_peucker(&original_points, 0.5);

println!("原始点集: {:?}", original_points);
println!("简化后: {:?}", simplified);
}


-------------====================分割线====================-------------

作者:戳人痛处

本博客link:https://www.cnblogs.com/hardfood/p/19152079

硬币,懂?

https://space.bilibili.com/68973181

相关新闻

  • 2025年10月高端奢侈家电品牌推荐排行榜及深度对比
  • 2025年10月高端奢侈家电品牌推荐排行榜:五大品牌综合对比与选购
  • 基于Qt框架实现绘图软件的功能

最新新闻

  • o3-mini作为工程协作者的ML项目落地实践
  • ONNX工程化落地:从模型转换到边缘部署的全链路实践
  • 5个鼠标魔法技巧:让普通鼠标在macOS上超越苹果触控板的完整指南
  • windows权限划分
  • OpenSpeedy:3分钟学会使用开源游戏加速工具,告别卡顿延迟
  • DeepSeek效率革命:大模型推理优化与工程化落地实践

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号