基于MATLAB Appdesigner的自行车辐条计算器

写在最前:本人非计算机科班出身,写代码是绝对的外行,软件中肯定有一些bug和屎山代码。请各位多包涵,也欢迎各路大佬们疯狂吐槽

基于MATLAB appdesigner设计了两款自行车辐条计算器,一个普通版一个专业版,普通版只能计算常规车圈和常规编法。专业版可以计算任意的车圈和编法。目前需要安装MATLAB才能使用,之后可能会打包成单独的app。

注:此代码是基于MATLAB 2022b写的,这几年MATLAB appdesigner更新得挺多的,过老的版本可能不支持。

普通版:

普通版只能计算常规车圈和常规编法。但是请注意该版本只计算了点到点的距离,没有考虑辐条的直径和拉伸长度(一般来说实际辐条长度是计算结果再减去辐条直径的1/2)。

普通版界面如下,使用非常简洁明了,输入各项数据点击计算即可得出辐条长度和轮组示意图。


附上源代码:

通过网盘分享的文件:普通版
链接: https://pan.baidu.com/s/12HNwu8h4PKnFL7UVAVFH1Q 提取码: nsjy

classdef MajorTom_SpokeCalculate < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure           matlab.ui.Figure
        SopkeLenTextArea   matlab.ui.control.TextArea
        Label_5            matlab.ui.control.Label
        CalculateButton    matlab.ui.control.StateButton
        Spoke_NumDropDown  matlab.ui.control.DropDown
        Label_4            matlab.ui.control.Label
        WeaveDropDown      matlab.ui.control.DropDown
        Label_3            matlab.ui.control.Label
        OffsetEditField    matlab.ui.control.EditField
        Label_2            matlab.ui.control.Label
        HubDiamEditField   matlab.ui.control.EditField
        EditFieldLabel     matlab.ui.control.Label
        ERDEditField       matlab.ui.control.EditField
        Label              matlab.ui.control.Label
        UIAxes             matlab.ui.control.UIAxes
    end

    
    properties (Access = public)
        ERD
        HubDiameter
        HubHole_Num
        RimHole_Num
        Weave
        Offset
        SpokeLen
    end


    % Callbacks that handle component events
    methods (Access = private)

        % Value changed function: CalculateButton
        function CalculateButtonValueChanged(app, event)

            app.ERD = str2double(app.ERDEditField.Value);
            app.HubHole_Num = str2num(app.Spoke_NumDropDown.Value);
            app.RimHole_Num = str2num(app.Spoke_NumDropDown.Value);
            app.Weave = app.WeaveDropDown.Value;
            app.Offset = str2double(app.OffsetEditField.Value);
            app.HubDiameter = str2double(app.HubDiamEditField.Value);


            % ======= show the half wheel in uiAxes ========
            hold(app.UIAxes,'off')
            Lim = app.ERD /2 * 1.1;
            app.UIAxes.XLim = [-Lim,Lim];
            app.UIAxes.YLim = [-Lim,Lim];
            
            % ----- the Rim -----
            Rim_phi = linspace(0,2*pi,1024);
            Rim_x = app.ERD/2 .* sin(Rim_phi);
            Rim_y = app.ERD/2 .* cos(Rim_phi);
            plot(app.UIAxes,Rim_x,Rim_y)

            RimHole_phi = linspace(0,2*pi,app.RimHole_Num./2+1);
            RimHole_x = app.ERD/2 .* sin(RimHole_phi);
            RimHole_y = app.ERD/2 .* cos(RimHole_phi);
            hold(app.UIAxes,'on')
            plot(app.UIAxes,RimHole_x,RimHole_y,"Marker","o","LineStyle","none");

            % ---- the Hub -----
            Hub_phi = linspace(0,2*pi,1024);
            Hub_x = app.HubDiameter/2 .* sin(Hub_phi);
            Hub_y = app.HubDiameter/2 .* cos(Hub_phi);
            plot(app.UIAxes,Hub_x,Hub_y)

            HubHole_phi = linspace(0,2*pi,app.HubHole_Num /2+1);
            HubHole_x = app.HubDiameter/2 .* sin(HubHole_phi);
            HubHole_y = app.HubDiameter/2 .* cos(HubHole_phi);
            plot(app.UIAxes,HubHole_x,HubHole_y,"Marker","o","LineStyle","none");


            % ---- the Spoke -----

            %           |\
            %  spokeLen | \ 
            %    (2D)   |  \  SpokeLen(real)
            %           |___\
            %           Offset  

            switch app.Weave
                case '0X'
                    % Show the Spoke
                    for k = 1 : app.HubHole_Num/2
                        plot(app.UIAxes,[HubHole_x(k),RimHole_x(k)],...
                            [HubHole_y(k),RimHole_y(k)],"LineStyle","-","Color",[0.39,0.83,0.07])
                    end
                    % Calculate the length of Spoken 
                    spokeLen = sqrt( (HubHole_x(k)-RimHole_x(k)).^2 + ...
                        (HubHole_y(k)-RimHole_y(k)).^2 );   % the Spoken length in 2D plane
                    app.SpokeLen = sqrt( (app.Offset).^2 + spokeLen.^2 );

                case '1X'
                    % Show the Spoke
                    for k = 1 : app.HubHole_Num/2 /2
                        plot(app.UIAxes,[HubHole_x(2*k),RimHole_x(2*k-1)],...
                            [HubHole_y(2*k),RimHole_y(2*k-1)],"LineStyle","-","Color",[0.39,0.83,0.07])
                        plot(app.UIAxes,[HubHole_x(2*k-1),RimHole_x(2*k)],...
                            [HubHole_y(2*k-1),RimHole_y(2*k)],"LineStyle","-","Color",[0.39,0.83,0.07])
                    end
                    % Calculate the length of Spoken 
                    spokeLen = sqrt( (HubHole_x(2*k)-RimHole_x(2*k-1)).^2 + ...
                        (HubHole_y(2*k)-RimHole_y(2*k-1)).^2 );   % the Spoken length in 2D plane
                    app.SpokeLen = sqrt( (app.Offset).^2 + spokeLen.^2 );

                case '2X'
                    HubHole_x_extend = [HubHole_x,HubHole_x(2:end)];
                    HubHole_y_extend = [HubHole_y,HubHole_y(2:end)];
                    RimHole_x_extend = [RimHole_x,RimHole_x(2:end)];
                    RimHole_y_extend = [RimHole_y,RimHole_y(2:end)];
                    for k = 2 : app.HubHole_Num/2 /2 + 1
                        plot(app.UIAxes,[HubHole_x_extend(2*k),RimHole_x_extend(2*k-2)],...
                            [HubHole_y_extend(2*k),RimHole_y_extend(2*k-2)],"LineStyle","-","Color",[0.39,0.83,0.07])
                        plot(app.UIAxes,[HubHole_x_extend(2*k-1),RimHole_x_extend(2*k+1)],...
                            [HubHole_y_extend(2*k-1),RimHole_y_extend(2*k+1)],"LineStyle","-","Color",[0.39,0.83,0.07])
                    end
                    spokeLen = sqrt( (HubHole_x_extend(2*k)-RimHole_x_extend(2*k-2)).^2 + ...
                        (HubHole_y_extend(2*k)-RimHole_y_extend(2*k-2)).^2 );   % the Spoken length in 2D plane
                    app.SpokeLen = sqrt( (app.Offset).^2 + spokeLen.^2 );

                case '3X'
                    HubHole_x_extend = [HubHole_x,HubHole_x(2:end)];
                    HubHole_y_extend = [HubHole_y,HubHole_y(2:end)];
                    RimHole_x_extend = [RimHole_x,RimHole_x(2:end)];
                    RimHole_y_extend = [RimHole_y,RimHole_y(2:end)];
                    for k = 3 : app.HubHole_Num/2 /2 + 2
                        plot(app.UIAxes,[HubHole_x_extend(2*k),RimHole_x_extend(2*k-3)],...
                            [HubHole_y_extend(2*k),RimHole_y_extend(2*k-3)],"LineStyle","-","Color",[0.39,0.83,0.07])
                        plot(app.UIAxes,[HubHole_x_extend(2*k-1),RimHole_x_extend(2*k+2)],...
                            [HubHole_y_extend(2*k-1),RimHole_y_extend(2*k+2)],"LineStyle","-","Color",[0.39,0.83,0.07])
                    end
                    spokeLen = sqrt( (HubHole_x_extend(2*k)-RimHole_x_extend(2*k-3)).^2 + ...
                        (HubHole_y_extend(2*k)-RimHole_y_extend(2*k-3)).^2 );   % the Spoken length in 2D plane
                    app.SpokeLen = sqrt( (app.Offset).^2 + spokeLen.^2 );

                case '4X'
                    HubHole_x_extend = [HubHole_x,HubHole_x(2:end)];
                    HubHole_y_extend = [HubHole_y,HubHole_y(2:end)];
                    RimHole_x_extend = [RimHole_x,RimHole_x(2:end)];
                    RimHole_y_extend = [RimHole_y,RimHole_y(2:end)];
                    for k = 4 : app.HubHole_Num/2 /2 + 3
                        plot(app.UIAxes,[HubHole_x_extend(2*k),RimHole_x_extend(2*k-4)],...
                            [HubHole_y_extend(2*k),RimHole_y_extend(2*k-4)],"LineStyle","-","Color",[0.39,0.83,0.07])
                        plot(app.UIAxes,[HubHole_x_extend(2*k-1),RimHole_x_extend(2*k+3)],...
                            [HubHole_y_extend(2*k-1),RimHole_y_extend(2*k+3)],"LineStyle","-","Color",[0.39,0.83,0.07])
                    end
                    spokeLen = sqrt( (HubHole_x_extend(2*k)-RimHole_x_extend(2*k-4)).^2 + ...
                        (HubHole_y_extend(2*k)-RimHole_y_extend(2*k-4)).^2 );   % the Spoken length in 2D plane
                    app.SpokeLen = sqrt( (app.Offset).^2 + spokeLen.^2 );
            end


            % My Experimen
%             if app.ERD > 451
%                 app.SpokeLen = app.SpokeLen - 1.3;
%             else
%                 app.SpokeLen = app.SpokeLen - 0.5;
%             end
            app.SopkeLenTextArea.Value = num2str(app.SpokeLen);

          




        end
    end

    % Component initialization
    methods (Access = private)

        % Create UIFigure and components
        function createComponents(app)

            % Create UIFigure and hide until all components are created
            app.UIFigure = uifigure('Visible', 'off');
            app.UIFigure.Position = [100 100 829 486];
            app.UIFigure.Name = 'MATLAB App';

            % Create UIAxes
            app.UIAxes = uiaxes(app.UIFigure);
            title(app.UIAxes, '示意图')
            xlabel(app.UIAxes, 'X')
            ylabel(app.UIAxes, 'Y')
            zlabel(app.UIAxes, 'Z')
            app.UIAxes.TickDir = 'in';
            app.UIAxes.Position = [9 21 445 447];

            % Create Label
            app.Label = uilabel(app.UIFigure);
            app.Label.HorizontalAlignment = 'center';
            app.Label.FontSize = 16;
            app.Label.Position = [584 342 48 22];
            app.Label.Text = 'ERD';

            % Create ERDEditField
            app.ERDEditField = uieditfield(app.UIFigure, 'text');
            app.ERDEditField.FontSize = 16;
            app.ERDEditField.Position = [647 339 100 25];

            % Create EditFieldLabel
            app.EditFieldLabel = uilabel(app.UIFigure);
            app.EditFieldLabel.HorizontalAlignment = 'center';
            app.EditFieldLabel.FontSize = 16;
            app.EditFieldLabel.Position = [563 299 69 22];
            app.EditFieldLabel.Text = '花鼓直径';

            % Create HubDiamEditField
            app.HubDiamEditField = uieditfield(app.UIFigure, 'text');
            app.HubDiamEditField.FontSize = 16;
            app.HubDiamEditField.Position = [647 298 100 25];

            % Create Label_2
            app.Label_2 = uilabel(app.UIFigure);
            app.Label_2.HorizontalAlignment = 'center';
            app.Label_2.FontSize = 16;
            app.Label_2.Position = [516 258 116 22];
            app.Label_2.Text = '花鼓中心偏移量';

            % Create OffsetEditField
            app.OffsetEditField = uieditfield(app.UIFigure, 'text');
            app.OffsetEditField.FontSize = 16;
            app.OffsetEditField.Position = [647 257 100 25];

            % Create Label_3
            app.Label_3 = uilabel(app.UIFigure);
            app.Label_3.HorizontalAlignment = 'right';
            app.Label_3.FontSize = 16;
            app.Label_3.Position = [563 218 69 22];
            app.Label_3.Text = '编织方法';

            % Create WeaveDropDown
            app.WeaveDropDown = uidropdown(app.UIFigure);
            app.WeaveDropDown.Items = {'0X', '1X', '2X', '3X', '4X'};
            app.WeaveDropDown.FontSize = 16;
            app.WeaveDropDown.Position = [647 218 100 22];
            app.WeaveDropDown.Value = '0X';

            % Create Label_4
            app.Label_4 = uilabel(app.UIFigure);
            app.Label_4.HorizontalAlignment = 'right';
            app.Label_4.FontSize = 16;
            app.Label_4.Position = [536 381 96 22];
            app.Label_4.Text = '辐条数(双边)';

            % Create Spoke_NumDropDown
            app.Spoke_NumDropDown = uidropdown(app.UIFigure);
            app.Spoke_NumDropDown.Items = {'16', '20', '24', '28', '32', '36', '40', '48'};
            app.Spoke_NumDropDown.FontSize = 16;
            app.Spoke_NumDropDown.Position = [647 381 100 22];
            app.Spoke_NumDropDown.Value = '16';

            % Create CalculateButton
            app.CalculateButton = uibutton(app.UIFigure, 'state');
            app.CalculateButton.ValueChangedFcn = createCallbackFcn(app, @CalculateButtonValueChanged, true);
            app.CalculateButton.Text = '计算';
            app.CalculateButton.FontSize = 16;
            app.CalculateButton.Position = [616 83 100 28];

            % Create Label_5
            app.Label_5 = uilabel(app.UIFigure);
            app.Label_5.HorizontalAlignment = 'right';
            app.Label_5.FontSize = 16;
            app.Label_5.Position = [548 135 69 22];
            app.Label_5.Text = '辐条长度';

            % Create SopkeLenTextArea
            app.SopkeLenTextArea = uitextarea(app.UIFigure);
            app.SopkeLenTextArea.FontSize = 16;
            app.SopkeLenTextArea.Position = [632 135 131 24];

            % Show the figure after all components are created
            app.UIFigure.Visible = 'on';
        end
    end

    % App creation and deletion
    methods (Access = public)

        % Construct app
        function app = MajorTom_SpokeCalculate

            % Create UIFigure and components
            createComponents(app)

            % Register the app with App Designer
            registerApp(app, app.UIFigure)

            if nargout == 0
                clear app
            end
        end

        % Code that executes before app deletion
        function delete(app)

            % Delete UIFigure when app is deleted
            delete(app.UIFigure)
        end
    end
end

专业版:

对于一些造型比较奇特的轮组(比如CP的G3编法,或者一些脑洞大开的编法)普通版难以胜任。目前一般的方法是用CAD画图。但是需要下载学习巨大无比的CAD软件。

但是专业版可以自定义每一个孔位的位置和每一根辐条的连接,可以轻松计算出辐条长度。(虽然现在也需要下载巨大无比的MATLAB,但之后会打包成独立的软件)

专业版界面如下:


附上源代码和使用说明:

通过网盘分享的文件:专业版
链接: https://pan.baidu.com/s/1677uNL35yYfqIn0Kljha5Q 提取码: njan

需要将三个.mlapp文件放在同一文件夹中,使用时打开SpokeCalculator_Professional_MajorTom即可。使用前请务必阅读使用说明。


欢迎各位亲切友好交流!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值