ディスクブレーキ
このチュートリアルでは,OpenCascadeLinkを使って,ディスクブレーキの主要部分であるディスクプレート(円形金属板)を作成する方法について説明する.大きさと作成過程は,コンピュータ支援設計(CAD)のチュートリアル [1,2]に基づく.
ディスクプレートの作成は,複数のステップで行われる.まず,本体を作成する.本体はディスクロータと呼ばれる部分で,ディスクプレートとハットセクションが含まれる.第2のステップでは,ハットセクションに穴を開け,ディスクの中央にスロットを1つ加える.最後に,穴のパターンをディスクの表面全体に加える.
Needs["OpenCascadeLink`"]
Needs["NDSolve`FEM`"]ディスクプレート
x-y面の横断面を指定することで,ディスクプレートを作成する.この横断面は,x軸の周りの回転から作成される立体の基礎となる.下の図では,不透明なディスクブレーキ内の濃い灰色で示される部分が横断面である.
横断面は12個の点
を含む1つの多角形からなり,ディスクの半径は144mmである.
radius = 144;
crossSection = Polygon[{{0, radius, 0}, {25, radius, 0}, {25, 80.5, 0}, {10, 80.5, 0}, {10, 74.125, 0}, {46.33, 74.125, 0}, {46.33, 34, 0}, {46.33 - 7.2, 34, 0}, {46.33 - 7.2, 67.5, 0}, {1, 67.5, 0}, {1, 80.5, 0}, {0, 80.5, 0}}];構築されたオブジェクトが正しい方向に向いていることを確かめることが大切である.このため,OpenCascadeAxis3Dを使う.
axisReference = OpenCascadeAxis3D[{0, 0, 0}, {80, 170, 170}];Show[Graphics3D[{Red, crossSection}], axisReference, Boxed -> False, ViewPoint -> Above]shape = OpenCascadeShape[crossSection]axisRotation = {{-60, 0, 0}, {60, 0, 0}};disc = OpenCascadeShapeRotationalSweep[shape, axisRotation, 2 Pi]OpenCascadeShapeType[disc]bmesh = OpenCascadeShapeSurfaceMeshToBoundaryMesh[disc]Show[bmesh["Wireframe"["MeshElementStyle" -> Directive[FaceForm[LightGray]]]], axisReference, ViewPoint -> {Right, Below}]完全な要素メッシュを生成し,境界メッシュの構築が意図した通りに行われたかどうかを確かめる.作成をスピードアップするために,一次メッシュを生成する.
ToElementMesh[bmesh, "MeshOrder" -> 1]現行バージョンのOpenCascadeLinkには,C面取りやフィレットを適用するために,可視化から直接特定の辺を選択する機能はない.代りに,辺の識別番号(ID)を手作業で指定する必要がある.モデルが大きくなればなるほど,辺の数も増える.このため,C面取りやフィレットをできるだけ早い段階で適用することが望ましい.具体的にどの辺にC面取りやフィレットを適用するかを求めるためには,OpenCascadeLinkを使うに記載されているように,Manipulateを使うと便利である.
OpenCascadeShapeNumberOfEdges[disc]disc2 = OpenCascadeShapeChamfer[disc, 3, {18, 20}]disc3 = OpenCascadeShapeChamfer[disc2, 2, {2, 21, 30}]disc4 = OpenCascadeShapeFillet[disc3, 1, {19, 20, 30}]disc5 = OpenCascadeShapeChamfer[disc4, 1, {45, 46}]C面取りやフィレットを作成するたびに,辺の数は増える.その結果,辺には新しいID番号が付けられる.
bmesh = OpenCascadeShapeSurfaceMeshToBoundaryMesh[disc5]Show[bmesh["Wireframe"["MeshElementStyle" -> Directive[EdgeForm[], FaceForm[LightGray]]]], axisReference, ViewPoint -> {Right, Below}]ハットセクションの穴
ハットセクションの上部の表面に,中央の穴の周りに直径15.3mmのボルト穴を開ける.それぞれのボルト穴の両側に1mmのC面取りを施す.
作成した辺を探して選択しなくて済むように,別の方法でC面取りを行う.まず「ツール」を作成して,それを適用したときにC面取りを施した穴が作成されるようにする.
作成するツールは,実際の穴となる円柱と,円柱の両端の直方体の3つの部分からなる.C面取りは,円柱と上の直方体を繋げる.このツールを作成する目的は,穴とC面取りを一挙に生成することにある.ツールを適用すると,ディスクブレーキにC面取りを施した穴が開けられる.
c1 = Cylinder[{{46.33 - 7.2, 0, 56}, {46.33, 0, 56}}, 15.3 / 2];cu1 = Cuboid[{46.33, 10, 45}, {60, -10, 66}];cu2 = Cuboid[{46.33 - 7.2, 10, 45}, {46.33 - 15, -10, 66}];regionU = RegionUnion[c1, cu1, cu2];Region[regionU]shapeu = OpenCascadeShape[regionU]chHole = OpenCascadeShapeChamfer[shapeu, 1, {25, 26}]Show[OpenCascadeShapeSurfaceMeshToBoundaryMesh[chHole]["Wireframe"["MeshElementStyle" -> Directive[EdgeForm[], FaceForm[LightGray]]]]]num = 5;
choles = OpenCascadeShapeTransformation[chHole, #]& /@ Table[RotationTransform[k * 2 π / num, {1, 0, 0}], {k, 1, num}]ブール領域とディスクプレートの差を計算することによって,穴を開ける.
disc6 = OpenCascadeShapeDifference[Flatten[{disc5, choles}]]bmesh = OpenCascadeShapeSurfaceMeshToBoundaryMesh[disc6]Show[bmesh["Wireframe"["MeshElementStyle" -> Directive[EdgeForm[], FaceForm[LightGray]]]], axisReference, ViewPoint -> {Right, Below}]隙間
ディスクの中央に円状に,長方形の切込みパターンからなる隙間を作成する.まずPolygonを使ってボスを作成し,それでディスク上に円状に切込みを入れる.ボスはy軸に対して対称となるように,それぞれ反対側に15°回転する.その後,回転軸の周りに円状のパターンを20インスタンス作成する.これらの20インスタンスがディクスプレートを切断する.
boss = Polygon[{{7.5, 154 - 22, 0}, {17.5, 154 - 22, 0}, {17.5, 154, 0}, {7.5, 154, 0}}];sboss = OpenCascadeShape[boss];
sboss2 = OpenCascadeShapeRotationalSweep[sboss, axisRotation, (15 Pi) / 180 / 2];
sboss3 = OpenCascadeShapeRotationalSweep[sboss, axisRotation, -(15 Pi) / 180 / 2];bossunion = OpenCascadeShapeUnion[sboss2, sboss3]20個の切込みのそれぞれについて,4つの角にフィレットを施す必要がある.それぞれの辺にフィレットを適用することを避けるために,半径2mmのフィレットをボスの4コーナーにまず適用する.その後,ボスとディスクプレートの差を計算する.
bossunionf = OpenCascadeShapeFillet[bossunion, 2, {34, 36, 18, 20}]Show[bmesh["Wireframe"["MeshElementStyle" -> Directive[EdgeForm[], FaceForm[LightGray]]]], OpenCascadeShapeSurfaceMeshToBoundaryMesh[bossunionf]["Wireframe"["MeshElementStyle" -> Directive[EdgeForm[], FaceForm[LightGray]]]], axisReference, ViewPoint -> Left]Show[bmesh["Wireframe"], OpenCascadeShapeSurfaceMeshToBoundaryMesh[bossunionf]["Wireframe"["MeshElementStyle" -> Directive[EdgeForm[Red]]]], axisReference, ViewPoint -> Left]num = 20;
boss20 = OpenCascadeShapeTransformation[bossunionf, #]& /@ Table[RotationTransform[k * 2 π / num, {1, 0, 0}], {k, 1, num}];disc7 = OpenCascadeShapeDifference[Flatten[{disc6, boss20}]]最後に,残りの辺を丸くするために,スロットの中央にトーラスを作成し,切込みを入れる.
torus = OpenCascadeShape[OpenCascadeTorus[{{25 / 2, 0, 0}, {70, 0, 0}}, 146.5, 12 / 2]]Show[bmesh["Wireframe"["MeshElementStyle" -> Directive[EdgeForm[], FaceForm[LightGray]]]], OpenCascadeShapeSurfaceMeshToBoundaryMesh[torus]["Wireframe"["MeshElementStyle" -> Directive[EdgeForm[], FaceForm[LightGray]]]], axisReference, ViewPoint -> Above]disc8 = OpenCascadeShapeDifference[disc7, torus]bmesh = OpenCascadeShapeSurfaceMeshToBoundaryMesh[disc8]Show[bmesh["Wireframe"["MeshElementStyle" -> Directive[EdgeForm[], FaceForm[LightGray]]]], axisReference]ディスクの表面の穴
以下の直径6mmの穴は,特定のパターンに従う.パターンは,円の弧からなる曲線に沿った5つの穴からなるもので,それぞれの穴は曲線に沿って等間隔に置かれる.このパターンは,x軸の周りで20回繰り返して置かれる.
円弧は,任意の円の外周部分に沿った2点間の曲線部分である.そのような弧を追跡するためには,円の中心,半径,中心角度を定義する必要がある.
この場合,弧は半径,中心,角度を指定することによって定義されてはいない.代りに,高さが30mm,幅が38mmの長方形内部に弧を置くことによって,これらの特性が自動的に定義されている.この長方形は,原点から88mm離れて,z軸に4.55°の角度で置かれている.
弧は,左上と右下のコーナーで長方形と交差する.こうすることで,弧の幾何学的特性は自動的に定義される.
w = 38;
h = 30;
coordinates = {{0, 0, 88}, {0, 0, 88 + w}, {0, -h, 88 + w}, {0, -h, 88}};rt = RotationTransform[-4.55 Degree, {1, 0, 0}];ctransform = rt[coordinates];rectangle = Polygon[ctransform];
Show[bmesh["Wireframe"["MeshElementStyle" -> Directive[EdgeForm[], FaceForm[LightGray]]]], Graphics3D[{rectangle}], axisReference, ViewPoint -> Left]r = (w^2/2 * h) + (h/2);弧の2つの点が同一の空間を占める半径と座標が求まったので,2つの方程式を解いて,円の中心とその角度を求めることができる.結果は,規則の集合として与えられる.
原点を中心としない円のパラメトリック方程式は以下で与えられる.
座標は2組あるので,4つの方程式を解く必要がある.解くべき変数は,
,
,
,
の4つである.
rules = Solve[C1 + r * Sin[θ1] == ctransform[[1, 2]] && C2 + r * Cos[θ1] == ctransform[[1, 3]] && C1 + r * Sin[θ2] == ctransform[[3, 2]] && C2 + r * Cos[θ2] == ctransform[[3, 3]], {C1, C2, θ1, θ2}];list = Table[{0, C1 + r * Sin[x], C2 + r * Cos[x]}, {x, θ1, θ2, (θ2 - θ1) / 4 }] /. rules[[1]];Show[Graphics3D[{PointSize[Large], Blue, Point[list]}], Graphics3D[{EdgeForm[Black], Opacity[0.1], rectangle}], ViewPoint -> Left, Boxed -> False]listCylinder = Cylinder[{{-10, 0, 0} + #, {35, 0, 0} + #}, 6 / 2]& /@ list;listShapeCylinder = OpenCascadeShape[#]& /@ listCylinder;
num = 20;
listransformCylinder = Table[OpenCascadeShapeTransformation[listShapeCylinder[[i]], #]& /@ Table[RotationTransform[k * 2 π / num, {1, 0, 0}], {k, 1, num}], {i, 1, Length[listShapeCylinder]}];disc9 = OpenCascadeShapeDifference[Flatten[{disc8, listransformCylinder}]]bmesh = OpenCascadeShapeSurfaceMeshToBoundaryMesh[disc9, "ShapeSurfaceMeshOptions" -> {"AngularDeflection" -> 0.25}]Show[
bmesh["Wireframe"["MeshElementStyle" -> Directive[FaceForm[LightGray]]]],
axisReference]mesh = ToElementMesh[bmesh, "MeshOrder" -> 1, "MaxCellMeasure" -> Infinity]Rasterize[Show[mesh["Wireframe"["MeshElementStyle" -> Directive[FaceForm[LightGray], EdgeForm[]], Lighting -> "ThreePoint"]],
mesh["Edgeframe"]
], ImageResolution -> 300]