热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

WPF折线/坐标点绘制LargestTriangleThreeBuckets算法

本文算法来自https:skemman.isbitstream1946153433SS_MSthesis.pdf作者对比了几个算法,主要突出的是 Largest-Triangle-

本文算法来自

https://skemman.is/bitstream/1946/15343/3/SS_MSthesis.pdf

作者对比了几个算法,主要突出的是  Largest-Triangle-Three-Buckets算法,我个人翻译为最大三点【三角】面积特征。同样作者给出了代码,我也找到了C#代码,适当改了下。主要是说说算法

主要说说几点:

1:算法的主要源于Visvalingam-Whyatt,也就是基于点与前后点形成的面积是否大于阈值,小于阈值则删除点。

   简单说一下Visvalingam-Whyatt,

  ①当节点从首位开始,连接前两个(因为是首位,没有后面),紧接着是第二点,2点连接首点,连接三点,依次向下,末位点参考首点

  ②当形成全部的三角后删除面积最小的结点,并由移至附近两点,重新形成三角形【或者从头重新连接~~】

  ③重复①,确定所有三角形的面积都小于阈值

 

2:LTTB是可以控制返回点的数量(亮点!!)

    基本操作:点集排除首尾点后的 数量与输出点的数量(同样减去首尾点,也就是-2)的比值,然后每比值的一个点集,默认第一个点是独立的一个点集,最后一个点也是独立的一个点集

      理论上第二步是选择点与下两个点集中的点所形成的最大的三角形的面积的点,实际上,算法中是 点1确定,点集3通过计算按照第几个点集,然后计算这个点集中所有的点的平均值(X,Y两个值的平均值)所创造的点,不一定存在。

     这样子就可以确定点1,点集2,然后不断筛选点集2的点,经行计算面积来比较大小。最后 依次重复上述步骤到下一个点,直至结束。

     同样,不用平均值,也可以枚举点集3与点集2的点与点1 所形成的每个三角形的面积。论文中 作者指出 差不多的效果~~(水啊????)

     最后 视觉效果上真的不错! 不过论文中说,当波峰值较大时,也有可能表现不好~

 

代码实现的步骤:

  零 初始点1为首点

  ① 计算比值(除去首尾,每个点集的数量)

  ② 计算点集3中点的平均点

  ③ 枚举点集2与点集3的平均和点1形成最大的三角形面积,并加入输出点集

  ④ 点1设置位点集2的最大面积点,并进入下一次循环步骤②

 

截图 

  WPF 折线/坐标点绘制     Largest-Triangle-Three-Buckets算法

 

 

代码 来自https://github.com/cgddrd/CSharp-LargestTriangleThreeBuckets(略微改造)

  public static List Get(List data, int threshold)
            {
                int dataLength = data.Count;
                if (threshold >= dataLength || threshold == 0)
                    return data; // Nothing to do

                List sampled = new List (threshold);

                // 点集大小,排除首尾点,阈值减2, 
                double every = (double)(dataLength - 2) / (threshold - 2);

                int a = 0;
                Point maxAreaPoint = new Point();
                int nextA = 0;

                sampled.Add(data[a]); //默认添加首点

                for (int i = 0; i 2; i++)
                {
                    // 假设第三个点是此前区间的平均值,大概率不存在,凭空捏造一个????
                    double avgX = 0;
                    double avgY = 0;
                    int avgRangeStart = (int)(((i + 1) * every) + 1);
                    int avgRangeEnd = (int)(((i + 2) * every) + 1);
                    avgRangeEnd = avgRangeEnd  avgRangeEnd : dataLength;

                    int avgRangeLength = avgRangeEnd - avgRangeStart;

                    for (; avgRangeStart )
                    {
                        avgX += data[avgRangeStart].X; // * 1 enforces Number (value may be Date)
                        avgY += data[avgRangeStart].Y;
                    }
                    avgX /= avgRangeLength;

                    avgY /= avgRangeLength;

                    // +1是为了排除当前点
                    int rangeOffs = (int)(Math.Floor((i + 0) * every) + 1);
                    int rangeTo = (int)(Math.Floor((i + 1) * every) + 1);

                    // Point a
                    double pointAx = data[a].X; // enforce Number (value may be Date)
                    double pointAy = data[a].Y;

                    double maxArea = -1;

                    for (; rangeOffs )
                    {
                        //计算面积 点1  点集2  虚拟的点3~~
                        double area = Math.Abs((pointAx - avgX) * (data[rangeOffs].Y - pointAy) -
                                               (pointAx - data[rangeOffs].X) * (avgY - pointAy)
                                          ) * 0.5;
                        if (area > maxArea)
                        {
                            maxArea = area;
                            maxAreaPoint = data[rangeOffs];
                            nextA = rangeOffs; //设置下一个点
                        }
                    }

                    sampled.Add(maxAreaPoint);  
                    a = nextA; // 进入下一次循环
                }

                sampled.Add(data[dataLength - 1]);  //默认添加尾点

                return sampled;
            }

 

   

 


推荐阅读
  • 使用Numpy实现无外部库依赖的双线性插值图像缩放
    本文介绍如何仅使用Numpy库,通过双线性插值方法实现图像的高效缩放,避免了对OpenCV等图像处理库的依赖。文中详细解释了算法原理,并提供了完整的代码示例。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 在前两篇文章中,我们探讨了 ControllerDescriptor 和 ActionDescriptor 这两个描述对象,分别对应控制器和操作方法。本文将基于 MVC3 源码进一步分析 ParameterDescriptor,即用于描述 Action 方法参数的对象,并详细介绍其工作原理。 ... [详细]
  • Coursera ML 机器学习
    2019独角兽企业重金招聘Python工程师标准线性回归算法计算过程CostFunction梯度下降算法多变量回归![选择特征](https:static.oschina.n ... [详细]
  • LeetCode 540:有序数组中的唯一元素
    来源:力扣(LeetCode),链接:https://leetcode-cn.com/problems/single-element-in-a-sorted-array。题目要求在仅包含整数的有序数组中,找到唯一出现一次的元素,并确保算法的时间复杂度为 O(log n) 和空间复杂度为 O(1)。 ... [详细]
  • QUIC协议:快速UDP互联网连接
    QUIC(Quick UDP Internet Connections)是谷歌开发的一种旨在提高网络性能和安全性的传输层协议。它基于UDP,并结合了TLS级别的安全性,提供了更高效、更可靠的互联网通信方式。 ... [详细]
  • 本文介绍如何解决在 IIS 环境下 PHP 页面无法找到的问题。主要步骤包括配置 Internet 信息服务管理器中的 ISAPI 扩展和 Active Server Pages 设置,确保 PHP 脚本能够正常运行。 ... [详细]
  • Python 异步编程:深入理解 asyncio 库(上)
    本文介绍了 Python 3.4 版本引入的标准库 asyncio,该库为异步 IO 提供了强大的支持。我们将探讨为什么需要 asyncio,以及它如何简化并发编程的复杂性,并详细介绍其核心概念和使用方法。 ... [详细]
  • Java 中 Writer flush()方法,示例 ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文详细介绍了福昕软件公司开发的Foxit PDF SDK ActiveX控件(版本5.20),并提供了关于其在64位Windows 7系统和Visual Studio 2013环境下的使用方法。该控件文件名为FoxitPDFSDKActiveX520_Std_x64.ocx,适用于集成PDF功能到应用程序中。 ... [详细]
author-avatar
穆羽默然
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有