在Onshape上繪製漸開線齒輪以及利用參數繪製齒輪

給定模數、齒數及壓力角後,繪製出節圓、齒頂圓、齒根圓及基圓

接著從基圓上拉出漸開線,接著繪製到齒根的垂直線,並對稱草圖,即可擠出齒型

接著即可加入參數繪製齒輪,可到老師網誌參考程式碼,亦可搜尋spur的FeatureScript

以下為對應的 FeatureScript 正齒輪輪廓繪圖程式碼:

FeatureScript 581;
import(path : "onshape/std/geometry.fs", version : "581.0");

annotation { "Feature Type Name" : "Spur2" } export const spur = defineFeature(function(context is Context, id is Id, definition is map) precondition { // 正齒輪齒數, 由使用者輸入, 型別為整數 annotation { "Name" : "Number of Gear Tooth" } isInteger(definition.n, POSITIVE_COUNT_BOUNDS); // 正齒輪模數, 由使用者輸入, 型別為長度, 為內建尺寸單位 annotation { "Name" : "Module" } isLength(definition.module, LENGTH_BOUNDS); // 正齒輪壓力角, 由使用者輸入, 型別為角度, 為內建角度單位 annotation { "Name" : "Pressure Angle" } isAngle(definition.pa, ANGLE_360_BOUNDS); // 正齒輪圓心座標點, 由使用者選擇 annotation { "Name" : "Select a point", "Filter" : EntityType.VERTEX, "MaxNumberOfPicks" : 1 } definition.point is Query; } { // Precondition 中的查詢, 需要 evalue 才能傳回對應的 entity var location = evaluateQuery(context, definition.point)[0]; // location 變數為點座標對應的 entity, 必須透過 evVetexPoint 的評量才能傳回對應的點座標 var center3D = evVertexPoint(context, { "vertex" : location });

    // 作圖平面利用 evOwnerSketch 評量, 與 location entity 同一個平面
    var sketchPlane = evOwnerSketchPlane(context, {
            "entity" : location
    });
    // 作圖畫
    const gearSketch = newSketchOnPlane(context, id + "gearSketch", {
            "sketchPlane" : sketchPlane
    });
    // 利用 worldToPlane, 將 center3D 轉換為 sketchPlane 上的平面點座標
    const center2D = worldToPlane(sketchPlane, center3D);
    //print(center2D);
    // 漸開線近似點數
    var imax = 5;
    // 使用者所選的齒輪圓心 x 座標
    var midx = center2D[0];
    // 使用者所選的齒輪圓心 y 座標
    var midy = center2D[1];
    // 齒數
    var n = definition.n;
    // 模數
    var m = definition.module;
    // 壓力角, 單位為角度
    var pa = definition.pa;
    // 齒輪的節圓半徑
    var rp = m*n/2;
    skLineSegment(gearSketch, "line", {
    "start" : vector(midx,midy),
    "end" : vector(midx,midy+rp)
    });
    // 齒根
    var d = 2.5*rp/n;
    // 齒頂圓半徑
    var ra = rp + m;
    // 基圓半徑
    var rb = rp*cos(pa);
    //print(rb);
    // 齒根圓半徑
    var rd = rp - d;
    // 分段後齒頂與齒根半徑差增量
    var dr = 0*meter;
    // 若 rb > rd 時從基圓開始繪製漸開線, 但是若 rd > rb, 則漸開線從 rd 畫到齒頂圓
    if (rd > rb)
    {
        // 半徑差的分段, 由齒根圓到齒頂圓
        dr = (ra-rd)/imax;
    }
    else
    {
        // 半徑差的分段, 由基圓到齒頂圓
        dr = (ra-rb)/imax;
    }
    // PI 為實數值沒有單位, tan(pa)也沒有單位, pa 已經設定單位為 degree, 這裡為了與 radian 運算
    // 系統會自動轉為 radian
    var rot = PI/(2*n)*radian;
    //print(sigma);
    // 分別用來設定 entity id 用的增量變數
    var nameId = 1;
    var nameId2 = 1;
    var r = 0*meter;
    // theta 為浮點數字
    var theta = 0;
    var inv = 0*radian;
    var inc = 0*radian;
    // 當 r=rp 時 ,計算 inv_rp 用來旋轉漸開線用
    // theta 為沒有單位的實數
    theta = sqrt((rp*rp)/(rb*rb)-1);
    // atan(theta) 為 radian
    var inv_rp = theta*radian-atan(theta);
    // 漸開線上點的 x 座標
    var xpt = 0*meter;
    // 漸開線上點的 y 座標
    var ypt = 0*meter;
    // 左側漸開線第1點座標 left first x and y
    var lfx = 0*meter;
    var lfy = 0*meter;
    // 右側漸開線第1點座標 right first x and y
    var rfx = 0*meter;
    var rfy = 0*meter;
    // 左側齒根圓上點座標 left x of dedendum point
    var lxd = 0*meter;
    var lyd = 0*meter;
    // 右側齒根圓上點座標 right x of dedendum point
    var rxd = 0*meter;
    var ryd = 0*meter;
    // 左側齒根圓上點座標 right x of dedendum point (advanced)
    var lxd_ad = 0*meter;
    var lyd_ad = 0*meter;
    var inc_ad = 0*radian;
    for (var j=0;j<n;j+=1)
    {
        // 當 j 增量時, 按照齒數輪廓繞行旋轉增量角度
        inc = (2.*j*PI/n)*radian;
        inc_ad = (2.*(j+1)*PI/n)*radian;
        if (rd>rb)
        {
            // 當齒根半徑因為齒數增多後大於基圓半徑時, 漸開線從齒根圓長起
            theta = sqrt((rd*rd)/(rb*rb)-1.);
            inv = theta*radian-atan(theta);
            // 左側漸開線第1點座標
            // 左側輪廓線配合逆時針旋轉 inc 角度
            lfx = midx+rd*sin(inv-rot-inv_rp+inc);
            lfy = midy+rd*cos(inv-rot-inv_rp+inc);
            lxd = lfx;
            lyd = lfy;
            lxd_ad = midx+rd*sin(inv-rot-inv_rp+inc_ad);
            lyd_ad = midy+rd*cos(inv-rot-inv_rp+inc_ad);
            // 右側漸開線第1點座標
            // 右側輪廓線配合順時針旋轉 inc 角度
            rfx = midx-rd*sin(inv-rot-inv_rp-inc);
            rfy = midy+rd*cos(inv-rot-inv_rp-inc);
            rxd = rfx;
            ryd = rfy;
            // 齒根圓上的直線 on dedendum points
            skLineSegment(gearSketch, "line_dd" ~ nameId, {
            "start" : vector(rxd,ryd),
            "end" : vector((lxd_ad),(lyd_ad))
            });
        }
        else
        {
            // 當基圓半徑大於齒根圓時, 漸開線從基圓長起
            theta = sqrt((rb*rb)/(rb*rb)-1.);
            inv = theta*radian-atan(theta);
            // 左側漸開線第1點座標
            lfx = midx+rb*sin(inv-rot-inv_rp+inc);
            lfy = midy+rb*cos(inv-rot-inv_rp+inc);
            lxd = midx+rd*sin(inv-rot-inv_rp+inc);
            lyd = midy+rd*cos(inv-rot-inv_rp+inc);
            lxd_ad = midx+rd*sin(inv-rot-inv_rp+inc_ad);
            lyd_ad = midy+rd*cos(inv-rot-inv_rp+inc_ad);
            // 從基圓點到齒根圓點, 畫直線 left from base point to dedendum point
            skLineSegment(gearSketch, "line_lbd" ~ nameId, {
            "start" : vector(lfx,lfy),
            "end" : vector((lxd),(lyd))
            });
            // 右側漸開線第1點座標
            rfx = midx-rb*sin(inv-rot-inv_rp-inc);
            rfy = midy+rb*cos(inv-rot-inv_rp-inc);
            rxd = midx-rd*sin(inv-rot-inv_rp-inc);
            ryd = midy+rd*cos(inv-rot-inv_rp-inc);
            // 從基圓點到齒根圓點, 畫直線 right from base point to dedendum point
            skLineSegment(gearSketch, "line_rbd" ~ nameId, {
            "start" : vector(rfx,rfy),
            "end" : vector((rxd),(ryd))
            });
            // 齒根圓上的直線 on dedendum points
            skLineSegment(gearSketch, "line_dd" ~ nameId, {
            "start" : vector(rxd,ryd),
            "end" : vector((lxd_ad),(lyd_ad))
            });
        }

        for (var i=1; i<imax+1; i+= 1)
        {
            // 先處理中線左側的漸開線
            // 當 rd 大於 rb 時, 漸開線並非畫至 rb, 而是 rd
            if (rd>rb)
            {
                r = rd+i*dr;
            }
            else
            {
                r = rb+i*dr;
            }
            theta = sqrt((r*r)/(rb*rb)-1);
            var inv = theta*radian-atan(theta);
            // 漸開線上的點座標
            xpt = midx+r*sin(inv-rot-inv_rp+inc);
            ypt = midy+r*cos(inv-rot-inv_rp+inc);
            // lxd, lyd 為漸開線上的繪線起點座標
            skLineSegment(gearSketch, "lineb" ~ nameId, {
            "start" : vector(lfx,lfy),
            "end" : vector((xpt),(ypt))
            });
            // 更新漸開線點座標
            lfx = xpt;
            lfy = ypt;
            nameId += 1;
        }
        // 紀錄左側漸開線的最後一點, 也就是齒頂圓上的點座標
        var lastlx = xpt;
        var lastly = ypt;
        // another side
        for (var i=1; i<imax+1; i+= 1)
        {
            if (rd>rb)
            {
                r = rd+i*dr;
            }
            else
            {
                r = rb+i*dr;
            }
            theta = sqrt((r*r)/(rb*rb)-1);
            var inv = theta*radian-atan(theta);
            // 漸開線上的點座標
            xpt = midx-r*sin(inv-rot-inv_rp-inc);
            ypt = midy+r*cos(inv-rot-inv_rp-inc);
            // rxd, ryd 為漸開線上的繪線起點座標
            skLineSegment(gearSketch, "linec" ~ nameId, {
            "start" : vector(rfx,rfy),
            "end" : vector((xpt),(ypt))
            });
            // 更新漸開線點座標
            rfx = xpt;
            rfy = ypt;
            nameId += 1;
        }
        var lastrx = xpt;
        var lastry = ypt;
        // 齒頂連線
        skLineSegment(gearSketch, "lined" ~ nameId2, {
        "start" : vector(lastlx,lastly),
        "end" : vector(lastrx,lastry)
        });
        nameId2 += 1;
    }
skSolve(gearSketch);
});

注意事項

1.當齒根半徑因為齒數增多後大於基圓半徑時, 漸開線從齒根圓長起

2.當基圓半徑大於齒根圓時, 漸開線從基圓長起

零件連結 :Onshape齒輪

練習影片

40423245機械設計工程系 - 協同產品設計實習課程W12-在Onshape上繪製漸開線齒輪 from 40423245 on Vimeo.

40423245機械設計工程系 - 協同產品設計實習課程W12-利用參數繪製齒輪 from 40423245 on Vimeo.

參考資料

Onshape Featurescript Spur Gear 輪廓繪圖

Gear Drawing with Bézier Curves