这是我使用的纯Python O(n)实现:

import math

"""

Minimal Enclosing Parallelogram

area, v1, v2, v3, v4 = mep(convex_polygon)

convex_polygon - array of points. Each point is a array [x, y] (1d array of 2 elements)

points should be presented in clockwise order.

the algorithm used is described in the following paper:

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.53.9659&rep=rep1&type=pdf

"""

def distance(p1, p2, p):

return abs(((p2[1]-p1[1])*p[0] - (p2[0]-p1[0])*p[1] + p2[0]*p1[1] - p2[1]*p1[0]) /

math.sqrt((p2[1]-p1[1])**2 + (p2[0]-p1[0])**2))

def antipodal_pairs(convex_polygon):

l = []

n = len(convex_polygon)

p1, p2 = convex_polygon[0], convex_polygon[1]

t, d_max = None, 0

for p in range(1, n):

d = distance(p1, p2, convex_polygon[p])

if d > d_max:

t, d_max = p, d

l.append(t)

for p in range(1, n):

p1, p2 = convex_polygon[p % n], convex_polygon[(p+1) % n]

_p, _pp = convex_polygon[t % n], convex_polygon[(t+1) % n]

while distance(p1, p2, _pp) > distance(p1, p2, _p):

t = (t + 1) % n

_p, _pp = convex_polygon[t % n], convex_polygon[(t+1) % n]

l.append(t)

return l

# returns score, area, points from top-left, clockwise , favouring low area

def mep(convex_polygon):

def compute_parallelogram(convex_polygon, l, z1, z2):

def parallel_vector(a, b, c):

v0 = [c[0]-a[0], c[1]-a[1]]

v1 = [b[0]-c[0], b[1]-c[1]]

return [c[0]-v0[0]-v1[0], c[1]-v0[1]-v1[1]]

# finds intersection between lines, given 2 points on each line.

# (x1, y1), (x2, y2) on 1st line, (x3, y3), (x4, y4) on 2nd line.

def line_intersection(x1, y1, x2, y2, x3, y3, x4, y4):

px = ((x1*y2 - y1*x2)*(x3 - x4) - (x1 - x2)*(x3*y4 - y3*x4))/((x1-x2)*(y3-y4) - (y1-y2)*(x3-x4))

py = ((x1*y2 - y1*x2)*(y3 - y4) - (y1 - y2)*(x3*y4 - y3*x4))/((x1-x2)*(y3-y4) - (y1-y2)*(x3-x4))

return px, py

# from each antipodal point, draw a parallel vector,

# so ap1->ap2 is parallel to p1->p2

# aq1->aq2 is parallel to q1->q2

p1, p2 = convex_polygon[z1 % n], convex_polygon[(z1+1) % n]

q1, q2 = convex_polygon[z2 % n], convex_polygon[(z2+1) % n]

ap1, aq1 = convex_polygon[l[z1 % n]], convex_polygon[l[z2 % n]]

ap2, aq2 = parallel_vector(p1, p2, ap1), parallel_vector(q1, q2, aq1)

a = line_intersection(p1[0], p1[1], p2[0], p2[1], q1[0], q1[1], q2[0], q2[1])

b = line_intersection(p1[0], p1[1], p2[0], p2[1], aq1[0], aq1[1], aq2[0], aq2[1])

d = line_intersection(ap1[0], ap1[1], ap2[0], ap2[1], q1[0], q1[1], q2[0], q2[1])

c = line_intersection(ap1[0], ap1[1], ap2[0], ap2[1], aq1[0], aq1[1], aq2[0], aq2[1])

s = distance(a, b, c) * math.sqrt((b[0]-a[0])**2 + (b[1]-a[1])**2)

return s, a, b, c, d

z1, z2 = 0, 0

n = len(convex_polygon)

# for each edge, find antipodal vertice for it (step 1 in paper).

l = antipodal_pairs(convex_polygon)

so, ao, bo, co, do, z1o, z2o = 100000000000, None, None, None, None, None, None

# step 2 in paper.

for z1 in range(0, n):

if z1 >= z2:

z2 = z1 + 1

p1, p2 = convex_polygon[z1 % n], convex_polygon[(z1+1) % n]

a, b, c = convex_polygon[z2 % n], convex_polygon[(z2+1) % n], convex_polygon[l[z2 % n]]

if distance(p1, p2, a) >= distance(p1, p2, b):

continue

while distance(p1, p2, c) > distance(p1, p2, b):

z2 += 1

a, b, c = convex_polygon[z2 % n], convex_polygon[(z2+1) % n], convex_polygon[l[z2 % n]]

st, at, bt, ct, dt = compute_parallelogram(convex_polygon, l, z1, z2)

if st < so:

so, ao, bo, co, do, z1o, z2o = st, at, bt, ct, dt, z1, z2

return so, ao, bo, co, do, z1o, z2o

python画平行四边形_Python中最小的封闭平行四边形相关推荐

  1. python画热力图_Python中绘制场景热力图

    原博文 2019-08-06 15:39 − 我们在做诸如人群密集度等可视化的时候,可能会考虑使用热力图,在Python中能很方便地绘制热力图. 下面以识别图片中的行人,并绘制热力图为例进行讲解. 步 ...

  2. python画对数函数_python中对数函数怎么表示

    log() 返回 x 的自然对数.math.log(x) 就相当于数学中的ln(x),x>0,求底数为e的对数,e = 2.718281828459:math.log10(x) 就相当于数学中的 ...

  3. python画松树_Python中的Phyllotaxis模式| 算法植物学的一个单位

    简介| 叶底 Phyllotaxis / phyllotaxy是植物茎上叶子的排列,Phyllotactic螺旋形成自然界中独特的一类模式.这个词本身来自希腊语phullon,意思是"叶子& ...

  4. 如何用python画饼图_Python中的五颜六色的饼状图!(一)

    [1x00]方法描述 matplotlib.pyplot.pie() 方法用于绘制饼状图. 基本语法:matplotlib.pyplot.pie( x[, explode=None, labels=N ...

  5. python画矢量场_Python中的图像渐变矢量场

    我试图使用 Python获取 Gradient Vector Field的图像(类似于 this matlab question). 这是原始图片: 这是我的代码: import numpy as n ...

  6. python怎么画人像_教你如何用Python画出心目中的自己

    原标题:教你如何用Python画出心目中的自己 引言:人脸图像的生成在各个行业有着重要应用,例如刑事调查.人物设计.教育培训等.然而一幅逼真的人脸肖像,对于职业画家也要至少数小时才能绘制出来:对于从未 ...

  7. python绘制对数函数_python中如何画对数函数图?

    小伙伴们还记不记得,在高考数学题后面的大题总会出现对数函数,需要我们画成对数函数图才能解答.之前小编向大家介绍对数log函数的表示方法(https://www.py.cn/jishu/jichu/21 ...

  8. python画树干_python教你画一棵树

    最近不少读者对 python 的 turtle 库比较感兴趣, 用python画一朵玫瑰给你 ,之前也写了一篇文章讲过如何画一朵玫瑰花.今天在知乎上找了一个用 turtle 画树的 python 程序 ...

  9. 怎么用python画直线_python怎么画直线

    python怎么画直线,画布,画图,创建一个,函数,对象 python怎么画直线 易采站长站,站长之家为您整理了python怎么画直线的相关内容. Tkinter是Python的标准 GUI 库.Py ...

  10. python销毁线程_Python 中的线程

    封面图片来源:沙沙野 线程线程与进程的联系:都是为了解决并发 线程与进程的区别:进程:计算机中最小的资源分配单位 线程:进程中的一员,同一个进程之间的几个线程共享一个进程的资源 线程可以直接被CPU调 ...

最新文章

  1. Elastic Job从单点到高可用、同城主备、同城双活
  2. Webots ROS
  3. 用户稿件 | 好家伙,到底谁在用TBtools?
  4. 从狭隘到自我设限,再到自我解放.
  5. QT的QLatin1String类的使用
  6. HTTP RTSP RTMP RTP 协议简说 流媒体学习(一)
  7. 如何正确的使用微信公众号
  8. java js websocket_js+java websocket记录
  9. python实现决策树归纳_决策树【python实现】
  10. 认识容器,我们从它的历史开始聊起
  11. jwt token注销_退出登录时怎样实现JWT Token失效?
  12. android bitmap 替换指定颜色,Android 实现把bitmap图片的某一部分的颜色改成其他颜色...
  13. ArcGIS地形图配准并生成三维模型(附练习数据下载)
  14. itunes安装后不能用,双击后等很长时间,提示:ITUNES 驱动程序缺少用于导入和刻录的CD与DVD注册的设置...
  15. 常用公差配合表图_机械密封零件的公差配合与技术要求
  16. 2021美团Java面试真题解析(含参考答案)
  17. 安装proteus8和卸载
  18. Android-第九节网络编程
  19. android微信下拉页面,Android仿微信下拉列表实现
  20. Kafka组消费之Rebalance机制

热门文章

  1. idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制
  2. matlab设计误码率,通信原理课程设计报告 数字传输系统误码率测试器的matlab实现及性能分析...
  3. Google Chrome 插件推荐
  4. 关于打开github网站慢如何解决
  5. 27个常用stata命令(2)
  6. linux 系统gbk字符集,linux 修改字符集gbk
  7. ogg是什么文件?ogg怎么转mp3格式?
  8. Ceres-Solver
  9. 微信支付接口操作说明
  10. Go优雅的重启服务之endless库