| | classdef RC_SRP_Calculator < handle
|
| |
|
| |
|
| |
|
| |
|
| | properties
|
| |
|
| | UIFigure
|
| | GridLayout
|
| |
|
| |
|
| | LeftPanel
|
| | CenterPanel
|
| | RightPanel
|
| |
|
| |
|
| | ModeDropdown
|
| | TitleFc, FieldFc
|
| | TitleFy, FieldFy
|
| | TitleB, FieldB
|
| | TitleH, FieldH
|
| | TitleBars, FieldBars
|
| | TitleArea, FieldArea
|
| | TitleCover, FieldCover
|
| |
|
| |
|
| | TitleBars2, FieldBars2
|
| | TitleArea2, FieldArea2
|
| | TitleSpacing, FieldSpacing
|
| |
|
| |
|
| | EquationHTML
|
| |
|
| |
|
| | LogTextArea
|
| |
|
| |
|
| | LogHistory = {}
|
| | end
|
| |
|
| | methods (Access = public)
|
| |
|
| | function app = RC_SRP_Calculator()
|
| | app.createApp();
|
| | app.addLog('Calculator app initialized! Welcome.');
|
| | app.updateEquations();
|
| | end
|
| |
|
| |
|
| | function delete(app)
|
| | if isvalid(app.UIFigure)
|
| | delete(app.UIFigure);
|
| | end
|
| | end
|
| | end
|
| |
|
| | methods (Access = private)
|
| |
|
| | function createApp(app)
|
| |
|
| | peachBase = [1.00, 0.89, 0.80];
|
| | peachDark = [0.95, 0.76, 0.65];
|
| | peachLight = [1.00, 0.95, 0.90];
|
| | peachText = [0.20, 0.20, 0.20];
|
| |
|
| |
|
| | app.UIFigure = uifigure('Name', 'RC-SRP Calculator', 'Position', [100, 100, 1200, 750]);
|
| | app.UIFigure.Color = peachBase;
|
| |
|
| |
|
| | app.GridLayout = uigridlayout(app.UIFigure);
|
| | app.GridLayout.ColumnWidth = {300, '1x', 280};
|
| | app.GridLayout.RowHeight = {'1x'};
|
| | app.GridLayout.BackgroundColor = peachBase;
|
| |
|
| |
|
| | app.LeftPanel = uipanel(app.GridLayout);
|
| | app.LeftPanel.Layout.Row = 1;
|
| | app.LeftPanel.Layout.Column = 1;
|
| | app.LeftPanel.BackgroundColor = peachDark;
|
| | app.LeftPanel.Title = 'Configurable Settings';
|
| | app.LeftPanel.ForegroundColor = peachText;
|
| | app.LeftPanel.FontWeight = 'bold';
|
| |
|
| |
|
| | leftGrid = uigridlayout(app.LeftPanel);
|
| | leftGrid.ColumnWidth = {'1x', '1x'};
|
| | leftGrid.RowHeight = repmat({32}, 1, 15);
|
| | leftGrid.BackgroundColor = peachDark;
|
| |
|
| |
|
| | uilabel(leftGrid, 'Text', 'Mode:', 'FontWeight', 'bold', 'FontColor', peachText);
|
| | app.ModeDropdown = uidropdown(leftGrid, ...
|
| | 'Items', {'Singly Reinforced', 'Single Layer', 'Double Layer'}, ...
|
| | 'ValueChangedFcn', @(src, event) app.onInputChanged(), ...
|
| | 'FontColor', peachText, 'BackgroundColor', peachLight);
|
| |
|
| |
|
| | app.TitleFc = uilabel(leftGrid, 'Text', 'f(c)'' (psi):', 'FontColor', peachText, 'FontWeight', 'bold');
|
| | app.FieldFc = uieditfield(leftGrid, 'numeric', 'Value', 4000, 'ValueChangedFcn', @(src, event) app.onInputChanged());
|
| |
|
| |
|
| | app.TitleFy = uilabel(leftGrid, 'Text', 'f(y) (psi):', 'FontColor', peachText, 'FontWeight', 'bold');
|
| | app.FieldFy = uieditfield(leftGrid, 'numeric', 'Value', 60000, 'ValueChangedFcn', @(src, event) app.onInputChanged());
|
| |
|
| |
|
| | app.TitleB = uilabel(leftGrid, 'Text', 'b (in):', 'FontColor', peachText, 'FontWeight', 'bold');
|
| | app.FieldB = uieditfield(leftGrid, 'numeric', 'Value', 12, 'ValueChangedFcn', @(src, event) app.onInputChanged());
|
| |
|
| |
|
| | app.TitleH = uilabel(leftGrid, 'Text', 'h (in):', 'FontColor', peachText, 'FontWeight', 'bold');
|
| | app.FieldH = uieditfield(leftGrid, 'numeric', 'Value', 20, 'ValueChangedFcn', @(src, event) app.onInputChanged());
|
| |
|
| |
|
| | app.TitleBars = uilabel(leftGrid, 'Text', 'Number of Bars:', 'FontColor', peachText, 'FontWeight', 'bold');
|
| | app.FieldBars = uieditfield(leftGrid, 'numeric', 'Value', 4, 'ValueChangedFcn', @(src, event) app.onInputChanged());
|
| |
|
| | app.TitleArea = uilabel(leftGrid, 'Text', 'Area per A(s):', 'FontColor', peachText, 'FontWeight', 'bold');
|
| | app.FieldArea = uieditfield(leftGrid, 'numeric', 'Value', 0.79, 'ValueChangedFcn', @(src, event) app.onInputChanged());
|
| |
|
| | app.TitleCover = uilabel(leftGrid, 'Text', 'Cover (in):', 'FontColor', peachText, 'FontWeight', 'bold');
|
| | app.FieldCover = uieditfield(leftGrid, 'numeric', 'Value', 2.5, 'ValueChangedFcn', @(src, event) app.onInputChanged());
|
| |
|
| |
|
| | app.TitleBars2 = uilabel(leftGrid, 'Text', 'L2 Bars:', 'FontColor', peachText, 'Visible', 'off');
|
| | app.FieldBars2 = uieditfield(leftGrid, 'numeric', 'Value', 2, 'Visible', 'off', 'ValueChangedFcn', @(src, event) app.onInputChanged());
|
| |
|
| | app.TitleArea2 = uilabel(leftGrid, 'Text', 'L2 Area A(s):', 'FontColor', peachText, 'Visible', 'off');
|
| | app.FieldArea2 = uieditfield(leftGrid, 'numeric', 'Value', 1.00, 'Visible', 'off', 'ValueChangedFcn', @(src, event) app.onInputChanged());
|
| |
|
| | app.TitleSpacing = uilabel(leftGrid, 'Text', 'Spacing (in):', 'FontColor', peachText, 'Visible', 'off');
|
| | app.FieldSpacing = uieditfield(leftGrid, 'numeric', 'Value', 2.13, 'Visible', 'off', 'ValueChangedFcn', @(src, event) app.onInputChanged());
|
| |
|
| |
|
| | app.CenterPanel = uipanel(app.GridLayout);
|
| | app.CenterPanel.Layout.Row = 1;
|
| | app.CenterPanel.Layout.Column = 2;
|
| | app.CenterPanel.BackgroundColor = peachLight;
|
| | app.CenterPanel.Title = 'Formula & Equations';
|
| | app.CenterPanel.ForegroundColor = peachText;
|
| | app.CenterPanel.FontWeight = 'bold';
|
| |
|
| |
|
| | centerGrid = uigridlayout(app.CenterPanel);
|
| | centerGrid.ColumnWidth = {'1x'};
|
| | centerGrid.RowHeight = {'1x'};
|
| |
|
| | app.EquationHTML = uihtml(centerGrid);
|
| |
|
| |
|
| | app.RightPanel = uipanel(app.GridLayout);
|
| | app.RightPanel.Layout.Row = 1;
|
| | app.RightPanel.Layout.Column = 3;
|
| | app.RightPanel.BackgroundColor = peachDark;
|
| | app.RightPanel.Title = 'Log & Summary';
|
| | app.RightPanel.ForegroundColor = peachText;
|
| | app.RightPanel.FontWeight = 'bold';
|
| |
|
| | rightGrid = uigridlayout(app.RightPanel);
|
| | rightGrid.ColumnWidth = {'1x'};
|
| | rightGrid.RowHeight = {'1x'};
|
| |
|
| | app.LogTextArea = uitextarea(rightGrid);
|
| | app.LogTextArea.Editable = 'off';
|
| | app.LogTextArea.BackgroundColor = peachLight;
|
| | app.LogTextArea.FontColor = peachText;
|
| | app.LogTextArea.FontName = 'Courier New';
|
| | end
|
| |
|
| |
|
| | function onInputChanged(app)
|
| |
|
| | if strcmp(app.ModeDropdown.Value, 'Double Layer')
|
| | app.TitleBars2.Visible = 'on'; app.FieldBars2.Visible = 'on';
|
| | app.TitleArea2.Visible = 'on'; app.FieldArea2.Visible = 'on';
|
| | app.TitleSpacing.Visible = 'on'; app.FieldSpacing.Visible = 'on';
|
| | else
|
| | app.TitleBars2.Visible = 'off'; app.FieldBars2.Visible = 'off';
|
| | app.TitleArea2.Visible = 'off'; app.FieldArea2.Visible = 'off';
|
| | app.TitleSpacing.Visible = 'off'; app.FieldSpacing.Visible = 'off';
|
| | end
|
| |
|
| | app.addLog('Settings modified, recalculating formulas...');
|
| | app.updateEquations();
|
| | end
|
| |
|
| |
|
| | function updateEquations(app)
|
| |
|
| | fc = app.FieldFc.Value;
|
| | fy = app.FieldFy.Value;
|
| | b = app.FieldB.Value;
|
| | h = app.FieldH.Value;
|
| | n_bars = app.FieldBars.Value;
|
| | a_bar = app.FieldArea.Value;
|
| | cover = app.FieldCover.Value;
|
| | mode = app.ModeDropdown.Value;
|
| |
|
| |
|
| | fc_ksi = fc / 1000;
|
| | fy_ksi = fy / 1000;
|
| | Es_ksi = 29000;
|
| | E_cu = 0.003;
|
| |
|
| |
|
| | html = [ ...
|
| | '<html><head><style>' ...
|
| | 'body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; ' ...
|
| | 'color: #4A3B32; background-color: #FFF2E6; padding: 20px; line-height: 1.6; } ' ...
|
| | 'h2 { color: #D35400; border-bottom: 2px solid #FAD7A1; padding-bottom: 5px; } ' ...
|
| | 'h3 { color: #E67E22; margin-top: 25px; } ' ...
|
| | '@keyframes popup { from { opacity: 0; transform: translateY(15px); } to { opacity: 1; transform: translateY(0); } } ' ...
|
| | '.equation { background-color: #FFE6CC; padding: 15px; border-radius: 12px; ' ...
|
| | 'margin: 12px 0; font-family: "Courier New", Courier, monospace; font-weight: bold; ' ...
|
| | 'box-shadow: 0 4px 6px rgba(0,0,0,0.06); animation: popup 0.4s ease-out; } ' ...
|
| | '.highlight { color: #C0392B; font-size: 1.1em; } ' ...
|
| | '.success { color: #27AE60; font-weight: bold; } ' ...
|
| | '.danger { color: #E74C3C; font-weight: bold; } ' ...
|
| | '</style></head><body>' ...
|
| | ];
|
| |
|
| | html = [html, '<h2>Analysis Mode: ', mode, '</h2>'];
|
| | html = [html, '<h3>Given Variables</h3>'];
|
| | html = [html, '<div class="equation">', ...
|
| | 'f_c'' = ', num2str(fc), ' psi f_y = ', num2str(fy), ' psi<br>', ...
|
| | 'b = ', num2str(b), ' in h = ', num2str(h), ' in<br>', ...
|
| | 'Bars = ', num2str(n_bars), ' (A_b = ', num2str(a_bar), ' in²)<br>', ...
|
| | 'Cover = ', num2str(cover), ' in</div>'];
|
| |
|
| |
|
| |
|
| | beta1 = 0.85;
|
| | if fc > 4000
|
| | beta1 = 0.85 - 0.05 * ((fc - 4000) / 1000);
|
| | end
|
| | beta1 = max(beta1, 0.65);
|
| |
|
| |
|
| | limit_val = 3 * sqrt(fc);
|
| | As_min_factor = max(limit_val, 200);
|
| |
|
| |
|
| | if strcmp(mode, 'Singly Reinforced') || strcmp(mode, 'Single Layer')
|
| |
|
| | d = h - cover;
|
| | html = [html, '<h3>1. Solve Effective Depth (d)</h3>'];
|
| | html = [html, '<div class="equation">d = h - cover<br>', ...
|
| | '= ', num2str(h), ' - ', num2str(cover), '<br>', ...
|
| | '= <span class="highlight">', num2str(d), ' in</span></div>'];
|
| |
|
| | As = n_bars * a_bar;
|
| | html = [html, '<h3>2. Solve Steel Area (A_s)</h3>'];
|
| | html = [html, '<div class="equation">A_s = bars × a_bar<br>', ...
|
| | '= ', num2str(n_bars), ' × ', num2str(a_bar), '<br>', ...
|
| | '= <span class="highlight">', num2str(As), ' in²</span></div>'];
|
| |
|
| |
|
| | T = As * fy_ksi;
|
| | html = [html, '<h3>3. Assume steel yields (T = A_s · f_y)</h3>'];
|
| | html = [html, '<div class="equation">T = ', num2str(As), ' × ', num2str(fy_ksi), ' ksi<br>', ...
|
| | '= <span class="highlight">', num2str(T), ' kips</span></div>'];
|
| |
|
| |
|
| | a = T / (0.85 * fc_ksi * b);
|
| | html = [html, '<h3>4. Solve Compression Block (a & c)</h3>'];
|
| | html = [html, 'By matching concrete volume force to tension:<br>'];
|
| | html = [html, '<div class="equation">a = T / (0.85 · f_c'' · b)<br>', ...
|
| | '= <span class="highlight">', num2str(a, '%.2f'), ' in</span></div>'];
|
| |
|
| | c = a / beta1;
|
| | html = [html, '<div class="equation">c = a / β&sub1; = ', num2str(a, '%.2f'), ' / ', num2str(beta1, '%.2f'), '<br>', ...
|
| | '= <span class="highlight">', num2str(c, '%.2f'), ' in</span></div>'];
|
| |
|
| |
|
| | eps_y = fy_ksi / Es_ksi;
|
| | eps_s = ((d - c) / c) * E_cu;
|
| | html = [html, '<h3>5. Strain Compatibility Check (ε_s ≥ ε_y)</h3>'];
|
| | html = [html, '<div class="equation">ε_y = f_y / E_s = ', num2str(eps_y, '%.5f'), '<br>', ...
|
| | 'ε_s = ((d - c) / c) · ε_cu<br>', ...
|
| | '= <span class="highlight">', num2str(eps_s, '%.5f'), '</span></div>'];
|
| |
|
| | if eps_s >= eps_y
|
| | html = [html, '<p class="success">Tension steel yielded. Assumption confirmed gracefully.</p>'];
|
| | else
|
| | html = [html, '<p class="danger">Assumption failed! Steel did not yield.</p>'];
|
| | end
|
| |
|
| |
|
| | Mn = T * (d - a/2) / 12;
|
| | html = [html, '<h3>6. Nominal Moment (M_n)</h3>'];
|
| | html = [html, '<div class="equation">M_n = T · (d - a/2) / 12<br>', ...
|
| | '= <span class="highlight">', num2str(Mn, '%.2f'), ' kip-ft</span></div>'];
|
| |
|
| |
|
| | As_min = (As_min_factor / fy) * b * d;
|
| | html = [html, '<h3>7. Check Minimum Code Rules</h3>'];
|
| | html = [html, '<div class="equation">A_s,min = (', num2str(As_min_factor), ' / f_y) · b · d<br>', ...
|
| | '= <span class="highlight">', num2str(As_min, '%.2f'), ' in²</span></div>'];
|
| | if As >= As_min
|
| | html = [html, '<p class="success">A_s exceeds minimum rules. Wonderful.</p>'];
|
| | else
|
| | html = [html, '<p class="danger">A_s falls short of required minimum!</p>'];
|
| | end
|
| |
|
| |
|
| | if strcmp(mode, 'Single Layer')
|
| | eps_t = eps_s;
|
| | if eps_t >= 0.005
|
| | phi = 0.90;
|
| | elseif eps_t <= 0.002
|
| | phi = 0.65;
|
| | else
|
| | phi = 0.65 + (eps_t - 0.002) * (250/3);
|
| | end
|
| | phi_Mn = phi * Mn;
|
| |
|
| | html = [html, '<h3>8. Strength Reduction Factor (φ)</h3>'];
|
| | html = [html, '<div class="equation">ε_t = ', num2str(eps_t, '%.5f'), '<br>', ...
|
| | 'φ = <span class="highlight">', num2str(phi, '%.2f'), '</span></div>'];
|
| |
|
| | html = [html, '<h3>9. Designed Maximum Moment (φM_n)</h3>'];
|
| | html = [html, '<div class="equation">φM_n = ', num2str(phi, '%.2f'), ' × ', num2str(Mn, '%.2f'), '<br>', ...
|
| | '= <span class="highlight">', num2str(phi_Mn, '%.2f'), ' kip-ft</span></div>'];
|
| | end
|
| |
|
| | elseif strcmp(mode, 'Double Layer')
|
| |
|
| | n_bars2 = app.FieldBars2.Value;
|
| | a_bar2 = app.FieldArea2.Value;
|
| | spacing = app.FieldSpacing.Value;
|
| |
|
| |
|
| | As1 = n_bars * a_bar;
|
| | As2 = n_bars2 * a_bar2;
|
| | As = As1 + As2;
|
| |
|
| | dist1 = cover;
|
| | dist2 = cover + spacing;
|
| |
|
| | g = (As1 * dist1 + As2 * dist2) / As;
|
| | d = h - g;
|
| | d_t = h - cover;
|
| |
|
| | html = [html, '<h3>1. Resolve the Steel Centroids</h3>'];
|
| | html = [html, '<div class="equation">g = (A_s1 · y1 + A_s2 · y2) / A_s<br>', ...
|
| | '= (', num2str(As1), ' × ', num2str(dist1), ' + ', num2str(As2), ' × ', num2str(dist2), ') / ', num2str(As), '<br>', ...
|
| | '= ', num2str(g, '%.2f'), ' in</div>'];
|
| |
|
| | html = [html, '<div class="equation">d = h - g = ', num2str(h), ' - ', num2str(g, '%.2f'), '<br>', ...
|
| | '= <span class="highlight">', num2str(d, '%.2f'), ' in</span></div>'];
|
| |
|
| |
|
| | T = As * fy_ksi;
|
| | a = T / (0.85 * fc_ksi * b);
|
| | c = a / beta1;
|
| |
|
| | html = [html, '<h3>2. Solve Basic Block (Assuming Yield)</h3>'];
|
| | html = [html, '<div class="equation">T = ', num2str(T, '%.2f'), ' kips<br>', ...
|
| | 'a = ', num2str(a, '%.2f'), ' in<br>', ...
|
| | 'c = <span class="highlight">', num2str(c, '%.2f'), ' in</span></div>'];
|
| |
|
| | eps_y = fy_ksi / Es_ksi;
|
| | eps_s = ((d - c) / c) * E_cu;
|
| |
|
| | html = [html, '<h3>3. Verify the Yield Strain</h3>'];
|
| | html = [html, '<div class="equation">ε_s = ', num2str(eps_s, '%.5f'), ' | ε_y = ', num2str(eps_y, '%.5f'), '</div>'];
|
| |
|
| |
|
| | if eps_s < eps_y
|
| | html = [html, '<p class="danger">Assumption Failed! Solving via Quadratic Exact Match...</p>'];
|
| |
|
| | A_quad = 0.85 * fc_ksi * b * beta1;
|
| | B_quad = As * Es_ksi * E_cu;
|
| | C_quad = -1 * As * Es_ksi * E_cu * d;
|
| |
|
| |
|
| | roots_c = roots([A_quad, B_quad, C_quad]);
|
| | c_new = max(roots_c(roots_c > 0));
|
| | a_new = beta1 * c_new;
|
| |
|
| | html = [html, '<div class="equation">Quadratic Form Evaluated for c:<br>', ...
|
| | 'c = <span class="highlight">', num2str(c_new, '%.2f'), ' in</span><br>', ...
|
| | 'a = <span class="highlight">', num2str(a_new, '%.2f'), ' in</span></div>'];
|
| |
|
| | c = c_new;
|
| | a = a_new;
|
| |
|
| |
|
| | T = As * Es_ksi * ((d - c)/c) * E_cu;
|
| | html = [html, '<div class="equation">Accurate Balance Tension T = C_c = <span class="highlight">', num2str(T, '%.2f'), ' kips</span></div>'];
|
| | else
|
| | html = [html, '<p class="success">Assumption smoothly verified.</p>'];
|
| | end
|
| |
|
| |
|
| | Mn = T * (d - a/2) / 12;
|
| | html = [html, '<h3>4. Base Moment Geometry (M_n)</h3>'];
|
| | html = [html, '<div class="equation">M_n = T · (d - a/2) / 12<br>', ...
|
| | '= <span class="highlight">', num2str(Mn, '%.2f'), ' kip-ft</span></div>'];
|
| |
|
| |
|
| | eps_t = ((d_t - c) / c) * E_cu;
|
| | if eps_t >= 0.005
|
| | phi = 0.90;
|
| | elseif eps_t <= 0.002
|
| | phi = 0.65;
|
| | else
|
| | phi = 0.65 + (eps_t - 0.002) * (250/3);
|
| | end
|
| |
|
| | html = [html, '<h3>5. Reduction Factor for Design Result</h3>'];
|
| | html = [html, '<div class="equation">ε_t (extreme) = ', num2str(eps_t, '%.5f'), '<br>', ...
|
| | 'φ = ', num2str(phi, '%.2f'), '<br>', ...
|
| | 'φM_n = <span class="highlight">', num2str(phi*Mn, '%.2f'), ' kip-ft</span></div>'];
|
| | end
|
| |
|
| |
|
| | html = [html, '</body></html>'];
|
| | app.EquationHTML.HTMLSource = html;
|
| |
|
| |
|
| | app.addLog(sprintf('Computed [%s] cleanly. End M_n: %.2f k-ft.', mode, Mn));
|
| | end
|
| |
|
| |
|
| | function addLog(app, msg)
|
| | timestamp = datestr(now, 'HH:MM:SS');
|
| | logEntry = sprintf('[%s] %s', timestamp, msg);
|
| | app.LogHistory = [app.LogHistory; {logEntry}];
|
| |
|
| |
|
| | if length(app.LogHistory) > 40
|
| | app.LogHistory(1) = [];
|
| | end
|
| |
|
| | app.LogTextArea.Value = app.LogHistory;
|
| | end
|
| |
|
| | end
|
| | end
|
| |
|