Python绘制正二十面体图形示例
作者:微小冷 发布时间:2022-01-10 18:27:08
标签:Python,绘制,正二十面体
正二十面体的顶点
正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()
得到顶点
绘制棱
接下来将这些顶点连接成线,由于总共只有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()
效果如图所示
绘制面
当然,只是有棱还显得不太好看,接下来要对正二十面体的面进行上色。由于三条棱构成一个面,所以只需得到所有三条棱的组合,然后判定这三条棱是否可以组成一个三角形,就可以获取所有的三角面。当然,这一切的前提是,正二十面体只有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()
如图所示
由于plot_trisurf
的画图逻辑是,先绘制xy坐标系上的三角形,然后再以此为三角形建立z轴坐标。所以这会导致一个Bug,即所绘制的三角面不能垂直于xy坐标系,为了让正二十面体被完整地绘制出来,可以对其绕着x和y轴旋转一下,当然首先要建立一个旋转矩阵。三维空间中的旋转矩阵如下表所示。详情可参考博客: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()
效果如下
来源:https://blog.csdn.net/m0_37816922/article/details/128258800
0
投稿
猜你喜欢
- 您也可以提供几个连接字符串修饰符来控制连接池行为,请参见本主题内下文中“使用连接字符串关键字控制连接池”这一节。池的创建和分配当连接打开时,
- 用类和对象实现一个银行账户的资金交易管理, 包括存款、取款和打印交易详情, 交易详情中包含每次交易的时间、存款或者取款的金额、每次交易后的余
- 我们用pyinstaller把朋友文件打包成exe文件,但有时候我们需要还原,我们可以用pyinstxtractor.py用法:python
- 数据备份与还原第三篇,具体如下基础概念:备份,将当前已有的数据或记录另存一份;还原,将数据恢复到备份时的状态。为什么要进行数据的备份与还原?
- Mac 安装 Python3.10 并且配置环境一、Python的安装访问官网:https://www.python.org/选择系统(Ma
- 我们知道,TCP是面向连接流传输的,其采用Nagle算法,在缓冲区对上层数据进行了处理。避免触发自动分片机制和网络上大量小数据包的同时也造成
- 鉴于最近一段时间一直在折腾的CNN网络效果不太理想,主要目标是为了检测出图像中的一些关键点,可以参考人脸的关键点检测算法。但是由于从数据集的
- 查到的可能原因:1.本地的go编译器版本2. go module构建模式未开启3. 是否在go.mod所在目录执行的go mod tidy解
- 一、 安装tensorboard直接pip即可:pip install tensorboard这里注意,使用pytorch,并不需要额外安装
- 本文实例为大家分享了javascript实现切割轮播的具体代码,供大家参考,具体内容如下效果代码<!DOCTYPE html>&
- 本文实例讲述了Python排序搜索基本算法之堆排序。分享给大家供大家参考,具体如下:堆是一种完全二叉树,堆排序是一种树形选择排序,利用了大顶
- 如下所示:#待处理列表A= [1,2,3,4,5]#移动次数a = 3右移比较简单for i in range(a): A.insert(0
- 前言在当前的JavaScript中,并没有枚举这个概念,在某些场景中使用枚举更能保证数据的正确性,减少数据校验过程,下面就介绍一下JavaS
- 1、安装mysql有InnoDB的插件扩展 ./configure --prefix=/usr/local/mysql --with-plu
- 问题:需要循环获取网元返回的某个参数,并计算出平均值。解决方案:通过expect解决返回More的问题。通过具体的参数位置,精确获取到参数。
- 记一次在写cli脚本的时候,碰到的一个问题。问题自己是写服务端的,有时候会写一些cli脚本去跑测试。习惯main.go写主流程,其他子文件写
- 看知乎的时候发现了一个 “如何正确地吐槽” 收藏夹,里面的一些神回复实在很搞笑,但是一页一页地看又有点麻烦,而且每次都要打开网页,于是想如果
- 前言夏天是用来告别的季节,因为毕业总在七月。那么七月之前的季节是用来干嘛的呢?当然是用来做毕业设计的啦今天还是写一些从简单到难的毕业设计或者
- 微信这个东西估计宅男没几个不熟悉的吧,微信经过这么两年多的发展终于向开放平台跨出了友好的一步。蛋疼的以为微信会出一个详细的api等接口,兴奋
- 一、赋值对比1、列表l1 = [1,2,3]l2 = l1l1.append('a')print(l1,l2)