广告位联系
返回顶部
分享到

基于Python实现绘制一个足球

python 来源:互联网 作者:佚名 发布时间:2023-02-26 11:57:45 人浏览
摘要

前情提要 如果想优雅地绘制一个足球,那首先需要绘制正二十面体:用Python绘制正二十面体 其核心代码为 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import nu

前情提要

如果想优雅地绘制一个足球,那首先需要绘制正二十面体:用Python绘制正二十面体

其核心代码为

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

import numpy as np

from itertools import product

G = (np.sqrt(5)-1)/2

def getVertex():

    pt2 =  [(a,b) for a,b in product([1,-1], [G, -G])]

    pts =  [(a,b,0) for a,b in pt2]

    pts += [(0,a,b) for a,b in pt2]

    pts += [(b,0,a) for a,b in pt2]

    return np.array(pts)

 

def getDisMat(pts):

    N = len(pts)

    dMat = np.ones([N,N])*np.inf

    for i in range(N):

        for j in range(i):

            dMat[i,j] = np.linalg.norm([pts[i]-pts[j]])

    return dMat

 

pts = getVertex()

dMat = getDisMat(pts)

# 由于存在舍入误差,所以得到的边的数值可能不唯一

ix, jx = np.where((dMat-np.min(dMat))<0.01)

# 获取正二十面体的边

edges = [pts[[i,j]] for i,j in zip(ix, jx)]

def isFace(e1, e2, e3):

    pts = np.vstack([e1, e2, e3])

    pts = np.unique(pts, axis=0)

    return len(pts)==3

 

from itertools import combinations

# 获取正二十面体的面

faces = [es for es in combinations(edges, 3)

    if isFace(*es)]

为了克服plot_trisurf在xy坐标系中的bug,需要对足球做一点旋转,所以下面要写入旋转矩阵。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

# 将角度转弧度后再求余弦

cos = lambda th : np.cos(np.deg2rad(th))

sin = lambda th : np.sin(np.deg2rad(th))

 

# 即 Rx(th) => Matrix

Rx = lambda th : np.array([

    [1, 0,       0],

    [0, cos(th), -sin(th)],

    [0, sin(th), cos(th)]])

Ry = lambda th : np.array([

    [cos(th),  0, sin(th)],

    [0      ,  1, 0],

    [-sin(th), 0, cos(th)]

])

Rz = lambda th : np.array([

    [cos(th) , sin(th), 0],

    [-sin(th), cos(th), 0],

    [0       , 0,       1]])

最后得到的正二十面体为

先画六边形

足球其实就是正二十面体削掉顶点,正二十面体有20个面和12个顶点,每个面都是三角形。削掉顶点对于三角形而言就是削掉三个角,如果恰好选择在1/3的位置削角,则三角形就变成正六边形;而每个顶点处刚好有5条棱,顶点削去之后就变成了正五边形。

而正好足球的六边形和五边形有着不同的颜色,所以可以分步绘制,先来搞定六边形。

由于此前已经得到了正二十面体的所有面,同时还有这个面对应的所有边,故而只需在每一条边的1/3 和2/3处截断,就可以得到足球的正六边形。

1

2

3

4

5

6

7

8

9

10

11

12

def getHexEdges(face):

    pts = []

    for st,ed in face:

        pts.append((2*st+ed)/3)

        pts.append((st+2*ed)/3)

    return np.vstack(pts)

 

ax = plt.subplot(projection='3d')

for f in faces:

    pt = getHexEdges(f)

    pt = Rx(1)@Ry(1)@pt.T

    ax.plot_trisurf(*pt, color="white")

于是,一个有窟窿的足球就很轻松地被画出来了

再画五边形

接下来要做的是,将五边形的窟窿补上,正如一开始说的,这个五边形可以理解为削去顶点而得到的,所以第一件事,就是要找到一个顶点周围的所有边。具体方法就是,对每一个顶点遍历所有边,如果某条边中存在这个顶点,那么就把这个边纳入到这个顶点的连接边。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

def getPtEdges(pts, edges):

    N = len(pts)

    pEdge = [[] for pt in pts]

    for i,e in product(range(N),edges):

        if (pts[i] == e[0]).all():

            pt = (2*pts[i]+e[1])/3

        elif (pts[i] == e[1]).all():

            pt = (2*pts[i]+e[0])/3

        else:

            continue

        pEdge[i].append(pt)

    return np.array(pEdge)

 

pEdge = getPtEdges(pts, edges)

接下来,就可以绘制足球了

1

2

3

4

5

6

7

8

9

10

11

ax = plt.subplot(projection='3d')

for f in faces:

    pt = getHexEdges(f)

    pt = Rx(1)@Ry(1)@pt.T

    ax.plot_trisurf(*pt, color="white")

 

for pt in pEdge:

    pt = Rx(1)@Ry(1)@pt.T

    ax.plot_trisurf(*pt, color="black")

 

plt.show()

效果为


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://tinycool.blog.csdn.net/article/details/128260408
相关文章
  • 用Python绘制一个仿黑洞图像

    用Python绘制一个仿黑洞图像
    黑洞图像大家都知道,毕竟前几年刚发布的时候曾火遍全网,甚至都做成表情包了。 问题在于,凭什么认为这就是黑洞的照片,而不是一个
  • python __init__与 __new__的区别
    一、构造函数 __init__ 与__new__ __new__ 作用: 创建对象,并分配内存 __init__ 作用: 初始化对象的值 注意: 1、与java相比,java只有一个构造器
  • 基于Python实现绘制一个足球

    基于Python实现绘制一个足球
    前情提要 如果想优雅地绘制一个足球,那首先需要绘制正二十面体:用Python绘制正二十面体 其核心代码为 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1
  • 关于keras中卷积层Conv2D的学习记录

    关于keras中卷积层Conv2D的学习记录
    keras中卷积层Conv2D的学习 关于卷积的具体操作不细讲,本文只是自己太懒了不想记手写笔记。 由于自己接触到的都是图像 处理相关的工作,
  • pycharm中执行.sh文件的方法

    pycharm中执行.sh文件的方法
    背景 在运行神经网络相关的实验的时候,通常要跑很多次实验,而每次实验运行时间很久,每运行完一次就需要手动再运行下一次实验。(
  • pycharm2022.2远程连接服务器调试代码实现

    pycharm2022.2远程连接服务器调试代码实现
    目的: 同步本地和服务器的全部或者部分文件 本地debug,服务器跑实验 需要条件: 服务器上已经创建好虚拟环境 你本地已经安装好pychar
  • numpy.unique()使用方法介绍
    numpy.unique() 函数接受一个数组,去除其中重复元素,并按元素由小到大返回一个新的无元素重复的元组或者列表。 1. 参数说明 1 numpy.unique
  • JWT的原理及使用
    目录JWT的原理及使用一、什么是JWT?二、签发认证流程三、使用方法1.设置登录接口2.设置过期事件3.定制返回格式4.配置认证类和权限类5.写
  • NumPy迭代数组的实现的介绍
    NumPy中引入了 nditer 对象来提供一种对于数组元素的访问方式。 一、单数组迭代 1. 使用 nditer 访问数组的每个元素 1 2 3 4 5 6 7 8 9 10 11 12 13 1
  • python批量翻译excel表格中的英文
    需求背景 女朋友的论文需要爬取YouTube视频热评,但爬下来的都是外文。 主要设计 读取一个表格文件,获取需要翻译的文本 使用百度翻译
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计