使用bokeh繪圖
bokeh
由於mpld3沒有支援Python 3.5,測試過執行產生的頁面是空白頁,所以選擇使用bokeh來繪製,但是後者不支援3D繪圖。
使用Anaconda的指令安裝bokeh。
1 | ana install bokeh
|

參照了一下官方的說明頁:
Exercise
將之前的Crank Rocker改寫一下鏈
#一三角形呆鍊,由一長一短的連桿固定在水平基線上。
#短連桿鎖固在原點上,長連鏈鎖固在距原點90mm處。
#短連桿長度35mm;長連桿長度70mm。
#三角形呆鍊邊長分別為40mm、40mm、70mm
from slvs import *
from math import *
from bokeh.plotting import figure, output_file, show
#相關參數
d0 = 90 #基線長度(mm)
n1 = 35 #短連桿長度(mm)
n2 = 70 #長連桿長度(mm)
t1 = 40 #三角形第一邊(mm)
t2 = 40 #三角形第二邊(mm)
t3 = 70 #三角形第三邊(mm)
#開始繪圖
def crank_rock(degree):
sys = System(500)
g = 1
#原點Point0
p0 = sys.add_param(0.0)
p1 = sys.add_param(0.0)
p2 = sys.add_param(0.0)
Point0 = Point3d(p0, p1, p2)
#XY法線
qw, qx, qy, qz = Slvs_MakeQuaternion(1, 0, 0, 0, 1, 0)
p3 = sys.add_param(qw)
p4 = sys.add_param(qx)
p5 = sys.add_param(qy)
p6 = sys.add_param(qz)
Normal1 = Normal3d(p3, p4, p5, p6)
#工作平面
Workplane1 = Workplane(Point0, Normal1)
#3D版的Point0=>Point1
p7 = sys.add_param(0.0)
p8 = sys.add_param(0.0)
Point1 = Point2d(Workplane1, p7, p8)
Constraint.dragged(Workplane1, Point1)
#長連桿轉軸Point2,還有基線Line0。
p9 = sys.add_param(d0)
p10 = sys.add_param(0.0)
Point2 = Point2d(Workplane1, p9, p10)
Constraint.dragged(Workplane1, Point2)
Line0 = LineSegment2d(Workplane1, Point1, Point2)
#Angle約束判斷
if degree >= 180:
other = -1
else:
other = 1
#三角形Point3 / Point4 / Point5
p11 = sys.add_param(20.0)
p12 = sys.add_param(20.0)
Point3 = Point2d(Workplane1, p11, p12)
p13 = sys.add_param(0.0)
p14 = sys.add_param(10.0*other)
Point4 = Point2d(Workplane1, p13, p14)
p15 = sys.add_param(30.0)
p16 = sys.add_param(20.0)
Point5 = Point2d(Workplane1, p15, p16)
Constraint.distance(t1, Workplane1, Point4, Point3)
Constraint.distance(t2, Workplane1, Point3, Point5)
Constraint.distance(t3, Workplane1, Point4, Point5)
#連桿約束
Constraint.distance(n1, Workplane1, Point1, Point4)
Constraint.distance(n2, Workplane1, Point2, Point5)
Line1 = LineSegment2d(Workplane1, Point1, Point4)
#短連桿與水平軸的角度
Constraint.angle(Workplane1, degree, Line1, Line0, False)
#以下解題
sys.solve()
if (sys.result == SLVS_RESULT_OKAY):
x = sys.get_param(11).val
y = sys.get_param(12).val
return x, y
elif (sys.result == SLVS_RESULT_INCONSISTENT):
print ("solve failed")
print ("SLVS_RESULT_INCONSISTENT")
print ("%d DOF" % sys.dof)
elif (sys.result == SLVS_RESULT_DIDNT_CONVERGE):
print ("solve failed")
print ("SLVS_RESULT_DIDNT_CONVERGE")
print ("%d DOF" % sys.dof)
elif (sys.result == SLVS_RESULT_TOO_MANY_UNKNOWNS):
print ("solve failed")
print ("SLVS_RESULT_TOO_MANY_UNKNOWNS")
print ("%d DOF" % sys.dof)
#主程式
Xval = []
Yval = []
for i in range(0, 361):
x, y = crank_rock(i)
Xval += [x]
Yval += [y]
print ("Solve Completed")
#bokeh
output_file("mango.html")
plot = figure(title="simple line example", x_axis_label='x', y_axis_label='y')
plot.line(Xval, Yval, legend="Temp.", line_width=2)
show(plot)
使用的是簡單的show指令,會產生一個html的檔案。
內容是和matplotlib一樣的圖形。

另外bokeh也可以在Jupyter notebook上使用。
from tmp.workplace.exposed.slvs import *
from math import *
from bokeh.plotting import figure, output_notebook, show
d0 = 90 #基線長度(mm)
n1 = 35 #短連桿長度(mm)
n2 = 70 #長連桿長度(mm)
t1 = 40 #三角形第一邊(mm)
t2 = 40 #三角形第二邊(mm)
t3 = 70 #三角形第三邊(mm)
#開始繪圖
def crank_rock(degree):
...
#主程式
Xval = []
Yval = []
for i in range(0, 361):
x, y = crank_rock(i)
Xval += [x]
Yval += [y]
print ("Solve Completed")
#bokeh
output_notebook()
plot = figure(title="simple line example", x_axis_label='x', y_axis_label='y')
plot.line(Xval, Yval, legend="Temp.", line_width=2)
show(plot)
程式庫名稱必須改為tmp.workplace.exposed.slvs
執行結果如下:

另一支跑手臂極限範圍的程式:

有找到另一個套件Vispy可以畫3D物件,也可以在Jupyter notebook上執行。
另外Solvespace的運算方面無法同時計算2D和3D的物件,儲存的項目也不一樣。
不知道能不能用球座標系或圓柱坐標系轉換的方式,做一個將3D點鎖定到2D點的功能。
Comments
comments powered by Disqus