您好,登錄后才能下訂單哦!
這篇文章主要介紹“Python如何利用plotly繪制正二十面體”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Python如何利用plotly繪制正二十面體”文章能幫助大家解決問題。
正20面體的12個頂點剛好可以分為三組,每一組都是一個符合黃金分割比例的長方形,而且這三個長方形是互相正交的。
所以,想繪制一個正二十面體是比較容易的
import plotly import plotly.express as px 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 fig = px.scatter_3d(x=xs, y=ys, z=zs, size=np.ones_like(xs)*0.5) fig.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 = [] for k in range(len(ix)): edges.append(pts[ix[k]].tolist() + [k]) edges.append(pts[jx[k]].tolist() + [k]) edges = np.array(edges) fig = px.line_3d(edges, x=0, y=1, z=2, color=3) fig.show()
效果如圖所示
接下來要對面上色。由于三棱成個面,所以只需得到所有三條棱的組合,只要這三條棱可以組成三角形,就能獲取所有的三角面。當然,這一切的前提是,正二十面體只有30個棱,即使遍歷多次,也無非27k的計算量,是完全沒問題的。
def isFace(e1, e2, e3): pts = np.vstack([e1, e2, e3]) pts = np.unique(pts, axis=0) return len(pts)==3 edges = [pts[[i,j]] for i,j in zip(ix, jx)] from itertools import combinations faces = [es for es in combinations(edges, 3) if isFace(*es)]
最后得到的faces有20個元素,每個元素由3條棱組成,每條棱有兩個頂點,故而可以縮減為三個頂點。
ptFace = [np.unique(np.vstack(f),axis=0) for f in faces] ptFace = np.vstack(ptFace)
接下來繪制一下,plotly繪制三角面的邏輯是,除了需要指定三角面的三個坐標之外,還需指定三角面的頂點序號
import plotly.figure_factory as ff simplices = np.arange(len(ptFace)).reshape(-1,3) fig = ff.create_trisurf(x=ptFace[:,0], y=ptFace[:,1], z=ptFace[:,2], simplices=simplices) fig.show()
效果如下
關于“Python如何利用plotly繪制正二十面體”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。