Created
September 8, 2021 14:13
-
-
Save mdecourse/626206cf3b2a9a9a69f7ce4bb4a116f0 to your computer and use it in GitHub Desktop.
Brython canvas spur gear and form to set gear number
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Draw single Spur Gear | |
| from browser import document as doc | |
| from browser import html | |
| import math | |
| # 利用 Brython 建立 canvas 標註元件 | |
| canvas = html.CANVAS(width = 600, height = 400) | |
| # 將此 canvas 的 id 設為 "spur" | |
| canvas.id = "spur" | |
| # 將 brython_div 變數設為 id 為 "brython_div 的 doc 物件 | |
| brython_div = doc["brython_div"] | |
| # 將此 canvas 物件插入網頁 | |
| brython_div <= canvas | |
| # 利用 canvas 代表 id="spur" 標註元件 | |
| # 表示要將 ctx 2d 繪圖至 canvas | |
| canvas = doc["spur"] | |
| ctx = canvas.getContext("2d") | |
| # 插入輸入表單 | |
| form = html.FORM() | |
| gearNumInput = html.INPUT(type="text", id="gearnum", value="23") | |
| button = html.BUTTON("設定齒數", id="set_num") | |
| form <= "齒數: " + gearNumInput + html.BR() | |
| brython_div <= form + button + html.BR() | |
| #print(html.BUTTON("設定齒數", id="set_num").outerHTML) | |
| # 以下建立正齒輪繪圖物件與設定齒數函式 | |
| # deg 為角度轉為徑度的轉換因子 | |
| deg = math.pi/180. | |
| # 定義 Spur 類別 | |
| class Spur: | |
| def __init__(self, ctx): | |
| self.ctx = ctx | |
| def create_line(self, x1, y1, x2, y2, width=1, fill="red"): | |
| self.ctx.beginPath() | |
| self.ctx.lineWidth = width | |
| self.ctx.moveTo(x1, y1) | |
| self.ctx.lineTo(x2, y2) | |
| self.ctx.strokeStyle = fill | |
| self.ctx.stroke() | |
| # 定義一個繪正齒輪的繪圖函式 | |
| # midx 為齒輪圓心 x 座標 | |
| # midy 為齒輪圓心 y 座標 | |
| # rp 為節圓半徑, n 為齒數 | |
| # pa 為壓力角 (deg) | |
| # rot 為旋轉角 (deg) | |
| # 針對 n 大於等於 52 齒時 base circle 與齒根圓大小必須進行判斷 | |
| def Gear(self, midx, midy, rp, n=20, pa=20, color="black"): | |
| # 齒輪漸開線分成 15 線段繪製 | |
| imax = 15 | |
| # 在輸入的畫布上繪製直線, 由圓心到節圓 y 軸頂點畫一直線 | |
| self.create_line(midx, midy, midx, midy-rp) | |
| # a 為模數 (代表公制中齒的大小), 模數為節圓直徑(稱為節徑)除以齒數 | |
| # 模數也就是齒冠大小 | |
| a=2*rp/n | |
| # d 為齒根大小, 為模數的 1.157 或 1.25倍, 這裡採 1.25 倍 | |
| d=2.5*rp/n | |
| # ra 為齒輪的外圍半徑 | |
| ra=rp+a | |
| # rb 則為齒輪的基圓半徑 | |
| # 基圓為漸開線長齒之基準圓 | |
| rb=rp*math.cos(pa*deg) | |
| # rd 為齒根圓半徑 | |
| rd=rp-d | |
| # 當 rd 大於 rb 時, 漸開線並非畫至 rb, 而是 rd | |
| # dr 則為基圓到齒頂圓半徑分成 imax 段後的每段半徑增量大小 | |
| # 將圓弧分成 imax 段來繪製漸開線 | |
| # 當 rd 大於 rb 時, 漸開線並非畫至 rb, 而是 rd | |
| if rd>rb: | |
| dr = (ra-rd)/imax | |
| else: | |
| dr=(ra-rb)/imax | |
| # tan(pa*deg)-pa*deg 為漸開線函數 | |
| sigma=math.pi/(2*n)+math.tan(pa*deg)-pa*deg | |
| for j in range(n): | |
| ang=-2.*j*math.pi/n+sigma | |
| ang2=2.*j*math.pi/n+sigma | |
| lxd=midx+rd*math.sin(ang2-2.*math.pi/n) | |
| lyd=midy-rd*math.cos(ang2-2.*math.pi/n) | |
| for i in range(imax+1): | |
| # 當 rd 大於 rb 時, 漸開線並非畫至 rb, 而是 rd | |
| if rd>rb: | |
| r=rd+i*dr | |
| else: | |
| r=rb+i*dr | |
| theta=math.sqrt((r*r)/(rb*rb)-1.) | |
| alpha=theta-math.atan(theta) | |
| xpt=r*math.sin(alpha-ang) | |
| ypt=r*math.cos(alpha-ang) | |
| xd=rd*math.sin(-ang) | |
| yd=rd*math.cos(-ang) | |
| # i=0 時, 繪線起點由齒根圓上的點, 作為起點 | |
| if(i==0): | |
| last_x = midx+xd | |
| last_y = midy-yd | |
| # 由左側齒根圓作為起點, 除第一點 (xd,yd) 齒根圓上的起點外, 其餘的 (xpt,ypt)則為漸開線上的分段點 | |
| self.create_line((midx+xpt),(midy-ypt),(last_x),(last_y),fill=color) | |
| # 最後一點, 則為齒頂圓 | |
| if(i==imax): | |
| lfx=midx+xpt | |
| lfy=midy-ypt | |
| last_x = midx+xpt | |
| last_y = midy-ypt | |
| # the line from last end of dedendum point to the recent | |
| # end of dedendum point | |
| # lxd 為齒根圓上的左側 x 座標, lyd 則為 y 座標 | |
| # 下列為齒根圓上用來近似圓弧的直線 | |
| self.create_line((lxd),(lyd),(midx+xd),(midy-yd),fill=color) | |
| for i in range(imax+1): | |
| # 當 rd 大於 rb 時, 漸開線並非畫至 rb, 而是 rd | |
| if rd>rb: | |
| r=rd+i*dr | |
| else: | |
| r=rb+i*dr | |
| theta=math.sqrt((r*r)/(rb*rb)-1.) | |
| alpha=theta-math.atan(theta) | |
| xpt=r*math.sin(ang2-alpha) | |
| ypt=r*math.cos(ang2-alpha) | |
| xd=rd*math.sin(ang2) | |
| yd=rd*math.cos(ang2) | |
| # i=0 時, 繪線起點由齒根圓上的點, 作為起點 | |
| if(i==0): | |
| last_x = midx+xd | |
| last_y = midy-yd | |
| # 由右側齒根圓作為起點, 除第一點 (xd,yd) 齒根圓上的起點外, 其餘的 (xpt,ypt)則為漸開線上的分段點 | |
| self.create_line((midx+xpt),(midy-ypt),(last_x),(last_y),fill=color) | |
| # 最後一點, 則為齒頂圓 | |
| if(i==imax): | |
| rfx=midx+xpt | |
| rfy=midy-ypt | |
| last_x = midx+xpt | |
| last_y = midy-ypt | |
| # lfx 為齒頂圓上的左側 x 座標, lfy 則為 y 座標 | |
| # 下列為齒頂圓上用來近似圓弧的直線 | |
| self.create_line(lfx,lfy,rfx,rfy,fill=color) | |
| # 以 button 驅動的事件函式 | |
| def setgearnumber(e): | |
| global ctx | |
| ctx.clearRect(0, 0, canvas.width, canvas.height) | |
| x = (canvas.width)/2 | |
| y = (canvas.height)/2 | |
| if doc["gearnum"].value.isdigit(): | |
| n1 = int(doc["gearnum"].value) | |
| else: | |
| n1= 26 | |
| # 設定齒輪參數 | |
| x = (canvas.width)/2 | |
| y = (canvas.height)/2 | |
| r = 0.8*(canvas.height/2) | |
| pa = 20 | |
| # 繪出正齒輪 | |
| spur = Spur(ctx) | |
| spur.Gear(x, y, r, n1, pa, "blue") | |
| #判定 button | |
| setgearnumber(True) | |
| doc['set_num'].bind('click',setgearnumber) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment