热门标签 | 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;
            }

 

   

 


推荐阅读
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
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社区 版权所有