-
Notifications
You must be signed in to change notification settings - Fork 1
/
user.py
179 lines (158 loc) · 7.08 KB
/
user.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
from flask import Blueprint, render_template, current_app, \
send_from_directory, session, redirect, url_for
import os
userapp = Blueprint('user', __name__, url_prefix='/user', template_folder='templates')
@userapp.route('/')
def index():
user = "Yen"
# 若 template 檔案名稱與位於外部 templates 目錄中的檔案同名, 則取外部的 template
return render_template('g1index.html', user=user)
@userapp.route('/threegear', defaults={'n1':15,'n2':20,'n3':18})
@userapp.route('/threegear/<n1>/<n2>/<n3>')
def threegear(n1, n2, n3):
# 真正最後的架構應該要在函式中準備繪圖所需的資料, 然後用 template 呈現內容
title = "網際 2D 繪圖"
head = '''
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>'''+ title +'''</title>
<!-- IE 9: display inline SVG -->
<meta http-equiv="X-UA-Compatible" content="IE=9">
'''
script = '''
<script type="text/javascript" src="https://brython.info/src/brython_dist.js"></script>
<script type="text/javascript" src="https://2015fallhw.github.io/cptocadp/static/Cango-8v03.js"></script>
<script type="text/javascript" src="https://2015fallhw.github.io/cptocadp/static/Cango2D-7v01-min.js"></script>
<script type="text/javascript" src="https://2015fallhw.github.io/cptocadp/static/gearUtils-05.js"></script>
<script>
window.onload=function(){
brython(1);
}
</script>
'''
headstring = head + script + "</head>"
# 能否根據 n1, n2, n3 與 width, 算出合理的 height
# 模數計算 m = canvas.width*0.8/(n1+n2+n3)
# max([int(n1), int(n2), int(n3)])
# 所以 height = 1.2*800*0.8/(int(n1)+int(n2)+int(n3))*max([int(n1), int(n2), int(n3)])
height = 1.2*800*0.8/(int(n1)+int(n2)+int(n3))*max([int(n1), int(n2), int(n3)])
body = '''
延伸應用:<br />
軸孔加入 keyway <br />
與 3D 零件設計繪圖對應 <br/>
與 2D/3D 軸的設計與繪圖對應<br /><br />
<canvas id='gear1' width='800' height="'''+str(int(height))+'''"></canvas>
<script type="text/python">
# 將 導入的 document 設為 doc 主要原因在於與舊程式碼相容
from browser import document as doc
# 由於 Python3 與 Javascript 程式碼已經不再混用, 因此來自 Javascript 的變數, 必須居中透過 window 物件轉換
from browser import window
# 針對 Javascript 既有的物件, 則必須透過 JSConstructor 轉換
from javascript import JSConstructor
import math
# 主要用來取得畫布大小
canvas = doc["gear1"]
# 此程式採用 Cango Javascript 程式庫繪圖, 因此無需 ctx
#ctx = canvas.getContext("2d")
# 針對類別的轉換, 將 Cango.js 中的 Cango 物件轉為 Python cango 物件
cango = JSConstructor(window.Cango)
# 針對變數的轉換, shapeDefs 在 Cango 中資料型別為變數, 可以透過 window 轉換
shapedefs = window.shapeDefs
# 目前 Cango 結合 Animation 在 Brython 尚無法運作, 此刻只能繪製靜態圖形
# in CangoAnimation.js
#interpolate1 = window.interpolate
# Cobi 與 createGearTooth 都是 Cango Javascript 程式庫中的物件
cobj = JSConstructor(window.Cobj)
creategeartooth = JSConstructor(window.createGearTooth)
# 經由 Cango 轉換成 Brython 的 cango, 指定將圖畫在 id="plotarea" 的 canvas 上
cgo = cango("gear1")
######################################
# 畫正齒輪輪廓
#####################################
def spur(cx, cy, m, n, pa, theta):
# n 為齒數
#n = 17
# pa 為壓力角
#pa = 25
# m 為模數, 根據畫布的寬度, 計算適合的模數大小
# Module = mm of pitch diameter per tooth
#m = 0.8*canvas.width/n
# pr 為節圓半徑
pr = n*m/2 # gear Pitch radius
# generate gear
data = creategeartooth(m, n, pa)
# Brython 程式中的 print 會將資料印在 Browser 的 console 區
#print(data)
gearTooth = cobj(data, "SHAPE", {
"fillColor":"#ddd0dd",
"border": True,
"strokeColor": "#606060" })
#gearTooth.rotate(180/n) # rotate gear 1/2 tooth to mesh, 請注意 rotate 角度為 degree
# theta 為角度
gearTooth.rotate(theta)
# 單齒的齒形資料經過旋轉後, 將資料複製到 gear 物件中
gear = gearTooth.dup()
# gear 為單一齒的輪廓資料
#cgo.render(gearTooth)
# 利用單齒輪廓旋轉, 產生整個正齒輪外形
for i in range(1, n):
# 將 gearTooth 中的資料複製到 newTooth
newTooth = gearTooth.dup()
# 配合迴圈, newTooth 的齒形資料進行旋轉, 然後利用 appendPath 方法, 將資料併入 gear
newTooth.rotate(360*i/n)
# appendPath 為 Cango 程式庫中的方法, 第二個變數為 True, 表示要刪除最前頭的 Move to SVG Path 標註符號
gear.appendPath(newTooth, True) # trim move command = True
# 建立軸孔
# add axle hole, hr 為 hole radius
hr = 0.6*pr # diameter of gear shaft
shaft = cobj(shapedefs.circle(hr), "PATH")
shaft.revWinding()
gear.appendPath(shaft) # retain the 'moveTo' command for shaft sub path
gear.translate(cx, cy)
# render 繪出靜態正齒輪輪廓
cgo.render(gear)
# 接著繪製齒輪的基準線
deg = math.pi/180
Line = cobj(['M', cx, cy, 'L', cx+pr*math.cos(theta*deg), cy+pr*math.sin(theta*deg)], "PATH", {
'strokeColor':'blue', 'lineWidth': 1})
cgo.render(Line)
# 3個齒輪的齒數
n1 = '''+str(n1)+'''
n2 = '''+str(n2)+'''
n3 = '''+str(n3)+'''
# m 為模數, 根據畫布的寬度, 計算適合的模數大小
# Module = mm of pitch diameter per tooth
# 利用 80% 的畫布寬度進行繪圖
# 計算模數的對應尺寸
m = canvas.width*0.8/(n1+n2+n3)
# 根據齒數與模組計算各齒輪的節圓半徑
pr1 = n1*m/2
pr2 = n2*m/2
pr3 = n3*m/2
# 畫布左右兩側都保留畫布寬度的 10%
# 依此計算對應的最左邊齒輪的軸心座標
cx = canvas.width*0.1+pr1
cy = canvas.height/2
# pa 為壓力角
pa = 25
# 畫最左邊齒輪, 定位線旋轉角為 0, 軸心座標 (cx, cy)
spur(cx, cy, m, n1, pa, 0)
# 第2個齒輪將原始的定位線逆時鐘轉 180 度後, 與第1個齒輪正好齒頂與齒頂對齊
# 只要第2個齒輪再逆時鐘或順時鐘轉動半齒的角度, 即可完成囓合
# 每一個齒分別包括從齒根到齒頂的範圍, 涵蓋角度為 360/n, 因此所謂的半齒角度為 180/n
spur(cx+pr1+pr2, cy, m, n2, pa, 180-180/n2)
# 第2齒與第3齒的囓合, 首先假定第2齒的定位線在 theta 角為 0 的原始位置
# 如此, 第3齒只要逆時鐘旋轉 180 度後, 再逆時鐘或順時鐘轉動半齒的角度, 即可與第2齒囓合
# 但是第2齒為了與第一齒囓合時, 已經從原始定位線轉了 180-180/n2 度
# 而當第2齒從與第3齒囓合的定位線, 逆時鐘旋轉 180-180/n2 角度後, 原先囓合的第3齒必須要再配合旋轉 (180-180/n2 )*n2/n3
spur(cx+pr1+pr2+pr2+pr3, cy, m, n3, pa, 180-180/n3+(180-180/n2)*n2/n3)
</script>
'''
bodystring = "<body>" + body+"</body>"
endstring = "</html>"
outstring = headstring + bodystring + endstring
return outstring
# 若 template 檔案名稱與位於外部 templates 目錄中的檔案同名, 則取外部的 template
# return render_template('g1index.html', user=user)