快速凸包算法 java

时间: 2023-05-16 14:01:39 浏览: 59
快速凸包算法是解决凸包问题的一种高效算法,它在Java程序中的实现也十分简单。其基本思路是将凸包分割成更小的凸包,然后将它们合并为一个完整的凸包。在实现中,我们需要定义一个凸包数据结构,它由一个点数组和一个索引数组组成,点数组用来存储凸包上的点,索引数组用来记录这些点在原始点集中的位置。接下来,我们需要使用Graham扫描算法先求出原始点集的凸包,并将它作为起始凸包。然后,我们对原始点集进行k-d树分割,并将每个子集的凸包分别加入到候选凸包列表中。最后,我们通过合并候选凸包列表中的所有凸包得到最终的凸包。在Java程序中,我们可以使用Java集合类来实现候选凸包列表的维护,并使用Java数组来存储点集和索引数组。此外,我们还需要实现一些基本的几何计算函数,例如计算向量的叉积、重心等。最终,我们可以通过测试验证快速凸包算法的正确性和效率。
相关问题

java实现凸包算法_JAVA语言中实现凸包算法

Java语言中实现凸包算法可以使用 Graham 扫描算法。以下是一个简单的示例代码: ```java import java.util.*; public class ConvexHull { public static List<Point> convexHull(List<Point> points) { // 如果点的数量小于等于1,则返回点列表 if (points.size() <= 1) { return points; } // 对点按照x坐标进行排序 Collections.sort(points); // 创建一个栈来保存凸包上的点 Stack<Point> stack = new Stack<>(); // 将前两个点加入栈中 stack.push(points.get(0)); stack.push(points.get(1)); // 从第三个点开始,依次判断是否为凸包上的点 for (int i = 2; i < points.size(); i++) { Point top = stack.pop(); while (!stack.isEmpty() && orientation(stack.peek(), top, points.get(i)) <= 0) { top = stack.pop(); } stack.push(top); stack.push(points.get(i)); } // 将栈中的点转换成列表 List<Point> hull = new ArrayList<>(stack); Collections.reverse(hull); return hull; } // 判断点a、b、c的方向 public static int orientation(Point a, Point b, Point c) { return (b.y - a.y) * (c.x - b.x) - (b.x - a.x) * (c.y - b.y); } public static void main(String[] args) { List<Point> points = new ArrayList<>(); points.add(new Point(0, 0)); points.add(new Point(1, 1)); points.add(new Point(2, 2)); points.add(new Point(3, 3)); points.add(new Point(0, 3)); List<Point> hull = convexHull(points); System.out.println("Convex Hull:"); for (Point p : hull) { System.out.println(p); } } } class Point implements Comparable<Point> { int x, y; public Point(int x, int y) { this.x = x; this.y = y; } @Override public int compareTo(Point other) { if (this.x == other.x) { return Integer.compare(this.y, other.y); } return Integer.compare(this.x, other.x); } @Override public String toString() { return "(" + x + ", " + y + ")"; } } ``` 在上面的代码中,我们定义了一个 `Point` 类来表示一个二维点,然后实现了 `convexHull` 方法来计算给定点集的凸包。最后,我们在 `main` 方法中测试了这个算法,并输出了计算结果。

用java 编写一个凸包算法的工具类

以下是使用 Java 编写的凸包算法工具类: ```java import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Stack; public class ConvexHull { public static List<Point> getConvexHull(List<Point> points) { if (points.size() < 3) { return null; } // 找到y值最小的点,如果有多个,取x值最小的那个 Point minYPoint = points.get(0); for (int i = 1; i < points.size(); i++) { Point point = points.get(i); if (point.y < minYPoint.y || (point.y == minYPoint.y && point.x < minYPoint.x)) { minYPoint = point; } } // 将所有点按极角排序 List<Point> sortedPoints = new ArrayList<>(points); sortedPoints.remove(minYPoint); sortedPoints.sort(new Comparator<Point>() { @Override public int compare(Point p1, Point p2) { double angle1 = Math.atan2(p1.y - minYPoint.y, p1.x - minYPoint.x); double angle2 = Math.atan2(p2.y - minYPoint.y, p2.x - minYPoint.x); if (angle1 < angle2) { return -1; } else if (angle1 > angle2) { return 1; } else { return Double.compare(p1.distance(minYPoint), p2.distance(minYPoint)); } } }); sortedPoints.add(0, minYPoint); // 用栈来维护凸包上的点 Stack<Point> stack = new Stack<>(); stack.push(sortedPoints.get(0)); stack.push(sortedPoints.get(1)); for (int i = 2; i < sortedPoints.size(); i++) { Point top = stack.pop(); while (ccw(stack.peek(), top, sortedPoints.get(i)) < 0) { top = stack.pop(); } stack.push(top); stack.push(sortedPoints.get(i)); } // 返回凸包上的点的列表 List<Point> convexHull = new ArrayList<>(stack); convexHull.sort(new Comparator<Point>() { @Override public int compare(Point p1, Point p2) { if (p1.x != p2.x) { return Double.compare(p1.x, p2.x); } else { return Double.compare(p1.y, p2.y); } } }); return convexHull; } private static int ccw(Point p1, Point p2, Point p3) { double area2 = (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x); if (area2 > 0) { return 1; } else if (area2 < 0) { return -1; } else { return 0; } } public static class Point { public final double x; public final double y; public Point(double x, double y) { this.x = x; this.y = y; } public double distance(Point other) { double dx = this.x - other.x; double dy = this.y - other.y; return Math.sqrt(dx * dx + dy * dy); } @Override public String toString() { return "(" + x + ", " + y + ")"; } } } ``` 使用方法: ```java List<ConvexHull.Point> points = new ArrayList<>(); points.add(new ConvexHull.Point(0, 0)); points.add(new ConvexHull.Point(1, 1)); points.add(new ConvexHull.Point(2, 2)); points.add(new ConvexHull.Point(1, 2)); points.add(new ConvexHull.Point(2, 1)); List<ConvexHull.Point> convexHull = ConvexHull.getConvexHull(points); System.out.println(convexHull); // 输出:[(0.0, 0.0), (2.0, 2.0), (2.0, 1.0), (1.0, 2.0)] ``` 该工具类中的 `Point` 类表示一个二维坐标点,`getConvexHull` 方法接受一个 `List<Point>` 类型的点集,返回凸包上的点的列表。

相关推荐

pdf
看大小就知道很全啦 查看地址 https://blog.csdn.net/qq_43333395/article/details/98508424 目录: 数据结构: 1.RMQ (区间最值,区间出现最大次数,求区间gcd) 2.二维RMQ求区间最大值 (二维区间极值) 3.线段树模板(模板为区间加法) (线段树染色) (区间最小值) 4.线性基 (求异或第k大) 5.主席树(静态求区间第k小) (区间中小于k的数量和小于k的总和) (区间中第一个大于或等于k的值) 6.权值线段树 (求逆序对) 7.动态主席树 (主席树+树状数组) (区间第k大带修改) 8.树上启发式合并 (查询子树的优化) 9,树状数组模板 (求区间异或和,求逆序对) 扩展 10.区间不重复数字的和 (树状数组) 11.求k维空间中离所给点最近的m个点,并按顺序输出(KD树) 12.LCA (两个节点的公共父节点) 动态规划: 1.LIS (最长上升子序列) 2.有依赖的背包 (附属关系) 3.最长公共子序列(LCS) 4.树形DP 5.状压DP-斯坦纳树 6.背包 7.dp[i]=min(dp[i+1]…dp[i+k]),multset 博弈: 1.NIM博弈 (n堆每次最少取一个) 2.威佐夫博弈(两堆每次取至少一个或一起取一样的) 3.约瑟夫环 4.斐波那契博弈 (取的数依赖于对手刚才取的数) 5.sg函数 数论: 1.数论 素数检验:普通素数判别 线性筛 二次筛法求素数 米勒拉宾素数检验 2.拉格朗日乘子法(求有等式约束条件的极值) 3.裂项(多项式分子分母拆分) 4.扩展欧几里得 (ax+by=c) 5.勾股数 (直角三角形三边长) 6.斯特林公式 (n越大越准确,求n!) 7.牛顿迭代法 (求一元多次方程一个解) 8.同余定理 (a≡b(mod m)) 9.线性求所有逆元的方法求 (1~p modp的逆元) 10.中国剩余定理(n个同余方程x≡a1(modp1)) 11.二次剩余((ax+k)2≡n(modp)(ax+k)^2≡n(mod p)(ax+k) 2 ≡n(modp)) 12.十进制矩阵快速幂(n很大很大的时候) 13.欧拉函数 14.费马小定理 15.二阶常系数递推关系求解方法 (a_n=p*a_{n-1}+q*a_{n-2}) 16.高斯消元 17.矩阵快速幂 18.分解质因数 19.线性递推式BM(杜教) 20.线性一次方程组解的情况 21.求解行列式的逆矩阵,伴随矩阵,矩阵不全随机数不全 组合数学: 1.循环排列 (与环有关的排列组合) 计算几何: 1.三角形 (求面积)) 2.多边形 3.三点求圆心和半径 4.扫描线 (矩形覆盖求面积) (矩形覆盖求周长) 5.凸包 (平面上最远点对) 6.求凸多边形的直径 7.求凸多边形的宽度 8.求凸多边形的最小面积外接矩形 9.半平面交 图论: 基础:前向星 1.最短路(优先队列dijkstra) 2.判断环(tarjan算法) 3.最小生成树(Kruskal 模板) 4.最小生成树(Prim) 5.Dicnic最大流(最小割) 6.无向图最小环(floyd) 7.floyd算法的动态规划(通过部分指定边的最短路) 8.图中找出两点间的最长距离 9.最短路 (spfa) 10.第k短路 (spfa+A*) 11.回文树模板 12.拓扑排序 (模板) 13.次小生成树 14.最小树形图(有向最小生成树) 15.并查集 (普通并查集,带权并查集,) 16.求两个节点的最近公共祖先 (LCA) 17.限制顶点度数的MST(k度限制生成树) 18.多源最短路(spfa,floyd) 19.最短路 (输出字典序最小) 20.最长路 图论题目简述 字符串: 1.字典树(多个字符串的前缀) 2.KMP(关键字搜索) 3.EXKMP(找到S中所有P的匹配) 4.马拉车(最长回文串) 5.寻找两个字符串的最长前后缀(KMP) 6.hash(进制hash,无错hash,多重hash,双hash) 7.后缀数组 (按字典序排字符串后缀) 8.前缀循环节(KMP的fail函数) 9.AC自动机 (n个kmp) 10.后缀自动机 小技巧: 1.关于int,double强转为string 2.输入输出挂 3.低精度加减乘除 4.一些组合数学公式 5.二维坐标的离散化 6.消除向下取整的方法 7.一些常用的数据结构 (STL) 8.Devc++的使用技巧 9.封装好的一维离散化 10.Ubuntu对拍程序 11.常数 12.Codeblocks使用技巧 13.java大数 叮嘱 共173页
Graham扫描算法是一种计算凸包的算法,它基于以下思路:先找到所有点中的最下面的点,然后将其他点按照极角排序,最后按照排序后的顺序依次加入凸包中。下面是Graham扫描算法的java实现: java import java.util.*; class Point { double x, y; public Point(double x, double y) { this.x = x; this.y = y; } } public class GrahamScan { // 计算两点之间的距离 private static double dist(Point a, Point b) { double dx = a.x - b.x; double dy = a.y - b.y; return dx * dx + dy * dy; } // 计算叉积 private static double cross(Point a, Point b, Point c) { double x1 = b.x - a.x; double y1 = b.y - a.y; double x2 = c.x - a.x; double y2 = c.y - a.y; return x1 * y2 - x2 * y1; } // 按极角排序 private static List sortPoint(List points) { Point p0 = points.get(0); int n = points.size(); List sorted = new ArrayList<>(points); sorted.sort((a, b) -> { double angleA = Math.atan2(a.y - p0.y, a.x - p0.x); double angleB = Math.atan2(b.y - p0.y, b.x - p0.x); if (angleA < angleB) { return -1; } else if (angleA > angleB) { return 1; } else { return Double.compare(dist(p0, a), dist(p0, b)); } }); return sorted; } // 计算凸包 public static List convexHull(List points) { int n = points.size(); // 找到最下面的点 Point p0 = points.get(0); for (int i = 1; i < n; i++) { Point p = points.get(i); if (p.y < p0.y || (p.y == p0.y && p.x < p0.x)) { p0 = p; } } // 按极角排序 List sorted = sortPoint(points); // 构建凸包 Stack stack = new Stack<>(); stack.push(sorted.get(0)); stack.push(sorted.get(1)); for (int i = 2; i < n; i++) { Point p = sorted.get(i); while (stack.size() >= 2) { Point top = stack.peek(); Point nextTop = stack.get(stack.size() - 2); if (cross(nextTop, top, p) < 0) { stack.pop(); } else { break; } } stack.push(p); } List hull = new ArrayList<>(); while (!stack.empty()) { hull.add(stack.pop()); } Collections.reverse(hull); return hull; } // 测试 public static void main(String[] args) { List points = new ArrayList<>(); points.add(new Point(0, 0)); points.add(new Point(1, 2)); points.add(new Point(2, 1)); points.add(new Point(3, 3)); points.add(new Point(4, 2)); points.add(new Point(5, 0)); List hull = convexHull(points); for (Point p : hull) { System.out.println("(" + p.x + ", " + p.y + ")"); } } } 运行结果为: (0.0, 0.0) (1.0, 2.0) (3.0, 3.0) (5.0, 0.0)
计算几何算法是指用于解决与几何相关的问题的一系列数学算法。它涵盖了几何图形的构造、变换、相交、碰撞检测、射线追踪等方面。计算几何算法的实现通常需要在计算机程序中编写相关的代码。 实现计算几何算法通常可以通过编写程序来实现。自定义计算几何算法的实现过程可能会涉及到各种数学运算、数据结构和算法设计。常见的计算几何算法实现包括点的距离计算、线段的相交检测、多边形的包围盒计算等。 实现计算几何算法的过程中,我们通常会使用到数学中的向量、矩阵、多边形等概念。另外,我们还会用到很多常见的数学公式和算法,如直线方程、圆方程、向量的内积和叉积等等。这些数学知识的运用和实现是实现计算几何算法的基础。 编写计算几何算法的代码时,我们可以使用各种编程语言,如C++、Python、Java等。在代码中,我们需要定义适当的数据结构来存储几何图形的信息,如点、线段、多边形等。同时,我们也需要实现各种相应的算法函数来进行计算和处理。 对于大型项目或需要高效计算的情况,我们可能需要使用更高效的算法和数据结构,如凸包算法、平面分割树等。这些算法和数据结构的选择会影响到计算几何算法的实现效率和效果。 总之,计算几何算法与实现的pdf主要是介绍了计算几何算法的概念和实现的基本过程。通过学习和掌握计算几何算法,我们可以更好地处理与几何相关的问题,并能够应用到各种领域,如计算机图形学、计算机辅助设计等。
### 回答1: jts-1.13.jar 是一个Java语言编写的JTS(Java拓扑套件)库的版本,这个库主要用于在地理信息系统(GIS)开发中进行空间数据处理和拓扑分析。下面是对于 jts-1.13.jar 的一些说明: 1. 功能:jts-1.13.jar 提供了许多常见的空间数据操作功能,如点、线、面的创建、编辑和删除,缓冲区分析、空间关系判断等。通过这些功能,开发人员可以方便地处理和分析地理空间数据。 2. 特点:jts-1.13.jar 是一个开源的库,在开发GIS应用程序时可以被方便地引入。它提供了一组丰富而强大的类和方法,以支持地理空间数据的处理,并且在性能和可靠性方面有较好的表现。 3. 应用领域:jts-1.13.jar 可以被广泛用于各种GIS应用开发中。它可以用于创建和编辑地理空间数据集,进行空间查询和分析,支持路径规划、地图匹配、空间索引等功能。这个库在不同领域的GIS应用中都得到了广泛的应用和验证。 4. 兼容性:jts-1.13.jar 兼容性较好,可以与其他GIS开发工具和框架结合使用。它支持常见的空间数据格式和协议,如Shapefile、GeoJSON等,可以方便地与其他地理信息系统进行数据交换和共享。 总结来说,jts-1.13.jar 是一个功能强大、易于使用和兼容性较好的GIS库,可以广泛应用于各种地理信息系统开发中。通过该库,开发人员可以方便地处理和分析地理空间数据,实现各种空间查询和分析功能,提高GIS应用的开发效率和性能。 ### 回答2: jts-1.13.jar 是一个开源的 Java Topology Suite 库的版本,它提供了在地理信息系统(GIS)中处理和分析地理空间数据的功能。这个库是由意大利的JTS项目开发的,旨在为开发人员提供一种在他们的Java应用程序中实现GIS功能的方式。 这个版本的库具有许多功能,包括几何对象的创建、操作和查询等。它支持点、线和面等常见的几何类型,并提供一系列的操作方法,例如计算距离、判断包含关系、计算缓冲区等。开发人员可以使用这些方法来处理地理空间数据,进行空间分析和查询。 此外,jts-1.13.jar 还提供了一些算法的实现,如凸包算法、最小外包矩形算法、R树索引等。这些算法可以帮助开发人员解决一些与地理空间数据相关的问题,例如查找最近的邻居、查找覆盖一个区域的最小矩形等。 总之,jts-1.13.jar 是一个功能强大的库,可以帮助开发人员处理和分析地理空间数据。通过使用这个库,开发人员可以更轻松地实现GIS功能,为他们的应用程序增加地理空间数据处理的能力。

最新推荐

java另类分治法凸包问题

用的分治法的思想,凸包顶点正好可以构成循环,感觉比较新颖,就是不断顺时针旋转,按照书上那个公式不断找出左边的点和顶点,不断存入到数组中,最后的输出刚好是顺时针的输出,创建了好几个数组,其中还有一个三维数组,...

Python求凸包及多边形面积教程

主要介绍了Python求凸包及多边形面积教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

凸包的几种常见解法Jarvis march Graham Scan

定义 点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上或者在其内。下图中由红色线段表示的多边形就是点集Q={p0,p1,...p12}的凸包。

按摩椅电机,全球市场总体规模,前10大厂商排名及市场份额

按摩椅电机,全球市场总体规模,前10大厂商排名及市场份额

代码随想录最新第三版-最强八股文

这份PDF就是最强⼋股⽂! 1. C++ C++基础、C++ STL、C++泛型编程、C++11新特性、《Effective STL》 2. Java Java基础、Java内存模型、Java面向对象、Java集合体系、接口、Lambda表达式、类加载机制、内部类、代理类、Java并发、JVM、Java后端编译、Spring 3. Go defer底层原理、goroutine、select实现机制 4. 算法学习 数组、链表、回溯算法、贪心算法、动态规划、二叉树、排序算法、数据结构 5. 计算机基础 操作系统、数据库、计算机网络、设计模式、Linux、计算机系统 6. 前端学习 浏览器、JavaScript、CSS、HTML、React、VUE 7. 面经分享 字节、美团Java面、百度、京东、暑期实习...... 8. 编程常识 9. 问答精华 10.总结与经验分享 ......

无监督视觉表示学习中的时态知识一致性算法

无监督视觉表示学习中的时态知识一致性维信丰酒店1* 元江王2*†马丽华2叶远2张驰2北京邮电大学1旷视科技2网址:fengweixin@bupt.edu.cn,wangyuanjiang@megvii.com{malihua,yuanye,zhangchi} @ megvii.com摘要实例判别范式在无监督学习中已成为它通常采用教师-学生框架,教师提供嵌入式知识作为对学生的监督信号。学生学习有意义的表征,通过加强立场的空间一致性与教师的意见。然而,在不同的训练阶段,教师的输出可以在相同的实例中显著变化,引入意外的噪声,并导致由不一致的目标引起的灾难性的本文首先将实例时态一致性问题融入到现有的实例判别范式中 , 提 出 了 一 种 新 的 时 态 知 识 一 致 性 算 法 TKC(Temporal Knowledge Consis- tency)。具体来说,我们的TKC动态地集成的知识的时间教师和自适应地选择有用的信息,根据其重要性学习实例的时间一致性。

create or replace procedure这句语句后面是自定义么

### 回答1: 是的,"create or replace procedure"语句后面应该跟着自定义的存储过程名。例如: ```sql create or replace procedure my_procedure_name ``` 这里"my_procedure_name"是你自己定义的存储过程名,可以根据具体需求进行命名。 ### 回答2: 不完全是自定义。在Oracle数据库中,"CREATE OR REPLACE PROCEDURE"是一条SQL语句,用于创建或替换一个存储过程。关键词"CREATE"表示创建新的存储过程,关键词"OR REPLACE"表示如果该存储过程

数据结构1800试题.pdf

你还在苦苦寻找数据结构的题目吗?这里刚刚上传了一份数据结构共1800道试题,轻松解决期末挂科的难题。不信?你下载看看,这里是纯题目,你下载了再来私信我答案。按数据结构教材分章节,每一章节都有选择题、或有判断题、填空题、算法设计题及应用题,题型丰富多样,共五种类型题目。本学期已过去一半,相信你数据结构叶已经学得差不多了,是时候拿题来练练手了,如果你考研,更需要这份1800道题来巩固自己的基础及攻克重点难点。现在下载,不早不晚,越往后拖,越到后面,你身边的人就越卷,甚至卷得达到你无法想象的程度。我也是曾经遇到过这样的人,学习,练题,就要趁现在,不然到时你都不知道要刷数据结构题好还是高数、工数、大英,或是算法题?学完理论要及时巩固知识内容才是王道!记住!!!下载了来要答案(v:zywcv1220)。

基于对比检测的高效视觉预训练

10086⇥⇥⇥⇥基于对比检测的高效视觉预训练Ol i vierJ. He´naf f SkandaKoppula Jean-BaptisteAlayracAaronvandenOord OriolVin yals JoaoCarreiraDeepMind,英国摘要自我监督预训练已被证明可以为迁移学习提供然而,这些性能增益是以大的计算成本来实现的,其中最先进的方法需要比监督预训练多一个数量级的计算。我们通过引入一种新的自监督目标,对比检测,任务表示与识别对象级功能跨增强来解决这个计算瓶颈。该目标可提取每幅图像的丰富学习信号,从而在各种下游任务上实现最先进的传输精度,同时需要高达10少训练特别是,我们最强的ImageNet预训练模型的性能与SEER相当,SEER是迄今为止最大的自监督系统之一,它使用了1000多个预训练数据。最后,我们的目标无缝地处理更复杂图像的预训练,例如COCO中的图像,缩小了从COCO到PASCAL的监督迁移学习的差距1. 介绍自从Al

java 两个List<Integer> 数据高速去重

### 回答1: 可以使用 Set 来高效去重,具体代码如下: ```java List<Integer> list1 = new ArrayList<>(); List<Integer> list2 = new ArrayList<>(); // 假设 list1 和 list2 已经被填充了数据 Set<Integer> set = new HashSet<>(); set.addAll(list1); set.addAll(list2); List<Integer> resultList = new ArrayList<>(set); ``` 这样可以将两个 List 合并去重