Python绘制正二十面体图形示例

作者:微小冷 时间:2022-01-10 18:27:08 

正二十面体的顶点

正20面体的12个顶点刚好可以分为三组,每一组都是一个符合黄金分割比例的长方形,而且这三个长方形是互相正交的。

所以,想绘制一个正二十面体是比较容易的

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)

xs, ys zs = getVertex().T
ax = plt.subplot(projection='3d')
ax.scatter(xs, ys, zs)
plt.show()

得到顶点

Python绘制正二十面体图形示例

绘制棱

接下来将这些顶点连接成线,由于总共只有12个顶点,所以两两相连,也不至于导致运算量 * 。另一方面,正二十面体的边长是相同的,而这些相同的边连接的也必然是最近的点,所以接下来只需建立顶点之间的距离矩阵,然后将距离最短的线抽出来即可。

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)]

ax = plt.subplot(projection='3d')
for pt in edges:
   ax.plot(*pt.T)

plt.show()

效果如图所示

Python绘制正二十面体图形示例

绘制面

当然,只是有棱还显得不太好看,接下来要对正二十面体的面进行上色。由于三条棱构成一个面,所以只需得到所有三条棱的组合,然后判定这三条棱是否可以组成一个三角形,就可以获取所有的三角面。当然,这一切的前提是,正二十面体只有30个棱,即使遍历多次,也无非27k的计算量,是完全没问题的。

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)]

接下来绘制一下

ax = plt.subplot(projection='3d')
for f in faces:
   pt = np.unique(np.vstack(f), axis=0)
   try:
       ax.plot_trisurf(*pt.T)
   except:
       pass

plt.show()

如图所示

Python绘制正二十面体图形示例

由于plot_trisurf的画图逻辑是,先绘制xy坐标系上的三角形,然后再以此为三角形建立z轴坐标。所以这会导致一个Bug,即所绘制的三角面不能垂直于xy坐标系,为了让正二十面体被完整地绘制出来,可以对其绕着x和y轴旋转一下,当然首先要建立一个旋转矩阵。三维空间中的旋转矩阵如下表所示。详情可参考博客:Python动态演示旋转矩阵的作用

Python绘制正二十面体图形示例

写成代码为

# 将角度转弧度后再求余弦
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)]
])

然后绘图函数

ax = plt.subplot(projection='3d')
for f in faces:
   pt = np.unique(np.vstack(f), axis=0)
   pt = Rx(1)@Ry(1)@pt.T
   ax.plot_trisurf(*pt)

for pt in edges:
   pt = Rx(1)@Ry(1)@pt.T
   ax.plot(*pt, lw=2, color='blue')

plt.show()  

效果如下

Python绘制正二十面体图形示例

来源:https://blog.csdn.net/m0_37816922/article/details/128258800

标签:Python,绘制,正二十面体
0
投稿

猜你喜欢

  • 基于python实现数组格式参数加密计算

    2021-08-20 23:29:54
  • python去掉空格的一些常用方式

    2022-02-10 04:45:34
  • 关于javascript中伪数组和真数组的一些小秘密

    2023-07-02 03:47:47
  • MySQL学习笔记之数据的增、删、改实现方法

    2024-01-27 04:07:41
  • Vue不能watch数组和对象变化解决方案

    2024-04-30 10:41:06
  • pymongo实现控制mongodb中数字字段做加法的方法

    2021-12-15 21:04:06
  • 用ASP和SQL语句动态的创建Access表

    2008-10-14 16:59:00
  • 跟老齐学Python之网站的结构

    2021-08-22 05:55:54
  • python 解析html之BeautifulSoup

    2021-02-09 23:09:12
  • SQLServer 2000 数据库同步详细步骤[两台服务器]

    2024-01-21 11:18:03
  • Python动态声明变量赋值代码实例

    2023-11-15 03:30:47
  • Python如何爬取b站热门视频并导入Excel

    2023-06-20 23:27:44
  • PHP扩展开发入门教程

    2024-05-05 09:17:51
  • pygame编写音乐播放器的实现代码示例

    2021-08-12 18:08:48
  • Python中使用glob和rmtree删除目录子目录及所有文件的例子

    2023-12-26 07:14:18
  • golang编程开发使用sort排序示例详解

    2023-09-16 23:20:18
  • php基础字符串与数组知识点讲解

    2023-05-25 08:28:14
  • Python中使用bidict模块双向字典结构的奇技淫巧

    2023-05-12 19:37:55
  • 用Python抢火车票的简单小程序实现解析

    2023-09-06 06:31:28
  • php 解压zip压缩包内容到指定目录的实例

    2024-04-18 09:28:47
  • asp之家 网络编程 m.aspxhome.com