|
![]() |
2019年04月19日 |
|
|
Python user_defined line/lines Class _(2) Python canvas line/lines自訂函數:Python學習日誌之四
(a)橢圓形及圓形 我們已經介紹過在此任意三點(x0,y0,x1,y1,x2,y2第一二點為長軸)之橢圓公式及橢圓上之點座標求法。現在我們再討論三點圓公式,三點圓是任意三點橢圓之特例 ,即圓心為三點橢圓第一二點連線(直徑)中心,第三點為通過圓心且垂直直徑,距離為半徑之點位置(上下兩點之任一點)。或採用過三點之圓公式,下面之程式碼為三點圓公式。 def Cir3pt_Draw(bolCir,x0,y0,x1,y1,x2,y2,angBeg=0.0,angEnd=360.0,npt=36, cenReturn=0): #print('into Cir3pt_Prop' ) v31X = x2 - x0 v31Y = y2 - y0 v21X = x1 - x0 v21Y = y1 - y0 d_ca = v31X * v21X + v31Y * v21Y v32X = x2 - x1 v32Y = y2 - y1 v12X = x0 - x1 v12Y = y0 - y1 d_ba = v32X * v12X + v32Y * v12Y v13X = x0 - x2 v13Y = y0 - y2 v23X = x1 - x2 v23Y = y1 - y2 d_cb = v13X * v23X + v13Y * v23Y n1 = d_ba * d_cb n2 = d_cb * d_ca n3 = d_ca * d_ba radius_ = math.sqrt((d_ca + d_ba) * (d_ba + d_cb) * (d_cb + d_ca)/(n1 + n2 + n3)) / 2.0 ptCenX = ((n2 + n3) * x0 + (n3 + n1) * x1 + (n1 + n2) * x2) / 2.0/(n1 + n2 + n3) ptCenY = ((n2 + n3) * y0 + (n3 + n1) * y1 + (n1 + n2) * y2) / 2.0 /(n1 + n2 + n3) #print('xcn,ycn,rad',ptCenX,ptCenY,radius_) if bolCir==True: xa=[] ya=[] pts=[] ndo=npt angdel=math.radians((angEnd-angBeg)/npt) #print('ndo,angdel',ndo,angdel) for i in range(npt+1): angdelT=angdel*i xtpt=ptCenX+radius_*math.cos(angdelT) ytpt=ptCenY+radius_*math.sin(angdelT) #print('i,ang,x,y=',i,math.degrees(angdelT),xtpt,ytpt) xa.append(xtpt) ya.append(ytpt) pts.append((xtpt,ytpt)) #xa += (xtpt) #ya += (ytpt) #pts +=(xtpt,ytpt) if cenReturn==0: return len(xa),xa,ya,pts else: return len(xa),xa,ya,pts,ptCenX,ptCenY
(b)圓滑曲線及雲狀線(Curve fitting & spline) Python canvas圓滑曲線主要在畫polyline時,畫線選項options設定smooth=True, splinestep=13或5或其他整數即可(預設為12),圓滑曲線是不經完全通過已知控制節點(knot)。如要spline則需設法求出節點(knot points)以外之增加點座標。在本篇報告我們是利用 import numpy as np from scipy.interpolate import interp1d import matplotlib.pyplot as plt 讀取增加點座標。非閉合Spline線上互動式畫法(滑鼠在pictuerbox上直接布點之rubber_band drawingt),老夫在二三十年前曾經幹過,本想將其改寫成python,在偶然機會看到有人在網路討論此議題(stack overflow: Fitting a closed curve to a set of points,閉合及非閉合spline),因此突發奇想,何不撿個現成。Numpy, matplotlib.pyplot等有很特殊函數曲線製圖,畫圖前必須先計算所有變化點標值後才能畫圖,電腦不能無中生有,只不過是有仙(賢)人替妳(你)寫好庫存函數代勞,我等要感謝這些無名英雌(雄)。我就是在多方嘗試後,設法將此計算值擷取出。有這些中間值後,再利用python canvas之create_line或create_polygon就稿定一切。
class Spline_pt: def __init__(self,ptkeylist,nptAdd=10,bolClosed=False): nptKey=len(ptkeylist) self.nptkey=nptKey if bolClosed==True: ptkeylist.append(ptkeylist[0]) nptkey +=1 self.nptkey=nptKey
x=[] y=[] for i in range(self.nptkey): x.append([ptkeylist[i].x]) y.append([ptkeylist[i].y]) #np.arange([start,]),stop[,step,],dtype=None)
i = np.arange(len(x)) #can not replace by i=self.nptkey # nptAdd * x (x=the original number of points) #np.linspace(start,stop,num=50,endpoint=True,restep=False,dtype=None) interp_i = np.linspace(0, i.max(), nptAdd * i.max()) xi=[] yi=[] xi = interp1d(i, x, kind='cubic')(interp_i) yi = interp1d(i, y, kind='cubic')(interp_i) self.ptslist=Ptxy(xi,yi)
|
上次修改此網站的日期: 2019年03月24日