python Graham求凸包问题并画图操作
作者:sunnyorrainy 发布时间:2023-06-01 12:37:00
标签:python,Graham,凸包,画图
python Graham求凸包并画图
python写Graham没有c++那么好写,但是python画图简单。只需要用matplotlib里的pyplot,c++画图太难了。
Graham算法写起来比较简单,只需要想办法对最小点和其他的点所连成的直线,与x轴正半轴的夹角进行排序,然后其他的就直接套用Graham算法模板就好了,因为c++可以重载排序函数sort,不用计算角度(用其他的数学方法),但是python不行(也许是我不知道而已,菜)。
python必须要在结构体里面加上角度这个变量,然后才能按照角度排序。排好序后就变得容易了,用stack栈存放答案,算完答案后,用scatter(散点图)画出点,用plt(折线图)画边界就好了。
import matplotlib.pyplot as plt
import math
import numpy as np
class Node:
def __init__(self):
self.x = 0
self.y = 0
self.angel = 0
#和最左下的点连成的直线,与x轴正半轴的夹角大小
#按照角度从小到大排序
def cmp(x):
return x.angel
def bottom_point(points):
min_index = 0
n = len(points)
#先判断y坐标,找出y坐标最小的点,x坐标最小的点
for i in range(1, n):
if points[i].y < points[min_index].y or (points[i].y == points[min_index].y and
points[i].x < points[min_index].x):
min_index = i
return min_index
#计算角度
def calc_angel(vec):
norm = math.sqrt(vec[0] * vec[0] + vec[1] * vec[1])
if norm == 0:
return 0
angel = math.acos(vec[0]/norm)
if vec[1] >= 0:
return angel
else:
return math.pi * 2 - angel
def multi(v1, v2):
return v1[0] * v2[1] - v1[1] * v2[0]
point = []
n = 30
#生成30个点的坐标,n可以修改
for i in range(n):
temp = Node()
temp.x = np.random.randint(1, 100)
temp.y = np.random.randint(1, 100)
point.append(temp)
index = bottom_point(point)
for i in range(n):
if i == index:
continue
#计算每个点和point[index]所连成的直线与x轴正半轴的夹角
vector = [point[i].x - point[index].x, point[i].y - point[index].y]
#vector是向量
point[i].angel = calc_angel(vector)
#排序
point.sort(key=cmp)
#答案存入栈中
stack = []
stack.append(point[0])
stack.append(point[1])
#for循环更新答案
for i in range(2, n):
L = len(stack)
top = stack[L - 1]
next_top = stack[L - 2]
vec1 = [point[i].x - next_top.x, point[i].y - next_top.y]
vec2 = [top.x - next_top.x, top.y - next_top.y]
#一定要大于等于零,因为可能在一条直线上
while multi(vec1, vec2) >= 0:
stack.pop()
L = len(stack)
top = stack[L - 1]
next_top = stack[L - 2]
vec1 = [point[i].x - next_top.x, point[i].y - next_top.y]
vec2 = [top.x - next_top.x, top.y - next_top.y]
stack.append(point[i])
#画出图像
for p in point:
plt.scatter(p.x, p.y, marker='o', c='g')
L = len(stack)
for i in range(L-1):
plt.plot([stack[i].x, stack[i+1].x], [stack[i].y, stack[i+1].y], c='r')
plt.plot([stack[0].x, stack[L-1].x], [stack[0].y, stack[L-1].y], c='r')
plt.show()
Python 找到凸包 Convex hulls
图形学可以说经常遇到这东西了,这里给出一个库函数的实现
from scipy.spatial import ConvexHull
points = np.random.rand(10, 2) # 30 random points in 2-D
hull = ConvexHull(points)
import matplotlib.pyplot as plt
plt.plot(points[:,0], points[:,1], 'o')
for simplex in hull.simplices:
plt.plot(points[simplex,0], points[simplex,1], 'k-')
plt.show()
来源:https://blog.csdn.net/qq_43552826/article/details/104632831


猜你喜欢
- 在国内外大中型数据库管理系统中,把ORACLE作为数据库管理平台的用户比较多。RACLE 不论是数据库管理能力还是安全性都是无可非
- 本文实例讲述了python简单分割文件的方法。分享给大家供大家参考。具体如下:有的网站在上传文件时对文件大小有限制,因此可以将大文件分割成多
- str_replace — 子字符串替换 [str_replace]mixed str_replace ( mixed
- 本地一个长期更新的项目,git log突然报错:xxx@yyy:~/android/project/kernel/.git$ git log
- 必要准备你得有一个sqlserver数据库,并且要和vs项目连接。关于VS连接sqlserver数据库的教程前几天发过了,链接如下VS202
- 随着 CSS3 渐入人心,Web 字体逐渐成为话题,这种即将让未来的 Web 更加丰富多彩的技术(或者说标准)拥有多种可能,虽然 .webf
- 本文实例讲述了python网络编程socket实现服务端、客户端操作。分享给大家供大家参考,具体如下:本文内容:socket介绍TCP:服务
- Python3中二叉树前序遍历的迭代解决方案A Binary Tree二叉树是分层数据结构,其中每个父节点最多有 2 个子节点。在今天的文章
- 可以加入以下3个参数 –without-debug --with-client-ldflags=--all-static,--w
- 本文实例讲述了Python实现的质因式分解算法。分享给大家供大家参考,具体如下:本来想实现一个其它的基本数学算法问题,但是发现在实现之前必须
- 本文实例讲述了Mysql数据库高级用法之视图、事务、索引、自连接、用户管理。分享给大家供大家参考,具体如下:视图视图是对若干张基本表的引用,
- lighttpd (http://www.djangoproject.com/r/lighttpd/) 是一个轻量级的Web服务器,通常被用
- 一.先看一些最简单的例子例子Table Aaid adate 1 &n
- 功能描述:如图,右侧悬浮菜单按钮,只支持上下方向拖动,点击时展开或关闭菜单。BUG说明:鼠标上下方向拖拽,如果松开时鼠标位于悬浮按钮上会默认
- 我就废话不多说了,直接上代码吧!# -*- coding: utf-8 -*-"""Created on Sa
- 脚本架构:domain_test.py:批量解析运行主程序DomainResult.txt:域名解析结果文件domains.txt:解析的域
- 学习编写简练、优化的CSS需要大量的实践和一种不自觉的强迫性清洁的渴望。然而让你的CSS保持整洁并不仅仅是你对清洁的疯狂的心理需求,尤其对于
- 问题描述先说明一下问题的由来:Django的模型中经常会用ForeignKey来关联其他表格数据class MeasureTask(mode
- 一、打开/关闭文件1、对文件操作时首先要打开文件,打开文件用 fopen()函数,语法是:fopen(filename,mode,inclu
- 在业务稳定性要求比较高的情况下,运维为能及时发现问题,有时需要对应用程序的日志进行实时分析,当符合某个条件时就立刻报警,而不是被动等待出问题