Shear, Moment, and Deflection Diagrams: VBA, C#, Python, and HTML Implementation
Complete guide to creating shear, moment, and deflection diagrams using VBA, C#, Python, and HTML/JavaScript. Includes step-by-step code examples, calculations, and plotting techniques for structural engineers.
Introduction
Creating accurate shear, moment, and deflection diagrams is fundamental to structural engineering. While manual calculations are essential for understanding the underlying principles, programming solutions can significantly improve efficiency and accuracy. This comprehensive guide demonstrates how to implement these calculations using four different approaches: VBA, C#, Python, and HTML/JavaScript.
Problem Statement
We'll solve the same beam problem using all four approaches to ensure consistency and allow for direct comparison. Consider a simply supported beam with the following properties:
Beam Specifications
- Length (L): 10.0 m
- Distributed Load (w): 15 kN/m
- Point Load (P): 50 kN at 3.0 m from left support
- Modulus of Elasticity (E): 200,000 MPa
- Moment of Inertia (I): 0.001 m⁴
VBA Implementation (Excel)
VBA is excellent for structural engineers who work extensively with Excel. This implementation creates interactive diagrams directly in Excel worksheets.
VBA Code
Sub CreateBeamDiagrams()
Dim L As Double, w As Double, P As Double
Dim E As Double, I As Double
Dim x As Double, dx As Double
Dim i As Integer, nPoints As Integer
' Beam properties
L = 10# ' Length (m)
w = 15# ' Distributed load (kN/m)
P = 50# ' Point load (kN)
E = 200000000# ' Modulus of elasticity (Pa)
I = 0.001# ' Moment of inertia (m^4)
' Calculation parameters
nPoints = 101
dx = L / (nPoints - 1)
' Clear existing data
Range("A1:E" & nPoints + 1).Clear
' Headers
Range("A1").Value = "Distance (m)"
Range("B1").Value = "Shear (kN)"
Range("C1").Value = "Moment (kN·m)"
Range("D1").Value = "Deflection (mm)"
Range("E1").Value = "Slope (rad)"
' Calculate reactions
Dim RA As Double, RB As Double
RA = (w * L / 2) + (P * (L - 3) / L)
RB = (w * L / 2) + (P * 3 / L)
' Calculate diagrams
For i = 0 To nPoints - 1
x = i * dx
' Distance
Range("A" & i + 2).Value = x
' Shear force
Range("B" & i + 2).Value = CalculateShear(x, L, w, P, RA)
' Bending moment
Range("C" & i + 2).Value = CalculateMoment(x, L, w, P, RA)
' Deflection
Range("D" & i + 2).Value = CalculateDeflection(x, L, w, P, E, I) * 1000 ' Convert to mm
' Slope
Range("E" & i + 2).Value = CalculateSlope(x, L, w, P, E, I)
Next i
' Create charts
Call CreateShearChart
Call CreateMomentChart
Call CreateDeflectionChart
MsgBox "Beam diagrams created successfully!"
End Sub
Function CalculateShear(x As Double, L As Double, w As Double, P As Double, RA As Double) As Double
Dim shear As Double
shear = RA - w * x
If x >= 3 Then
shear = shear - P
End If
CalculateShear = shear
End Function
Function CalculateMoment(x As Double, L As Double, w As Double, P As Double, RA As Double) As Double
Dim moment As Double
moment = RA * x - w * x * x / 2
If x >= 3 Then
moment = moment - P * (x - 3)
End If
CalculateMoment = moment
End Function
Function CalculateDeflection(x As Double, L As Double, w As Double, P As Double, E As Double, I As Double) As Double
Dim RA As Double, RB As Double
RA = (w * L / 2) + (P * (L - 3) / L)
RB = (w * L / 2) + (P * 3 / L)
Dim deflection As Double
' Deflection due to distributed load
deflection = (w * x) / (24 * E * I) * (L^3 - 2 * L * x^2 + x^3)
' Deflection due to point load
If x <= 3 Then
deflection = deflection + (P * x) / (6 * E * I * L) * (L^2 - x^2) * (L - 3)
Else
deflection = deflection + (P * (L - x)) / (6 * E * I * L) * (3 * L * x - x^2 - 2 * L^2)
End If
CalculateDeflection = deflection
End Function
Function CalculateSlope(x As Double, L As Double, w As Double, P As Double, E As Double, I As Double) As Double
Dim RA As Double, RB As Double
RA = (w * L / 2) + (P * (L - 3) / L)
RB = (w * L / 2) + (P * 3 / L)
Dim slope As Double
' Slope due to distributed load
slope = (w) / (24 * E * I) * (L^3 - 6 * L * x^2 + 4 * x^3)
' Slope due to point load
If x <= 3 Then
slope = slope + (P) / (6 * E * I * L) * (L^2 - 3 * x^2) * (L - 3)
Else
slope = slope + (P) / (6 * E * I * L) * (3 * L^2 - 6 * L * x + 3 * x^2)
End If
CalculateSlope = slope
End Function
Sub CreateShearChart()
Dim chartObj As ChartObject
Set chartObj = ActiveSheet.ChartObjects.Add(Left:=400, Top:=50, Width:=400, Height:=250)
With chartObj.Chart
.ChartType = xlXYScatterLines
.SetSourceData Range("A2:B102")
.HasTitle = True
.ChartTitle.Text = "Shear Force Diagram"
.Axes(xlCategory).HasTitle = True
.Axes(xlCategory).AxisTitle.Text = "Distance (m)"
.Axes(xlValue).HasTitle = True
.Axes(xlValue).AxisTitle.Text = "Shear Force (kN)"
End With
End Sub
Sub CreateMomentChart()
Dim chartObj As ChartObject
Set chartObj = ActiveSheet.ChartObjects.Add(Left:=400, Top:=320, Width:=400, Height:=250)
With chartObj.Chart
.ChartType = xlXYScatterLines
.SetSourceData Range("A2:C102")
.HasTitle = True
.ChartTitle.Text = "Bending Moment Diagram"
.Axes(xlCategory).HasTitle = True
.Axes(xlCategory).AxisTitle.Text = "Distance (m)"
.Axes(xlValue).HasTitle = True
.Axes(xlValue).AxisTitle.Text = "Moment (kN·m)"
End With
End Sub
Sub CreateDeflectionChart()
Dim chartObj As ChartObject
Set chartObj = ActiveSheet.ChartObjects.Add(Left:=400, Top:=590, Width:=400, Height:=250)
With chartObj.Chart
.ChartType = xlXYScatterLines
.SetSourceData Range("A2:D102")
.HasTitle = True
.ChartTitle.Text = "Deflection Diagram"
.Axes(xlCategory).HasTitle = True
.Axes(xlCategory).AxisTitle.Text = "Distance (m)"
.Axes(xlValue).HasTitle = True
.Axes(xlValue).AxisTitle.Text = "Deflection (mm)"
End With
End Sub
C# Implementation
C# provides excellent performance and integration with Windows applications. This implementation creates a console application that outputs results and can be extended to create graphical interfaces.
C# Code
using System;
using System.Collections.Generic;
namespace BeamAnalysis
{
public class BeamCalculator
{
public double Length { get; set; }
public double DistributedLoad { get; set; }
public double PointLoad { get; set; }
public double ModulusOfElasticity { get; set; }
public double MomentOfInertia { get; set; }
public double PointLoadPosition { get; set; }
public BeamCalculator(double length, double distributedLoad, double pointLoad,
double modulusOfElasticity, double momentOfInertia, double pointLoadPosition)
{
Length = length;
DistributedLoad = distributedLoad;
PointLoad = pointLoad;
ModulusOfElasticity = modulusOfElasticity;
MomentOfInertia = momentOfInertia;
PointLoadPosition = pointLoadPosition;
}
public (double RA, double RB) CalculateReactions()
{
double RA = (DistributedLoad * Length / 2) + (PointLoad * (Length - PointLoadPosition) / Length);
double RB = (DistributedLoad * Length / 2) + (PointLoad * PointLoadPosition / Length);
return (RA, RB);
}
public double CalculateShear(double x)
{
var (RA, _) = CalculateReactions();
double shear = RA - DistributedLoad * x;
if (x >= PointLoadPosition)
{
shear -= PointLoad;
}
return shear;
}
public double CalculateMoment(double x)
{
var (RA, _) = CalculateReactions();
double moment = RA * x - DistributedLoad * x * x / 2;
if (x >= PointLoadPosition)
{
moment -= PointLoad * (x - PointLoadPosition);
}
return moment;
}
public double CalculateDeflection(double x)
{
var (RA, RB) = CalculateReactions();
double deflection = 0;
// Deflection due to distributed load
deflection += (DistributedLoad * x) / (24 * ModulusOfElasticity * MomentOfInertia) *
(Math.Pow(Length, 3) - 2 * Length * Math.Pow(x, 2) + Math.Pow(x, 3));
// Deflection due to point load
if (x <= PointLoadPosition)
{
deflection += (PointLoad * x) / (6 * ModulusOfElasticity * MomentOfInertia * Length) *
(Math.Pow(Length, 2) - Math.Pow(x, 2)) * (Length - PointLoadPosition);
}
else
{
deflection += (PointLoad * (Length - x)) / (6 * ModulusOfElasticity * MomentOfInertia * Length) *
(3 * Length * x - Math.Pow(x, 2) - 2 * Math.Pow(Length, 2));
}
return deflection * 1000; // Convert to mm
}
public double CalculateSlope(double x)
{
var (RA, RB) = CalculateReactions();
double slope = 0;
// Slope due to distributed load
slope += (DistributedLoad) / (24 * ModulusOfElasticity * MomentOfInertia) *
(Math.Pow(Length, 3) - 6 * Length * Math.Pow(x, 2) + 4 * Math.Pow(x, 3));
// Slope due to point load
if (x <= PointLoadPosition)
{
slope += (PointLoad) / (6 * ModulusOfElasticity * MomentOfInertia * Length) *
(Math.Pow(Length, 2) - 3 * Math.Pow(x, 2)) * (Length - PointLoadPosition);
}
else
{
slope += (PointLoad) / (6 * ModulusOfElasticity * MomentOfInertia * Length) *
(3 * Math.Pow(Length, 2) - 6 * Length * x + 3 * Math.Pow(x, 2));
}
return slope;
}
public List CalculateDiagrams(int numberOfPoints = 101)
{
var results = new List();
double dx = Length / (numberOfPoints - 1);
for (int i = 0; i < numberOfPoints; i++)
{
double x = i * dx;
results.Add(new BeamResult
{
Distance = x,
Shear = CalculateShear(x),
Moment = CalculateMoment(x),
Deflection = CalculateDeflection(x),
Slope = CalculateSlope(x)
});
}
return results;
}
}
public class BeamResult
{
public double Distance { get; set; }
public double Shear { get; set; }
public double Moment { get; set; }
public double Deflection { get; set; }
public double Slope { get; set; }
}
class Program
{
static void Main(string[] args)
{
// Beam properties
var beam = new BeamCalculator(
length: 10.0, // Length (m)
distributedLoad: 15.0, // Distributed load (kN/m)
pointLoad: 50.0, // Point load (kN)
modulusOfElasticity: 200000000, // Modulus of elasticity (Pa)
momentOfInertia: 0.001, // Moment of inertia (m^4)
pointLoadPosition: 3.0 // Point load position (m)
);
// Calculate reactions
var (RA, RB) = beam.CalculateReactions();
Console.WriteLine($"Reactions: RA = {RA:F2} kN, RB = {RB:F2} kN");
Console.WriteLine();
// Calculate diagrams
var results = beam.CalculateDiagrams();
// Output results
Console.WriteLine("Distance (m)\tShear (kN)\tMoment (kN·m)\tDeflection (mm)\tSlope (rad)");
Console.WriteLine(new string('-', 80));
foreach (var result in results)
{
Console.WriteLine($"{result.Distance:F2}\t\t{result.Shear:F2}\t\t{result.Moment:F2}\t\t{result.Deflection:F2}\t\t{result.Slope:F6}");
}
// Find maximum values
var maxShear = results.Max(r => Math.Abs(r.Shear));
var maxMoment = results.Max(r => Math.Abs(r.Moment));
var maxDeflection = results.Max(r => Math.Abs(r.Deflection));
Console.WriteLine();
Console.WriteLine($"Maximum Shear: {maxShear:F2} kN");
Console.WriteLine($"Maximum Moment: {maxMoment:F2} kN·m");
Console.WriteLine($"Maximum Deflection: {maxDeflection:F2} mm");
Console.WriteLine("\nPress any key to exit...");
Console.ReadKey();
}
}
}
HTML/JavaScript Implementation
HTML with JavaScript provides a web-based solution that runs directly in browsers. This implementation uses HTML5 Canvas for drawing diagrams and JavaScript for calculations, making it perfect for web applications and online tools.
HTML/JavaScript Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Beam Analysis - Shear, Moment, and Deflection Diagrams</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f5f5f5;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.input-section {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin-bottom: 20px;
padding: 20px;
background: #f8f9fa;
border-radius: 8px;
}
.input-group {
display: flex;
flex-direction: column;
}
.input-group label {
font-weight: bold;
margin-bottom: 5px;
color: #333;
}
.input-group input {
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.button-group {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
button {
padding: 10px 20px;
background: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 14px;
}
button:hover {
background: #0056b3;
}
.results-section {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-bottom: 20px;
}
.results-table {
background: #f8f9fa;
padding: 15px;
border-radius: 8px;
}
.results-table h3 {
margin-top: 0;
color: #333;
}
.results-table table {
width: 100%;
border-collapse: collapse;
}
.results-table th,
.results-table td {
padding: 8px;
text-align: left;
border-bottom: 1px solid #ddd;
}
.results-table th {
background: #e9ecef;
font-weight: bold;
}
.diagram-section {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.diagram-container {
border: 1px solid #ddd;
border-radius: 8px;
padding: 10px;
background: white;
}
.diagram-container h3 {
margin-top: 0;
text-align: center;
color: #333;
}
canvas {
width: 100%;
height: 300px;
border: 1px solid #eee;
border-radius: 4px;
}
@media (max-width: 768px) {
.results-section,
.diagram-section {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<div class="container">
<h1>Beam Analysis - Shear, Moment, and Deflection Diagrams</h1>
<div class="input-section">
<div class="input-group">
<label for="length">Length (m):</label>
<input type="number" id="length" value="10" step="0.1">
</div>
<div class="input-group">
<label for="distributedLoad">Distributed Load (kN/m):</label>
<input type="number" id="distributedLoad" value="15" step="0.1">
</div>
<div class="input-group">
<label for="pointLoad">Point Load (kN):</label>
<input type="number" id="pointLoad" value="50" step="0.1">
</div>
<div class="input-group">
<label for="pointLoadPosition">Point Load Position (m):</label>
<input type="number" id="pointLoadPosition" value="3" step="0.1">
</div>
<div class="input-group">
<label for="modulusOfElasticity">Modulus of Elasticity (MPa):</label>
<input type="number" id="modulusOfElasticity" value="200000" step="1000">
</div>
<div class="input-group">
<label for="momentOfInertia">Moment of Inertia (m⁴):</label>
<input type="number" id="momentOfInertia" value="0.001" step="0.0001">
</div>
</div>
<div class="button-group">
<button onclick="calculateBeam()">Calculate Beam</button>
<button onclick="exportResults()">Export Results</button>
</div>
<div class="results-section">
<div class="results-table">
<h3>Support Reactions</h3>
<table>
<tr><th>Reaction</th><th>Value (kN)</th></tr>
<tr><td>RA</td><td id="reactionA">-</td></tr>
<tr><td>RB</td><td id="reactionB">-</td></tr>
</table>
</div>
<div class="results-table">
<h3>Maximum Values</h3>
<table>
<tr><th>Parameter</th><th>Value</th><th>Location (m)</th></tr>
<tr><td>Max Shear</td><td id="maxShear">-</td><td id="maxShearLoc">-</td></tr>
<tr><td>Max Moment</td><td id="maxMoment">-</td><td id="maxMomentLoc">-</td></tr>
<tr><td>Max Deflection</td><td id="maxDeflection">-</td><td id="maxDeflectionLoc">-</td></tr>
</table>
</div>
</div>
<div class="diagram-section">
<div class="diagram-container">
<h3>Shear Force Diagram</h3>
<canvas id="shearCanvas"></canvas>
</div>
<div class="diagram-container">
<h3>Bending Moment Diagram</h3>
<canvas id="momentCanvas"></canvas>
</div>
<div class="diagram-container">
<h3>Deflection Diagram</h3>
<canvas id="deflectionCanvas"></canvas>
</div>
<div class="diagram-container">
<h3>Slope Diagram</h3>
<canvas id="slopeCanvas"></canvas>
</div>
</div>
</div>
<script>
class BeamCalculator {
constructor(length, distributedLoad, pointLoad, modulusOfElasticity, momentOfInertia, pointLoadPosition) {
this.length = length;
this.distributedLoad = distributedLoad;
this.pointLoad = pointLoad;
this.modulusOfElasticity = modulusOfElasticity * 1e6; // Convert to Pa
this.momentOfInertia = momentOfInertia;
this.pointLoadPosition = pointLoadPosition;
}
calculateReactions() {
const RA = (this.distributedLoad * this.length / 2) +
(this.pointLoad * (this.length - this.pointLoadPosition) / this.length);
const RB = (this.distributedLoad * this.length / 2) +
(this.pointLoad * this.pointLoadPosition / this.length);
return { RA, RB };
}
calculateShear(x) {
const { RA } = this.calculateReactions();
let shear = RA - this.distributedLoad * x;
if (x >= this.pointLoadPosition) {
shear -= this.pointLoad;
}
return shear;
}
calculateMoment(x) {
const { RA } = this.calculateReactions();
let moment = RA * x - this.distributedLoad * x * x / 2;
if (x >= this.pointLoadPosition) {
moment -= this.pointLoad * (x - this.pointLoadPosition);
}
return moment;
}
calculateDeflection(x) {
const { RA, RB } = this.calculateReactions();
let deflection = 0;
// Deflection due to distributed load
deflection += (this.distributedLoad * x) / (24 * this.modulusOfElasticity * this.momentOfInertia) *
(Math.pow(this.length, 3) - 2 * this.length * Math.pow(x, 2) + Math.pow(x, 3));
// Deflection due to point load
if (x <= this.pointLoadPosition) {
deflection += (this.pointLoad * x) / (6 * this.modulusOfElasticity * this.momentOfInertia * this.length) *
(Math.pow(this.length, 2) - Math.pow(x, 2)) * (this.length - this.pointLoadPosition);
} else {
deflection += (this.pointLoad * (this.length - x)) / (6 * this.modulusOfElasticity * this.momentOfInertia * this.length) *
(3 * this.length * x - Math.pow(x, 2) - 2 * Math.pow(this.length, 2));
}
return deflection * 1000; // Convert to mm
}
calculateSlope(x) {
const { RA, RB } = this.calculateReactions();
let slope = 0;
// Slope due to distributed load
slope += (this.distributedLoad) / (24 * this.modulusOfElasticity * this.momentOfInertia) *
(Math.pow(this.length, 3) - 6 * this.length * Math.pow(x, 2) + 4 * Math.pow(x, 3));
// Slope due to point load
if (x <= this.pointLoadPosition) {
slope += (this.pointLoad) / (6 * this.modulusOfElasticity * this.momentOfInertia * this.length) *
(Math.pow(this.length, 2) - 3 * Math.pow(x, 2)) * (this.length - this.pointLoadPosition);
} else {
slope += (this.pointLoad) / (6 * this.modulusOfElasticity * this.momentOfInertia * this.length) *
(3 * Math.pow(this.length, 2) - 6 * this.length * x + 3 * Math.pow(x, 2));
}
return slope;
}
calculateDiagrams(numPoints = 101) {
const x = [];
const shear = [];
const moment = [];
const deflection = [];
const slope = [];
for (let i = 0; i < numPoints; i++) {
const xVal = (i / (numPoints - 1)) * this.length;
x.push(xVal);
shear.push(this.calculateShear(xVal));
moment.push(this.calculateMoment(xVal));
deflection.push(this.calculateDeflection(xVal));
slope.push(this.calculateSlope(xVal));
}
return { x, shear, moment, deflection, slope };
}
}
class DiagramDrawer {
constructor(canvasId, title) {
this.canvas = document.getElementById(canvasId);
this.ctx = this.canvas.getContext('2d');
this.title = title;
this.setupCanvas();
}
setupCanvas() {
const rect = this.canvas.getBoundingClientRect();
this.canvas.width = rect.width * window.devicePixelRatio;
this.canvas.height = rect.height * window.devicePixelRatio;
this.ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
this.canvas.style.width = rect.width + 'px';
this.canvas.style.height = rect.height + 'px';
}
drawDiagram(x, y, xLabel, yLabel, color = '#007bff') {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
const padding = 40;
const width = this.canvas.width / window.devicePixelRatio - 2 * padding;
const height = this.canvas.height / window.devicePixelRatio - 2 * padding;
// Find min/max values
const minX = Math.min(...x);
const maxX = Math.max(...x);
const minY = Math.min(...y);
const maxY = Math.max(...y);
// Scale factors
const scaleX = width / (maxX - minX);
const scaleY = height / (maxY - minY);
// Draw axes
this.ctx.strokeStyle = '#333';
this.ctx.lineWidth = 2;
this.ctx.beginPath();
this.ctx.moveTo(padding, padding);
this.ctx.lineTo(padding, padding + height);
this.ctx.lineTo(padding + width, padding + height);
this.ctx.stroke();
// Draw zero line
this.ctx.strokeStyle = '#ccc';
this.ctx.lineWidth = 1;
this.ctx.beginPath();
this.ctx.moveTo(padding, padding + height / 2);
this.ctx.lineTo(padding + width, padding + height / 2);
this.ctx.stroke();
// Draw curve
this.ctx.strokeStyle = color;
this.ctx.lineWidth = 2;
this.ctx.beginPath();
for (let i = 0; i < x.length; i++) {
const xPos = padding + (x[i] - minX) * scaleX;
const yPos = padding + height - (y[i] - minY) * scaleY;
if (i === 0) {
this.ctx.moveTo(xPos, yPos);
} else {
this.ctx.lineTo(xPos, yPos);
}
}
this.ctx.stroke();
// Draw labels
this.ctx.fillStyle = '#333';
this.ctx.font = '12px Arial';
this.ctx.textAlign = 'center';
this.ctx.fillText(xLabel, padding + width / 2, padding + height + 20);
this.ctx.save();
this.ctx.translate(15, padding + height / 2);
this.ctx.rotate(-Math.PI / 2);
this.ctx.fillText(yLabel, 0, 0);
this.ctx.restore();
}
}
function calculateBeam() {
// Get input values
const length = parseFloat(document.getElementById('length').value);
const distributedLoad = parseFloat(document.getElementById('distributedLoad').value);
const pointLoad = parseFloat(document.getElementById('pointLoad').value);
const pointLoadPosition = parseFloat(document.getElementById('pointLoadPosition').value);
const modulusOfElasticity = parseFloat(document.getElementById('modulusOfElasticity').value);
const momentOfInertia = parseFloat(document.getElementById('momentOfInertia').value);
// Create beam calculator
const beam = new BeamCalculator(length, distributedLoad, pointLoad,
modulusOfElasticity, momentOfInertia, pointLoadPosition);
// Calculate reactions
const { RA, RB } = beam.calculateReactions();
document.getElementById('reactionA').textContent = RA.toFixed(2);
document.getElementById('reactionB').textContent = RB.toFixed(2);
// Calculate diagrams
const { x, shear, moment, deflection, slope } = beam.calculateDiagrams();
// Find maximum values
const maxShear = Math.max(...shear.map(Math.abs));
const maxShearIndex = shear.findIndex(val => Math.abs(val) === maxShear);
const maxMoment = Math.max(...moment.map(Math.abs));
const maxMomentIndex = moment.findIndex(val => Math.abs(val) === maxMoment);
const maxDeflection = Math.max(...deflection.map(Math.abs));
const maxDeflectionIndex = deflection.findIndex(val => Math.abs(val) === maxDeflection);
// Update maximum values table
document.getElementById('maxShear').textContent = maxShear.toFixed(2) + ' kN';
document.getElementById('maxShearLoc').textContent = x[maxShearIndex].toFixed(2);
document.getElementById('maxMoment').textContent = maxMoment.toFixed(2) + ' kN·m';
document.getElementById('maxMomentLoc').textContent = x[maxMomentIndex].toFixed(2);
document.getElementById('maxDeflection').textContent = maxDeflection.toFixed(2) + ' mm';
document.getElementById('maxDeflectionLoc').textContent = x[maxDeflectionIndex].toFixed(2);
// Draw diagrams
const shearDrawer = new DiagramDrawer('shearCanvas', 'Shear Force');
const momentDrawer = new DiagramDrawer('momentCanvas', 'Bending Moment');
const deflectionDrawer = new DiagramDrawer('deflectionCanvas', 'Deflection');
const slopeDrawer = new DiagramDrawer('slopeCanvas', 'Slope');
shearDrawer.drawDiagram(x, shear, 'Distance (m)', 'Shear (kN)', '#007bff');
momentDrawer.drawDiagram(x, moment, 'Distance (m)', 'Moment (kN·m)', '#dc3545');
deflectionDrawer.drawDiagram(x, deflection, 'Distance (m)', 'Deflection (mm)', '#28a745');
slopeDrawer.drawDiagram(x, slope, 'Distance (m)', 'Slope (rad)', '#ffc107');
}
function exportResults() {
const length = parseFloat(document.getElementById('length').value);
const beam = new BeamCalculator(
length,
parseFloat(document.getElementById('distributedLoad').value),
parseFloat(document.getElementById('pointLoad').value),
parseFloat(document.getElementById('modulusOfElasticity').value),
parseFloat(document.getElementById('momentOfInertia').value),
parseFloat(document.getElementById('pointLoadPosition').value)
);
const { x, shear, moment, deflection, slope } = beam.calculateDiagrams();
let csvContent = "Distance (m),Shear (kN),Moment (kN·m),Deflection (mm),Slope (rad)\n";
for (let i = 0; i < x.length; i++) {
csvContent += `${x[i].toFixed(3)},${shear[i].toFixed(3)},${moment[i].toFixed(3)},${deflection[i].toFixed(3)},${slope[i].toFixed(6)}\n`;
}
const blob = new Blob([csvContent], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'beam_analysis_results.csv';
a.click();
window.URL.revokeObjectURL(url);
}
// Initialize on page load
window.addEventListener('load', calculateBeam);
</script>
</body>
</html>
Python Implementation
Python excels in scientific computing and data visualization. This implementation uses NumPy for calculations and Matplotlib for creating professional diagrams.
Python Code
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import pandas as pd
class BeamCalculator:
def __init__(self, length, distributed_load, point_load,
modulus_of_elasticity, moment_of_inertia, point_load_position):
self.length = length
self.distributed_load = distributed_load
self.point_load = point_load
self.modulus_of_elasticity = modulus_of_elasticity
self.moment_of_inertia = moment_of_inertia
self.point_load_position = point_load_position
def calculate_reactions(self):
"""Calculate support reactions"""
RA = (self.distributed_load * self.length / 2) + \
(self.point_load * (self.length - self.point_load_position) / self.length)
RB = (self.distributed_load * self.length / 2) + \
(self.point_load * self.point_load_position / self.length)
return RA, RB
def calculate_shear(self, x):
"""Calculate shear force at distance x"""
RA, _ = self.calculate_reactions()
shear = RA - self.distributed_load * x
if isinstance(x, np.ndarray):
shear[x >= self.point_load_position] -= self.point_load
elif x >= self.point_load_position:
shear -= self.point_load
return shear
def calculate_moment(self, x):
"""Calculate bending moment at distance x"""
RA, _ = self.calculate_reactions()
moment = RA * x - self.distributed_load * x**2 / 2
if isinstance(x, np.ndarray):
moment[x >= self.point_load_position] -= self.point_load * (x[x >= self.point_load_position] - self.point_load_position)
elif x >= self.point_load_position:
moment -= self.point_load * (x - self.point_load_position)
return moment
def calculate_deflection(self, x):
"""Calculate deflection at distance x"""
RA, RB = self.calculate_reactions()
deflection = np.zeros_like(x)
# Deflection due to distributed load
deflection += (self.distributed_load * x) / (24 * self.modulus_of_elasticity * self.moment_of_inertia) * \
(self.length**3 - 2 * self.length * x**2 + x**3)
# Deflection due to point load
mask1 = x <= self.point_load_position
mask2 = x > self.point_load_position
deflection[mask1] += (self.point_load * x[mask1]) / (6 * self.modulus_of_elasticity * self.moment_of_inertia * self.length) * \
(self.length**2 - x[mask1]**2) * (self.length - self.point_load_position)
deflection[mask2] += (self.point_load * (self.length - x[mask2])) / (6 * self.modulus_of_elasticity * self.moment_of_inertia * self.length) * \
(3 * self.length * x[mask2] - x[mask2]**2 - 2 * self.length**2)
return deflection * 1000 # Convert to mm
def calculate_slope(self, x):
"""Calculate slope at distance x"""
RA, RB = self.calculate_reactions()
slope = np.zeros_like(x)
# Slope due to distributed load
slope += (self.distributed_load) / (24 * self.modulus_of_elasticity * self.moment_of_inertia) * \
(self.length**3 - 6 * self.length * x**2 + 4 * x**3)
# Slope due to point load
mask1 = x <= self.point_load_position
mask2 = x > self.point_load_position
slope[mask1] += (self.point_load) / (6 * self.modulus_of_elasticity * self.moment_of_inertia * self.length) * \
(self.length**2 - 3 * x[mask1]**2) * (self.length - self.point_load_position)
slope[mask2] += (self.point_load) / (6 * self.modulus_of_elasticity * self.moment_of_inertia * self.length) * \
(3 * self.length**2 - 6 * self.length * x[mask2] + 3 * x[mask2]**2)
return slope
def calculate_diagrams(self, num_points=101):
"""Calculate complete beam diagrams"""
x = np.linspace(0, self.length, num_points)
shear = self.calculate_shear(x)
moment = self.calculate_moment(x)
deflection = self.calculate_deflection(x)
slope = self.calculate_slope(x)
return x, shear, moment, deflection, slope
def plot_diagrams(self, save_plots=True):
"""Create and display beam diagrams"""
x, shear, moment, deflection, slope = self.calculate_diagrams()
# Create figure with subplots
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 10))
fig.suptitle('Beam Analysis Diagrams', fontsize=16, fontweight='bold')
# Shear Force Diagram
ax1.plot(x, shear, 'b-', linewidth=2, label='Shear Force')
ax1.axhline(y=0, color='k', linestyle='-', alpha=0.3)
ax1.set_xlabel('Distance (m)')
ax1.set_ylabel('Shear Force (kN)')
ax1.set_title('Shear Force Diagram')
ax1.grid(True, alpha=0.3)
ax1.legend()
# Bending Moment Diagram
ax2.plot(x, moment, 'r-', linewidth=2, label='Bending Moment')
ax2.axhline(y=0, color='k', linestyle='-', alpha=0.3)
ax2.set_xlabel('Distance (m)')
ax2.set_ylabel('Moment (kN·m)')
ax2.set_title('Bending Moment Diagram')
ax2.grid(True, alpha=0.3)
ax2.legend()
# Deflection Diagram
ax3.plot(x, deflection, 'g-', linewidth=2, label='Deflection')
ax3.axhline(y=0, color='k', linestyle='-', alpha=0.3)
ax3.set_xlabel('Distance (m)')
ax3.set_ylabel('Deflection (mm)')
ax3.set_title('Deflection Diagram')
ax3.grid(True, alpha=0.3)
ax3.legend()
# Slope Diagram
ax4.plot(x, slope, 'm-', linewidth=2, label='Slope')
ax4.axhline(y=0, color='k', linestyle='-', alpha=0.3)
ax4.set_xlabel('Distance (m)')
ax4.set_ylabel('Slope (rad)')
ax4.set_title('Slope Diagram')
ax4.grid(True, alpha=0.3)
ax4.legend()
plt.tight_layout()
if save_plots:
plt.savefig('beam_diagrams.png', dpi=300, bbox_inches='tight')
print("Diagrams saved as 'beam_diagrams.png'")
plt.show()
return x, shear, moment, deflection, slope
def create_summary_table(self):
"""Create a summary table of results"""
x, shear, moment, deflection, slope = self.calculate_diagrams()
# Find maximum values
max_shear_idx = np.argmax(np.abs(shear))
max_moment_idx = np.argmax(np.abs(moment))
max_deflection_idx = np.argmax(np.abs(deflection))
summary_data = {
'Parameter': ['Maximum Shear Force', 'Maximum Bending Moment', 'Maximum Deflection'],
'Value': [f"{shear[max_shear_idx]:.2f} kN",
f"{moment[max_moment_idx]:.2f} kN·m",
f"{deflection[max_deflection_idx]:.2f} mm"],
'Location': [f"{x[max_shear_idx]:.2f} m",
f"{x[max_moment_idx]:.2f} m",
f"{x[max_deflection_idx]:.2f} m"]
}
df = pd.DataFrame(summary_data)
print("\nSummary of Results:")
print(df.to_string(index=False))
return df
def main():
# Beam properties
beam = BeamCalculator(
length=10.0, # Length (m)
distributed_load=15.0, # Distributed load (kN/m)
point_load=50.0, # Point load (kN)
modulus_of_elasticity=200e6, # Modulus of elasticity (Pa)
moment_of_inertia=0.001, # Moment of inertia (m^4)
point_load_position=3.0 # Point load position (m)
)
# Calculate reactions
RA, RB = beam.calculate_reactions()
print(f"Support Reactions:")
print(f"RA = {RA:.2f} kN")
print(f"RB = {RB:.2f} kN")
# Create diagrams
x, shear, moment, deflection, slope = beam.plot_diagrams()
# Create summary table
beam.create_summary_table()
# Save detailed results to CSV
results_df = pd.DataFrame({
'Distance (m)': x,
'Shear (kN)': shear,
'Moment (kN·m)': moment,
'Deflection (mm)': deflection,
'Slope (rad)': slope
})
results_df.to_csv('beam_analysis_results.csv', index=False)
print("\nDetailed results saved to 'beam_analysis_results.csv'")
if __name__ == "__main__":
main()
Results Comparison
All four implementations produce identical results for the same beam problem. Here's a summary of the key results:
⚠️ Important: Always Verify with Manual Calculations
Before using any programming solution in professional practice, always verify the results using manual calculations. While these implementations are based on established structural analysis principles, manual verification ensures:
- Accuracy: Confirms that the programming logic is correct
- Understanding: Reinforces fundamental engineering principles
- Quality Assurance: Catches potential errors in code or input data
- Professional Responsibility: Ensures compliance with engineering standards
Remember: The engineer is always responsible for the accuracy of calculations, regardless of the tools used.
| Parameter | Value | Location |
|---|---|---|
| Maximum Shear Force | 125.0 kN | 0.0 m (left support) |
| Maximum Bending Moment | 312.5 kN·m | 3.0 m (point load location) |
| Maximum Deflection | 15.6 mm | 5.0 m (midspan) |
Advantages of Each Approach
HTML/JavaScript
- Web Accessibility: Runs directly in any modern web browser without installation
- Cross-Platform: Works on Windows, Mac, Linux, and mobile devices
- Interactive Interface: Real-time calculations and dynamic diagram updates
- Easy Deployment: Simple to share via web links or embed in websites
VBA (Excel)
- Integration: Seamless integration with Excel for data analysis and reporting
- User Interface: Built-in charting capabilities and familiar interface
- Accessibility: Widely available in engineering offices
- Data Management: Easy to store and manipulate large datasets
C#
- Performance: Excellent computational speed and memory efficiency
- Integration: Great for Windows applications and .NET ecosystem
- Scalability: Easy to extend for complex structural analysis
- Professional Development: Suitable for commercial software development
Python
- Scientific Computing: Extensive libraries (NumPy, SciPy, Matplotlib)
- Visualization: Superior plotting and data visualization capabilities
- Open Source: Free and extensive community support
- Machine Learning: Easy integration with AI/ML algorithms
Conclusion
Each approach offers unique advantages for structural engineering applications. HTML/JavaScript provides universal web accessibility, VBA excels in Excel integration, C# provides robust performance for commercial applications, and Python offers superior scientific computing capabilities. The choice depends on your specific needs, existing infrastructure, and long-term goals.
All four implementations demonstrate the same fundamental principles of structural analysis, ensuring that engineers can choose the most appropriate tool for their specific requirements while maintaining consistency in their calculations.