当前位置: 首页 > news >正文

C# | 凸包算法之Jarvis,寻找一组点的边界/轮廓

在这里插入图片描述

C#实现凸包算法之Jarvis

文章目录

  • C#实现凸包算法之Jarvis
    • 前言
    • 示例代码
    • 实现思路
    • 测试结果
    • 结束语

前言

这篇关于凸包算法的文章,本文使用C#和Jarvis算法来实现凸包算法。
首先消除两个最基本的问题:

  1. 什么是凸包呢?
    凸包是一个包围一组点的凸多边形。凸多边形是指多边形中的每个内角都小于180度的多边形。
  2. 凸包算法有什么用呢?
    凸包算法的作用是找到这个凸多边形,并且使用最少的点来绘制出它的轮廓。凸包算法在计算机图形学、计算几何和机器学习等领域中有着广泛的应用。

示例代码

现在来看一下C#中的Jarvis算法是如何实现凸包算法的:

        /// <summary>/// 通过Jarvis算法获取围绕所有点的凸多边形的轮廓点<br/>/// </summary>/// <param name="points">点数组</param>/// <returns>轮廓点数组</returns>public static PointD[] GetConvexHullByJarvis(PointD[] points){if (points.Length < 3){throw new ArgumentException("凸包算法需要至少3个点");}List<PointD> pointList = new List<PointD>(points);// 找到最左边的点PointD leftmostPoint = pointList[0];for (int i = 1; i < pointList.Count; i++){if (pointList[i].X < leftmostPoint.X){leftmostPoint = pointList[i];}}// 使用栈来存储凸包的点Stack<PointD> hull = new Stack<PointD>();PointD currentPoint = leftmostPoint;do{hull.Push(currentPoint);PointD endpoint = pointList[0];for (int i = 1; i < pointList.Count; i++){if (endpoint.Equals(currentPoint) || Cross(currentPoint, endpoint, pointList[i]) < 0){endpoint = pointList[i];}}currentPoint = endpoint;pointList.Remove(currentPoint);} while (!currentPoint.Equals(leftmostPoint));return hull.ToArray();}

上面代码中定义了一个名为GetConvexHullByJarvis的静态方法,该方法接受一个PointD类型的数组作为输入参数,并返回一个PointD类型的数组,表示围绕所有点的凸多边形的轮廓点。

补充一下,关于示例中使用到的Cross方法和PointD类型的源代码如下:

        /// <summary>/// 计算从 a 到 b 再到 c 的叉积/// </summary>/// <returns>叉积值</returns>private static double Cross(PointD a, PointD b, PointD c){return (b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X);}
    public struct PointD {public PointD(double x, double y) {X = x;Y = y;}public double X { get; set; }public double Y { get; set; }public override bool Equals(object obj){if (obj == null || GetType() != obj.GetType()){return false;}PointD other = (PointD)obj;return X.Equals(other.X) && Y.Equals(other.Y);}}

实现思路

  1. 找到最左边的点,将它放入凸包中;
  2. 找到在当前点的右侧且离当前点最远的点,将它放入凸包中;
  3. 重复这个过程,直到回到最左边的点,形成一个闭合的凸多边形。

这就是 Jarvis 算法的基本思路。

需要注意的是,当点集中存在大量共线的点时,Jarvis 算法的时间复杂度可能会退化到 O(n^2) 级别,因为需要不断地扫描点集中的点来找到下一个点。此外当点集中存在大量重复的点时,Jarvis 算法可能会陷入死循环,因此需要对点集进行去重操作。


测试结果

用于测试的数据点:

        static PointD[] points = new PointD[]{   new PointD(0, 0),new PointD(0, 10),new PointD(10, 10),new PointD(10, 0),new PointD(1, 0),new PointD(4, 3),new PointD(5, 2),new PointD(6, 5),new PointD(4, 9),new PointD(4, 2),new PointD(5, 1),new PointD(6, 5),new PointD(1, 3),new PointD(7, 2),new PointD(8, 2),new PointD(6, 7),new PointD(8, 5),new PointD(9, 3),new PointD(7, 8),new PointD(8, 9),};

测试代码如下:

        [TestMethod]public void GetConvexHullByJarvis(){Console.WriteLine("Jarvis 算法");PrintPoints(ConvexHull.GetConvexHullByJarvis(points));}private void PrintPoints(PointD[] points){Console.WriteLine(points.Select(p => $"  ({p.X}, {p.Y})").Join("\r\n"));}

执行结果如下:
在这里插入图片描述


结束语

通过本章的代码可以轻松实现Jarvis算法并找到一组点最外侧的凸多边形。如果您觉得本文对您有所帮助,请不要吝啬您的点赞和评论,提供宝贵的反馈和建议,让更多的读者受益。

相关文章:

C# | 凸包算法之Jarvis,寻找一组点的边界/轮廓

C#实现凸包算法之Jarvis 文章目录 C#实现凸包算法之Jarvis前言示例代码实现思路测试结果结束语 前言 这篇关于凸包算法的文章&#xff0c;本文使用C#和Jarvis算法来实现凸包算法。 首先消除两个最基本的问题&#xff1a; 什么是凸包呢&#xff1f; 凸包是一个包围一组点的凸多…...

SpringBoot接收请求参数的方式

【方式一】原始方式 因为SpringBoot封装了Servlet&#xff0c;所以也允许使用HttpServletRequest类中的方法来获取 /*** 【方式一】原始方式*/RequestMapping("/demo01")public String demo01(HttpServletRequest request) {// 参数名要与页面提交的参数名一致Strin…...

MKS SERVO4257D 闭环步进电机_系列5 CAN指令说明

第1部分 产品介绍 MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口和RS485/CAN串行接口&#xff0c;支持MODBUS-RTU通讯协议&#xff0c;内置高效FOC矢量算法&#xff0c;采用高精度编码器&#xff0c;通过位置反馈&am…...

安捷伦E4440A(Agilent) e4440a 3HZ-26.5G频谱分析仪

Agilent E4440A、Keysight E4440A、HP E4440A频谱分析仪&#xff0c;3 Hz - 26.5 GHz&#xff08;PSA 系列&#xff09; ​Agilent / Keysight PSA 系列 E4440A 高性能频谱分析仪提供强大的一键式测量、多功能功能集和前沿技术&#xff0c;可满足您的项目和需求。选项可供您选…...

华为OD机试真题 Java 实现【最长子字符串的长度】【2022Q4 100分】,附详细解题思路

一、题目描述 给你一个字符串s,字符串s首尾相连组成一个环形,请你在环形中找出‘o’字符出现了偶数次最长子字符串的长度。 二、输入描述 输入一串小写字母组成的字符串。 三、输出描述 输出一个整数。 四、解题思路 题目要求在给定的环形字符串中找出字符’o’出现了…...

【iOS】--对象的底层结构

源码 先转一下源码 //#import <Foundation/Foundation.h> #import <objc/runtime.h>interface LGPerson : NSObject property (nonatomic, strong) NSString *KCName; endimplementation LGPersonendint main(int argc, const char * argv[]) {autoreleasepool {…...

高并发内存池设计_内存池

高并发内存池设计 1. 常用的内存操作函数2. 高性能内存池设计_弊端解决之道弊端一弊端二弊端三弊端四3. 弊端解决之道内存管理维度分析内存管理组件选型4. 高并发内存管理最佳实践内存池技术内存池如何解决弊端?高并发时内存池如何实现?5. 高效内存池设计和实现实现思路 (分而…...

给编程初学者的一封信

提醒&#xff1a;以下内容仅做参考&#xff0c;具体请自行设计。 随着信息技术的快速发展&#xff0c;编程已经成为一个越来越重要的技能。那么&#xff0c;我们该如何入门编程呢&#xff1f;欢迎大家积极讨论 一、自学编程需要注意什么&#xff1f; 要有足够的时间、精力等…...

【无功优化】基于改进教与学算法的配电网无功优化【IEEE33节点】(Matlab代码时候)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

数据在内存中的存储(超详细讲解)

目录 浮点数家族 浮点数类型在内存中的存储 一.为什么说整型和浮点数在内存中存储方式不同&#xff08;证明&#xff09; 二.浮点数的存储规则 浮点数在计算机内部的表示方法 1.对于M的存储和取出规则 2.对于E的存储和取出时的规则 对前面代码结果进行解释&#xff1a; …...

log4cplus使用示例

1、l4jlog.h封装头文件 #pragma once#include <iostream> #include <log4cplus/logger.h> #include <log4cplus/loggingmacros.h> #include <log4cplus/fileappender.h> #include <log4cplus/layout.h> #include <log4cplus/configurator.h&…...

人工智能学习07--pytorch20--目标检测:COCO数据集介绍+pycocotools简单使用

如&#xff1a;天空 coco包含pascal voc 的所有类别&#xff0c;并且对每个类别的标注目标个数也比pascal voc的多。 一般使用coco数据集预训练好的权重来迁移学习。 如果仅仅针对目标检测object80类而言&#xff0c;有些图片并没有标注信息&#xff0c;或者有错误标注信息。…...

learnOpenGL-深度测试

深度测试&#xff1a;OpenGL将一个片段的深度值与深度缓冲的内容进行对比。执行一个深度测试&#xff0c;测试通过则深度缓冲将会更新为新的深度值。测试失败则片段被丢弃。 深度测试片段着色器及模版测试之后执行。 片段着色器中内置变量gl_FragCoord的z值即为深度值。 提前深…...

阿里云服务器数据盘是什么?系统盘和数据盘区别

阿里云服务器系统盘和数据盘有什么区别&#xff1f;系统盘类似Windows电脑的C盘&#xff0c;数据盘相当于其他盘符&#xff0c;数据盘可以有多个而系统盘只能有一个&#xff0c;数据盘可有可无而云服务器系统盘是必须要有的。阿里云服务器网来详细说下阿里云服务器数据盘和系统…...

linux常用命令精选

参考文章&#xff1a; Top 60 Linux Interview Questions and Answers - howtouselinux 在管理和维护Linux系统时&#xff0c;有一些常用的命令可以帮助您进行系统初始化和配置。这些命令涵盖了各种任务&#xff0c;包括系统设置、用户管理、软件安装和网络配置等。 本文将为…...

人体行为足力特征分析及其应用研究_kaic

第一章 绪论 随着社会现代化的发展和科技的不断进步&#xff0c;我国航天事业蓬勃发展&#xff0c;与此同时产生了很多亟待解决的难题&#xff0c;康复医疗成为航天医学和康复领域的重要课题之一。载人航天实践证明&#xff0c;失重对航天员生理功能有很大影响&#xff0c;这不…...

javascript基础二十七:说说 JavaScript 数字精度丢失的问题,解决方案?

一、场景复现 一个经典的面试题 0.1 0.2 0.3 // false 为什么是false呢? 先看下面这个比喻 比如一个数 130.33333333… 这是一个除不尽的运算&#xff0c;3会一直无限循环&#xff0c;数学可以表示&#xff0c;但是计算机要存储&#xff0c;方便下次再使用&#xff0c;但…...

重塑工作场所:后疫情时代组织韧性的8个策略

经济寒冬来临&#xff0c;倒挂的收益率曲线、持续上升的利率以及层出不穷的裁员公告等等&#xff0c;让经济学家们得出一个结论&#xff1a;全球经济正在衰退。然而&#xff0c;经济下行周期可能是卓越公司改变其命运的最佳时机。有研究表明&#xff0c;相对于非经济衰退时期&a…...

TCP协议为什么要三次握手而不是两次?

TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;的历史可以追溯到1970年代初期&#xff0c;最初的版本是RFC 793&#xff0c;后来经过多次更新和改进&#xff0c;包括RFC 1122、RFC 1323、RFC 2018、RFC 2581、RFC 2873、RFC 3168和RFC 461…...

使用Vuex进行状态管理

在Vue.js应用程序中&#xff0c;状态管理是一个重要的主题。当应用程序变得复杂&#xff0c;组件之间的状态共享和通信变得困难&#xff0c;这时候使用Vuex就会变得十分有用。Vuex是一个专门为Vue.js设计的状态管理库&#xff0c;它提供了一个集中式的状态管理方案&#xff0c;…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...