Darwin ยท Dolan ยท Nilson โ€” 15th Ed.

Chapter 4
Flexural Analysis
& Design of Beams

The heart of RC design โ€” master how beams bend, when they fail, and how to calculate the exact amount of steel they need.

โฌก Complete โ€” All 7 Sections
4.1 โ€” Introduction 4.2 โ€” Beam Behavior 4.3 โ€” Rectangular Design 4.4 โ€” Design Aids 4.5 โ€” Practical Details 4.6 โ€” Doubly Reinforced 4.7 โ€” T-Beams
ยง 4.1

Introduction

Chapter 4 is where design becomes real. Chapter 3 gave you the theory โ€” now you'll use it to calculate exactly how much steel a beam needs and how thick it should be. These tools are used every time a concrete floor, bridge, or parking garage is designed.

Flexural design answers one central question: given the loads a beam must carry, what cross-section dimensions and how much steel reinforcement are required so the beam is safe yet economical?

Think of a wooden shelf sagging under too many books. The shelf bends โ€” the top gets squeezed (compression) and the bottom stretches (tension). If the wood is weak in tension, it cracks at the bottom. Concrete is that same shelf โ€” strong in compression but brittle in tension. Steel bars embedded at the bottom take over the tension job. The entire art of Chapter 4 is figuring out how many steel "books" can act as tension carriers.

๐Ÿ“
Analysis
Given a beam with known dimensions and steel โ€” what moment can it safely carry?
โš™๏ธ
Design
Given a required moment demand โ€” what dimensions and how much steel are needed?
๐Ÿ“‹
ACI 318 Rules
Code limits ensure beams fail ductilely โ€” with warning, not suddenly.
๐Ÿ”‘ The Core Design Inequality

Every design check in this chapter comes down to one statement:

ฯ†Mn โ‰ฅ Muโ€” strength provided must exceed strength required
SymbolMeaningTypical Value
MuFactored moment demand (from loads ร— load factors)Calculated from analysis
MnNominal moment capacity of the sectionCalculated from section geometry
ฯ†Strength reduction factor0.90 for flexure (tension-controlled)
ยง 4.2

Reinforced Concrete
Beam Behavior

Before you can calculate beam capacity, you must understand how a beam fails. RC beams don't just snap โ€” they go through predictable stages as load increases. Knowing these stages is what separates engineers who understand the code from those who just apply formulas blindly.

Loading an RC beam is like inflating a balloon until it bursts. At first, everything stretches elastically and nothing cracks. As you add more load, the tension side cracks โ€” but the steel wires inside the balloon (the rebar) hold it together. Finally, either the steel wire yields (ductile failure, with warning) or the balloon skin ruptures suddenly (brittle concrete crushing). Engineers design for the first type, always.

Three Stages of RC Beam Loading โ€” Click Each Stage

The Whitney Rectangular Stress Block

At ultimate load, the concrete stress distribution above the neutral axis is a curved, parabolic shape. Whitney's brilliant insight: replace the complicated curve with an equivalent rectangle that gives the same total compression force and the same centroid location. This makes the math tractable without losing accuracy.

From Real Stress Distribution โ†’ Whitney Rectangle
N.A. Real stress (parabola) 0.85f'c As T = Asยทfy โ‰ก Whitney's simplification a c N.A. 0.85f'c C As T = Asยทfy d โˆ’ a/2 Whitney Rectangle (equivalent) KEY RELATIONSHIPS Depth of stress block: a = Asfy / (0.85f'c ยท b) Relationship a to c : a = ฮฒโ‚ ยท c ฮฒโ‚ factor (ACI 318): 0.85 if f'c โ‰ค 4000 psi โˆ’0.05 per 1000 psi above 4000 minimum ฮฒโ‚ = 0.65
๐Ÿงฎ Nominal Moment Capacity โ€” The Core Formula

From equilibrium of the internal couple (C = T, and Mn = C ร— moment arm):

T = As ยท fytension force in steel at yield
C = 0.85 ยท f'c ยท a ยท bcompression force in concrete block
a = Asยทfy / (0.85ยทf'cยทb)depth of stress block (from T = C)
Mn = As ยท fy ยท (d โˆ’ a/2)โ† The Main Event

Where d = effective depth (top fiber to steel centroid), b = beam width, As = steel area.

Two Ways a Beam Can Fail โ€” and Why One is Acceptable

โœ… Tension-Controlled (Ductile)
Steel yields first. The beam deflects visibly before collapse. Cracks open wide โ€” giving warning. Engineers design all beams to fail this way.

ACI requires: ฮตt โ‰ฅ 0.005 โ†’ ฯ† = 0.90
โŒ Compression-Controlled (Brittle)
Concrete crushes before steel yields. Sudden, no warning. Occurs when too much steel is packed in (over-reinforced). This is prohibited by ACI code.

ACI prohibits: ฮตt < 0.004 at nominal strength
Strain Distribution at Ultimate โ€” the ฮต = 0.003 Rule
N.A. (c) Cross-section c dโˆ’c โ†ฮตcu = 0.003 (assumed constant for all cases) ฮตt Strain ACI STRAIN LIMITS (ฮตt at steel) ฮตt โ‰ฅ 0.005 โ†’ Tension-Controlled โ†’ ฯ† = 0.90 0.004 โ‰ค ฮตt < 0.005 โ†’ Transition zone ฯ† interpolates between 0.75 and 0.90 ฮตt < 0.004 โ†’ NOT PERMITTED by ACI (too much steel, brittle failure risk) Strain compatibility: ฮตt = 0.003ยท(dโˆ’c)/c
โœฆ Quick Check
A beam has ฮตt = 0.006 at the steel level when the concrete reaches crushing strain. How does ACI 318 classify this section?
ยง 4.3

Design of Tension-Reinforced
Rectangular Beams

This section hands you the complete design toolkit: how to pick beam dimensions, how to find the required steel area, and how to verify ACI's ฯ limits. Get comfortable here โ€” this exact procedure repeats in almost every beam you'll ever design.

The Reinforcement Ratio ฯ

The reinforcement ratio ฯ (rho) is simply the fraction of the beam's cross-section that is steel. It is the single most important parameter controlling beam behavior.

ฯ = As / (b ยท d)dimensionless, typically 0.005 to 0.02
Reinforcement Ratio Limits โ€” Where Does Your ฯ Fall?

Adjust material strengths to see how ACI limits shift. Enter your ฯ to check feasibility.

f'c (psi) 4000
fy (psi) 60,000
Your ฯ (%) 1.0
0% ฯmin ฯmax 3.5%
ฯmin
โ€”
ฯmax (ฮตt=0.004)
โ€”
Your ฯ
โ€”
Status
โ€”
๐Ÿ“ Reinforcement Ratio Limits โ€” ACI 318
LimitFormulaReason
ฯmin max(3โˆšf'c/fy , 200/fy) Minimum steel to prevent sudden brittle failure right at cracking
ฯ for ฮตt=0.005 (0.85ฮฒโ‚f'c/fy)ยท[3/8] Upper limit for full ฯ†=0.90 (tension-controlled)
ฯmax (ฮตt=0.004) (0.85ฮฒโ‚f'c/fy)ยท[3/7] Absolute ACI maximum โ€” beam still ductile at this limit

Interactive Beam Capacity Calculator

Compute Mn and ฯ†Mn for Any Rectangular Section

Adjust the parameters โ€” the capacity and stress block update instantly.

b โ€” width (in) 12
d โ€” eff. depth (in) 20
As โ€” steel area (inยฒ) 2.40
f'c (psi) 4000
fy (psi) 60,000
a (stress block)
โ€”
ฮฒโ‚
โ€”
c (N.A. depth)
โ€”
ฮตt (steel strain)
โ€”
ฯ† factor
โ€”
ฯ actual
โ€”
Mn (kยทft)
โ€”
ฯ†Mn (kยทft)
โ€”

The Complete Design Procedure

There are two types of design problems: Analysis (section is given, find capacity) and Design (demand is given, find the section). Here is the step-by-step for each.

ANALYSIS PROBLEM
Given: b, d, As, f'c, fy โ€” Find: ฯ†Mn
  1. Compute a = Asfy/(0.85f'cb)
  2. Compute Mn = Asfy(d โˆ’ a/2)
  3. Compute ฮตt = 0.003(dโˆ’c)/c where c = a/ฮฒโ‚
  4. Determine ฯ† (0.90 if ฮตt โ‰ฅ 0.005)
  5. Report ฯ†Mn
  6. Check ฯ โ‰ฅ ฯmin
DESIGN PROBLEM
Given: Mu, f'c, fy โ€” Find: b, d, As
  1. Choose target ฯ (โ‰ˆ 0.5โ€“0.6 ร— ฯmax for economy)
  2. Compute Rn = ฯfy(1 โˆ’ ฯfy/1.7f'c)
  3. From Mu = ฯ†ยทRnยทbยทdยฒ, solve for bยทdยฒ
  4. Choose b; solve for d; round up
  5. Compute required As = ฯยทbยทd
  6. Select bars; verify ฯ†Mn โ‰ฅ Mu; check ฯmin
โœฆ Quick Check
A beam has b = 12 in, d = 22 in, As = 3.0 inยฒ, f'c = 4000 psi, fy = 60,000 psi. What is the depth of the Whitney stress block a?
โœฆ Quick Check
Why does ACI 318 require ฯ โ‰ฅ ฯmin? What failure does this prevent?
ยง 4.4

Design Aids

The formulas in ยง4.3 involve an implicit circular dependency โ€” you need As to find a, but you need a to find the required As. Design aids (tables and charts) break this loop by pre-computing useful coefficients so you can solve problems in one pass without iteration.

Think of design aids like a conversion chart. Instead of typing miles ร— 1.609344 every time, you glance at a table and read off the answer. Design aids for beams are the same โ€” they encode the beam equations so you look up a coefficient, multiply, and you're done.

The Flexural Resistance Factor Rn

The design equation can be rewritten as:

Mu = ฯ† ยท Rn ยท b ยท dยฒ
Rn = ฯ ยท fy ยท (1 โˆ’ ฯยทfy / 1.7f'c)units: psi

This means: once you pick ฯ (and know f'c, fy), you can look up Rn in a table, then solve bยทdยฒ = Mu / (ฯ†ยทRn) directly. No iteration needed.

Live Rn Table Generator

Select material strengths to generate a design aid table โ€” just like Table A.7 in the textbook.

f'c (psi) 4000
fy (psi) 60,000
ฯ (%) Rn (psi) Ku = ฯ†Rn (psi) ฯ†=0.90 Strain ฮตt Status

Usage: Compute Mu (kยทft) โ†’ convert to lbยทin โ†’ solve bยทdยฒ = Mu/(ฯ†ยทRn) in inยณ โ†’ choose b, find d.

The Rnโ€“ฯ Curve

Rn vs ฯ Chart โ€” with ฯmin and ฯmax Boundaries

The curve shows how increasing ฯ gives diminishing returns in Rn โ€” the relationship is not linear because of the a/2 correction. Red dashed lines = ACI limits.

๐Ÿ“‹ Key Takeaways from Design Aids
โœฆ Quick Check
For f'c = 4000 psi and fy = 60,000 psi, a designer picks ฯ = 0.012 and needs Mu = 200 kยทft. Using Rn โ‰ˆ 633 psi (from table) and ฯ† = 0.90, what is the required bยทdยฒ value?
โœฆ Summary โ€” Sections 4.1 through 4.4
ยง4.1
Design goal: ฯ†Mn โ‰ฅ Mu. Two modes: analysis (find capacity) and design (find section).
ยง4.2
3 stages of loading. Whitney stress block: a = Asfy/(0.85f'cb). Mn = Asfy(d โˆ’ a/2). Must be tension-controlled (ฮตt โ‰ฅ 0.005).
ยง4.3
ฯ = As/bd. Must be between ฯmin (sudden cracking) and ฯmax (brittle crushing). Full design and analysis procedures.
ยง4.4
Rn = ฯfy(1 โˆ’ ฯfy/1.7f'c). Use Mu = ฯ†ยทRnยทbยทdยฒ to size beam without iteration. Aim for ฯ โ‰ˆ 50โ€“60% of ฯmax.
โ†“ Continue below โ†’ ยง4.5 Practical Details ยท ยง4.6 Doubly Reinforced Beams ยท ยง4.7 T-Beams
ยง 4.5

Practical Considerations
in the Design of Beams

The formulas in ยง4.3 give you As and d on paper โ€” but a real beam has to be physically built. Bars need space to fit. Concrete must flow around them. Cover protects steel from corrosion and fire. This section translates calculated numbers into a buildable beam.

You've calculated you need a 3-foot door opening โ€” but lumber comes in fixed sizes, hinges have specific positions, and you need room to swing the door. Practical beam design is the same: bars come in discrete sizes, beams are built to round dimensions, and code rules dictate minimum gaps. You don't get to specify 11.3 inches โ€” you round up to 12.

Concrete Cover

Cover is the distance from the outer face of the beam to the surface of the nearest bar. It protects steel from corrosion, fire, and bond failure near the surface.

๐Ÿ“ ACI 318 Minimum Cover Requirements
Exposure ConditionMin. CoverNotes
Interior, not exposed โ€” bars #6โ€“#181ยฝ inTypical interior beams & slabs
Interior, not exposed โ€” bars #5 and smallerยพ inSlabs, walls with small bars
Exposed to weather โ€” bars #6โ€“#182 inExterior beams, retaining walls
Exposed to weather โ€” bars #5 and smaller1ยฝ in 
Cast against and in contact with earth3 inFootings โ€” no formwork between bar and soil

Total Depth h vs. Effective Depth d

Design formulas use d โ€” but you specify h on drawings. The relationship depends on cover, stirrup size, and bar diameter:

d = h โˆ’ cover โˆ’ dstirrup โˆ’ dbar/2
h โ†” d Calculator โ€” Find Your Effective Depth

Specify the beam's total depth and detailing โ€” get the effective depth d used in all Mn calculations.

Total depth h (in) 24
Cover (in) 1.5
Stirrup dst (in) 0.375
Main bar db (in) 1.000
Effective depth d
โ€”
d/h ratio
โ€”
CG from bottom
โ€”
Rule of thumb
d โ‰ˆ 0.85โ€“0.90h

Bar Spacing Requirements

ACI 318 requires clear spacing between parallel bars to satisfy all three rules simultaneously:

sclear โ‰ฅ max( db , 1 in , 4/3ยทdagg )
RULE 1
โ‰ฅ db
Bar diameter โ€” concrete must flow around each bar
RULE 2
โ‰ฅ 1 inch
Absolute minimum regardless of bar size
RULE 3
โ‰ฅ 4/3 dagg
Aggregate must physically fit between bars
๐Ÿ“ Quick Proportioning Guidelines
ParameterGuidelineReason
Beam width bb โ‰ˆ 0.4โ€“0.6 ร— dEfficient aspect ratio; common values 10, 12, 14, 16 in
Total depth hh = d + 2.5 to 3.5 inCover + stirrup + half bar; round up to nearest inch
Min h for deflectionh โ‰ฅ L/16 (simple span)ACI Table 9.3.1.1 โ€” avoids explicit deflection check
Bar layers1 or 2 preferredMore layers reduce d and complicate detailing
โœฆ Quick Check
A beam uses 1.5 in cover, #3 stirrups (dst = 0.375 in), and #8 main bars (db = 1.0 in). If h = 20 in, what is the effective depth d?
ยง 4.6

Rectangular Beams with Tension
& Compression Reinforcement

Sometimes you cannot increase beam depth โ€” a parking garage has a fixed floor-to-floor height, or the architect has fixed the soffit. If a singly-reinforced beam can't carry Mu without exceeding ฯmax, adding compression steel A's near the top unlocks extra capacity within the same envelope by allowing more tension steel As at the bottom.

Imagine a pulley system where the main rope is already maxed out. You can't strengthen that rope โ€” but you can add a second rope on the other side of the pulley to share the load. Compression steel is that second rope: it opens up a new load path and lets the beam carry more moment in the same cross-section height.

Doubly Reinforced Beam โ€” Decomposed into Two Internal Couples
0.85f'c N.A. A's As = Block 1 Cโ‚=0.85f'cยทaยทb Tโ‚=As1ยทfy dโˆ’a/2 Couple 1 โ†’ Mn1 + Cโ‚‚=A'sยทf's Tโ‚‚=As2ยทfy dโˆ’d' Couple 2 โ†’ Mn2 Mn = Mn1 + Mn2 Mn1 = As1ยทfyยท(d โˆ’ a/2) Mn2 = A'sยทf'sยท(d โˆ’ d')

Does the Compression Steel Actually Yield?

The key question: is f's = fy valid? If the neutral axis is high (small c), the strain at A's depth may not reach yield strain.

ฮต's = 0.003 ยท (c โˆ’ d') / cstrain in compression steel
f's = min( Es ยท ฮต's , fy )capped at fy (29,000 ร— ฮต's vs fy)
โœ… ฮต's โ‰ฅ fy/Es โ†’ A's has yielded
Use f's = fy. Equilibrium gives:
a = (Asโˆ’A's)fy / (0.85f'cยทb)
Simple one-pass calculation.
โš  ฮต's < fy/Es โ†’ A's has NOT yielded
Use f's = Esยทฮต's. Equilibrium becomes quadratic in c. More work โ€” but same principle.
๐Ÿงฎ Analysis Procedure โ€” Doubly Reinforced (assuming A's yields)
  1. Assume A's yields. Set T = C1 + C2: Asยทfy = 0.85f'cยทฮฒโ‚cยทb + A'sยทfy โ†’ solve for c
  2. Verify: ฮต's = 0.003(cโˆ’d')/c โ‰ฅ fy/Es. If not, iterate with f's = Esยทฮต's
  3. Check ductility: ฮตt = 0.003(dโˆ’c)/c โ‰ฅ 0.004
  4. Compute a = ฮฒโ‚ยทc
  5. Compute Mn = (Asโˆ’A's)ยทfyยท(dโˆ’a/2) + A'sยทfyยท(dโˆ’d')
  6. Apply ฯ† โ†’ report ฯ†Mn
Doubly Reinforced Beam Calculator

Add compression steel A's and watch how ฯ†Mn grows beyond what a singly-reinforced section achieves at the same depth.

b (in) 14
d (in) 22
As โ€” tension steel (inยฒ) 4.00
A's โ€” comp. steel (inยฒ) 1.00
d' โ€” depth to A's (in) 2.5
f'c (psi) 4000
c (N.A. depth)
โ€”
ฮต's
โ€”
f's (psi)
โ€”
ฮตt
โ€”
ฯ†Mn (kยทft)
โ€”
Gain vs singly reinf.
โ€”
โœฆ Quick Check
In a doubly reinforced beam, why must you verify whether A's has yielded before using f's = fy?
ยง 4.7

T-Beams

Almost every real building beam is cast monolithically with the floor slab above it. Under positive bending (sagging), the slab is on the compression side โ€” it adds a huge compression area. Ignoring this treats the beam as a wasteful little rectangle. The T-beam model correctly accounts for the slab's contribution, which can dramatically reduce the required beam depth or steel area.

Think of a steel I-beam. Its wide top flange handles compression efficiently โ€” the force is spread over a large area, keeping stress low. The narrow web carries shear. A T-beam is concrete's I-beam โ€” the monolithic slab is the flange, the rectangular stem below it is the web. You get the efficiency of the I-shape for free because the slab is already there.

T-Beam Geometry โ€” ACI Effective Flange Width be
be โ€” effective flange width (ACI limits) bw (web width) hf d effective overhang compression zone (slab) web bw ร— hw ACI be = minimum of: โ€ข ln / 4 (quarter of span) โ€ข bw + 8hf each side โ€ข bw + clear distance to next web

The Two Cases: Does the Stress Block Stay in the Flange?

โœ… Case 1: a โ‰ค hf
Stress block entirely within the flange. Web below the block is cracked and irrelevant. Treat as a rectangular beam with b = be.

a = Asยทfy / (0.85ยทf'cยทbe)
Mn = Asยทfyยท(d โˆ’ a/2)

Most common case for positive moment T-beams.
โš  Case 2: a > hf
Stress block extends into the web. Split compression into two parts:

Cf = 0.85f'cยท(beโˆ’bw)ยทhf (overhangs)
Cw = 0.85f'cยทbwยทaw (web block)

Set T = Cf + Cw, solve for aw, then compute Mn from both couples.
๐Ÿงฎ T-Beam Analysis โ€” Case 2 Full Procedure (a > hf)
  1. Compute trial a with b = be: a_trial = Asยทfy/(0.85ยทf'cยทbe)
  2. If a_trial > hf โ†’ Case 2 applies. Continue below.
  3. Steel resisted by flange overhangs: Asf = 0.85ยทf'cยท(beโˆ’bw)ยทhf / fy
  4. Steel for web block: Asw = As โˆ’ Asf
  5. Web stress block depth: aw = Aswยทfy / (0.85ยทf'cยทbw)
  6. Nominal moment: Mn = Asfยทfyยท(dโˆ’hf/2) + Aswยทfyยท(dโˆ’aw/2)
  7. Check ฮตt at steel: ฮตt = 0.003(dโˆ’c)/c, where c = (hf + aw/2)ยท... โ€” or use c = a_total/ฮฒโ‚
T-Beam Calculator โ€” be, Case Detection, and ฯ†Mn

Enter beam and slab geometry. The calculator finds be, auto-detects Case 1 vs 2, and computes ฯ†Mn.

bw โ€” web width (in) 14
d โ€” eff. depth (in) 24
hf โ€” slab thickness (in) 5
As (inยฒ) 4.00
ln โ€” clear span (ft) 20
f'c (psi) 4000
be (eff. flange)
โ€”
a (stress block)
โ€”
Case
โ€”
ฮตt
โ€”
Mn (kยทft)
โ€”
ฯ†Mn (kยทft)
โ€”
โœฆ Quick Check
A T-beam has be = 60 in, bw = 14 in, hf = 4 in, d = 22 in, As = 5.0 inยฒ, f'c = 4000 psi, fy = 60 ksi. Compute a assuming b = be. Which case applies?
โœฆ Chapter 4 โ€” Complete Summary
ยง4.1 โ€” Intro
ฯ†Mn โ‰ฅ Mu. Analysis vs. design. ฯ† = 0.90 for tension-controlled flexure.
ยง4.2 โ€” Behavior
3 load stages. Whitney block: a = Asfy/(0.85f'cb). Mn = Asfy(dโˆ’a/2). ฮตt โ‰ฅ 0.005 for ฯ† = 0.90.
ยง4.3 โ€” Design
ฯ = As/bd. ฯmin prevents sudden cracking. ฯmax ensures ductility. 6-step design procedure.
ยง4.4 โ€” Design Aids
Rn = ฯfy(1โˆ’ฯfy/1.7f'c). Use Mu = ฯ†Rnยทbยทdยฒ directly. Target ฯ โ‰ˆ 50โ€“60% of ฯmax.
ยง4.5 โ€” Practical
d = h โˆ’ cover โˆ’ stirrup โˆ’ db/2. Clear spacing โ‰ฅ db, 1 in, 4/3ยทdagg. Round h up to nearest inch.
ยง4.6 โ€” Doubly Reinf.
Two couples: Mn1 + Mn2. Check ฮต's before using f's = fy. Adds Mn capacity without more depth.
ยง4.7 โ€” T-Beams
Slab = compression flange. ACI limits be. a โ‰ค hf โ†’ rect. with b=be. a > hf โ†’ split Cf + Cw.
const obs = new IntersectionObserver(entries => { entries.forEach(e => { if(e.isIntersecting) e.target.classList.add('visible'); }); }, {threshold:0.08}); document.querySelectorAll('.reveal').forEach(el => obs.observe(el)); /* โ•โ• NAV ACTIVE โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• */ const navIds = ['s41','s42','s43','s44','s45','s46','s47']; window.addEventListener('scroll', () => { let cur = ''; navIds.forEach(id => { const el=document.getElementById(id); if(el&&window.scrollY>=el.offsetTop-110) cur=id; }); document.querySelectorAll('.nav-item').forEach(a => a.classList.toggle('active', a.getAttribute('href')==='#'+cur)); }); /* โ•โ• STAGE DIAGRAM โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• */ const stageData = [ { label:'Stage I โ€” Uncracked Elastic', color:'#2dd4bf', desc:'Below cracking load (M < Mcr). The entire cross-section โ€” both concrete and steel โ€” carries load. Stress is linear (elastic) throughout. This stage ends when tensile stress at the bottom reaches the modulus of rupture: fr = 7.5โˆšf\'c. This is the range of normal service loads for lightly loaded members.' }, { label:'Stage II โ€” Cracked Elastic', color:'#f59e0b', desc:'After cracking, before steel yields. Tension cracks form at the bottom. Cracked concrete carries ZERO tension โ€” only the steel does. The neutral axis shifts upward. Stress is still linear in the remaining concrete and in the steel. This is the range of most service-load conditions. We use the cracked transformed section here (Chapter 7 serviceability checks).' }, { label:'Stage III โ€” Ultimate (Nominal Strength)', color:'#fb7185', desc:'Steel has yielded; concrete is near crushing. The steel stress plateaus at fy. Concrete compressive stress is highly nonlinear. Whitney\'s insight: replace this curve with an equivalent rectangle of depth a = ฮฒโ‚c and intensity 0.85f\'c. This gives the nominal moment capacity Mn. ACI design is based entirely on this stage.' } ]; let currentStage = 0; function setStage(i) { currentStage = i; document.querySelectorAll('.stage-btn').forEach((b,j) => b.classList.toggle('active', j===i)); document.getElementById('stageDesc').innerHTML = stageData[i].desc; drawStage(i); } function drawStage(i) { const canvas = document.getElementById('stageCanvas'); const ctx = canvas.getContext('2d'); const W = canvas.width, H = canvas.height; ctx.clearRect(0,0,W,H); ctx.fillStyle = '#080b10'; ctx.fillRect(0,0,W,H); // Section geometry const bx=60, by=40, bw=100, bh=200; const NA_frac = [0.5, 0.38, 0.28]; // NA position as fraction of height const na_y = by + bh * NA_frac[i]; // Draw beam cross section ctx.fillStyle = i===2 ? 'rgba(251,113,133,0.08)' : '#0f1318'; ctx.strokeStyle = stageData[i].color; ctx.lineWidth = 1.8; ctx.beginPath(); ctx.roundRect(bx,by,bw,bh,5); ctx.fill(); ctx.stroke(); // Stage-specific shading if(i===1||i===2) { // Crack lines on tension side ctx.strokeStyle = 'rgba(251,113,133,0.5)'; ctx.lineWidth=1; ctx.setLineDash([2,3]); for(let cy=na_y+10; cy { ctx.fillStyle='#38bdf8'; ctx.beginPath(); ctx.arc(rx,ry,7,0,Math.PI*2); ctx.fill(); }); ctx.fillStyle='#38bdf8'; ctx.font='9px Space Mono,monospace'; ctx.fillText('As', bx+bw+8, dY+4); // โ”€โ”€ STRAIN DIAGRAM โ”€โ”€ const sx=220, sy=by, sh=bh, sw=120; ctx.strokeStyle='#1e2733'; ctx.lineWidth=1; ctx.beginPath(); ctx.moveTo(sx,sy-5); ctx.lineTo(sx,sy+sh+5); ctx.stroke(); ctx.fillStyle='#6b7a90'; ctx.font='8.5px Space Mono,monospace'; ctx.textAlign='center'; ctx.fillText('Strain', sx+sw/2, sy-10); const strains = [[0.0008,0.0008],[0.003,0.001],[0.003,0.016]]; const [eTop, eBot] = strains[i]; const topX = sx + eTop/0.004*sw; const botX = sx + eBot/0.004*sw; const naX = sx; ctx.fillStyle='rgba(45,212,191,0.12)'; ctx.beginPath(); ctx.moveTo(sx,sy); ctx.lineTo(topX,sy); ctx.lineTo(naX,na_y); ctx.closePath(); ctx.fill(); ctx.fillStyle='rgba(251,113,133,0.1)'; ctx.beginPath(); ctx.moveTo(sx,na_y); ctx.lineTo(botX,dY); ctx.lineTo(sx,dY); ctx.closePath(); ctx.fill(); ctx.strokeStyle = stageData[i].color; ctx.lineWidth=2; ctx.beginPath(); ctx.moveTo(topX,sy); ctx.lineTo(naX,na_y); ctx.lineTo(botX,dY); ctx.stroke(); ctx.fillStyle='#2dd4bf'; ctx.font='8px Space Mono,monospace'; ctx.textAlign='left'; ctx.fillText('ฮต='+eTop.toFixed(4), topX+4, sy+12); ctx.fillStyle = i===2?'#fb7185':'#2dd4bf'; ctx.fillText('ฮตt='+eBot.toFixed(4), botX+4, dY-4); // โ”€โ”€ STRESS DIAGRAM โ”€โ”€ const stx=400, sty=by, stsh=bh, stsw=130; ctx.strokeStyle='#1e2733'; ctx.lineWidth=1; ctx.beginPath(); ctx.moveTo(stx,sty-5); ctx.lineTo(stx,sty+stsh+5); ctx.stroke(); ctx.fillStyle='#6b7a90'; ctx.font='8.5px Space Mono,monospace'; ctx.textAlign='center'; ctx.fillText('Stress', stx+stsw/2, sty-10); if(i===0) { // Linear stress diagram both sides const topS=60, botS=50; ctx.fillStyle='rgba(45,212,191,0.15)'; ctx.beginPath(); ctx.moveTo(stx,sty); ctx.lineTo(stx+topS,sty); ctx.lineTo(stx,na_y); ctx.closePath(); ctx.fill(); ctx.fillStyle='rgba(251,113,133,0.12)'; ctx.beginPath(); ctx.moveTo(stx,na_y); ctx.lineTo(stx+botS,dY); ctx.lineTo(stx,dY); ctx.closePath(); ctx.fill(); ctx.strokeStyle='#2dd4bf'; ctx.lineWidth=1.8; ctx.beginPath(); ctx.moveTo(stx+topS,sty); ctx.lineTo(stx,na_y); ctx.stroke(); ctx.strokeStyle='#fb7185'; ctx.beginPath(); ctx.moveTo(stx,na_y); ctx.lineTo(stx+botS,dY); ctx.stroke(); ctx.fillStyle='#2dd4bf'; ctx.font='8px Space Mono,monospace'; ctx.textAlign='left'; ctx.fillText('fc (comp)', stx+topS+4, sty+10); ctx.fillStyle='#fb7185'; ctx.fillText('ft (tens)', stx+botS+4, dY-4); ctx.fillStyle='#6b7a90'; ctx.font='8px Space Mono,monospace'; ctx.textAlign='center'; ctx.fillText('Linear elastic', stx+60, na_y+18); } else if(i===1) { // Cracked: linear compression only const topS=80; ctx.fillStyle='rgba(45,212,191,0.15)'; ctx.beginPath(); ctx.moveTo(stx,sty); ctx.lineTo(stx+topS,sty); ctx.lineTo(stx,na_y); ctx.closePath(); ctx.fill(); ctx.strokeStyle='#2dd4bf'; ctx.lineWidth=1.8; ctx.beginPath(); ctx.moveTo(stx+topS,sty); ctx.lineTo(stx,na_y); ctx.stroke(); ctx.fillStyle='#2dd4bf'; ctx.font='8px Space Mono,monospace'; ctx.textAlign='left'; ctx.fillText('fc linear', stx+topS+4, sty+10); // Steel force dot ctx.fillStyle='#38bdf8'; ctx.beginPath(); ctx.arc(stx+90,dY,8,0,Math.PI*2); ctx.fill(); ctx.fillStyle='#38bdf8'; ctx.font='8px Space Mono,monospace'; ctx.fillText('fs=nfc', stx+100,dY+4); ctx.fillStyle='#fb7185'; ctx.font='8px Space Mono,monospace'; ctx.fillText('CRACKED โ€” no tension', stx+5, na_y+14); } else { // Stage III: rectangle block + steel yield const aH=bh*0.18; ctx.fillStyle='rgba(245,158,11,0.25)'; ctx.fillRect(stx, sty, stsw*0.7, aH); ctx.strokeStyle='#f59e0b'; ctx.lineWidth=1.5; ctx.strokeRect(stx, sty, stsw*0.7, aH); ctx.fillStyle='#f59e0b'; ctx.font='8.5px Space Mono,monospace'; ctx.textAlign='left'; ctx.fillText('0.85f\'c', stx+stsw*0.7+4, sty+aH/2+4); ctx.fillStyle='#fb7185'; ctx.font='8px Space Mono,monospace'; ctx.fillText('Whitney rectangle', stx+4, sty+aH+14); ctx.fillStyle='#38bdf8'; ctx.beginPath(); ctx.arc(stx+90,dY,8,0,Math.PI*2); ctx.fill(); ctx.fillStyle='#38bdf8'; ctx.font='8.5px Space Mono,monospace'; ctx.fillText('fs = fy (yield)', stx+100,dY+4); } // โ”€โ”€ LOAD ARROW โ”€โ”€ ctx.strokeStyle=stageData[i].color; ctx.lineWidth=2.5; const arrowX = bx+bw/2; ctx.beginPath(); ctx.moveTo(arrowX,by-35); ctx.lineTo(arrowX,by-5); ctx.stroke(); ctx.beginPath(); ctx.moveTo(arrowX-8,by-12); ctx.lineTo(arrowX,by-2); ctx.lineTo(arrowX+8,by-12); ctx.stroke(); const loadLabels=['Load: Low','Load: Service','Load: Ultimate']; ctx.fillStyle=stageData[i].color; ctx.font='bold 9px Space Mono,monospace'; ctx.textAlign='center'; ctx.fillText(loadLabels[i], arrowX, by-40); } setStage(0); /* โ•โ• RHO LIMITS โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• */ function calcBeta1(fc) { return Math.max(0.65, 0.85 - 0.05*Math.max(0,(fc-4000)/1000)); } function calcRhoMin(fc, fy) { return Math.max(3*Math.sqrt(fc)/fy, 200/fy); } function calcRhoMax(fc, fy) { // ฮตt = 0.004 limit const beta1 = calcBeta1(fc); return (0.85*beta1*fc/fy)*(0.003/(0.003+0.004)); } function calcRhoTC(fc, fy) { // ฮตt = 0.005 limit (full tension-controlled) const beta1 = calcBeta1(fc); return (0.85*beta1*fc/fy)*(0.003/(0.003+0.005)); } function updateRho() { const fc=+document.getElementById('fc2').value; const fy=+document.getElementById('fy2').value; const rhoUser=+document.getElementById('rho-input').value/100; document.getElementById('fc2-val').textContent=fc.toLocaleString(); document.getElementById('fy2-val').textContent=fy.toLocaleString(); document.getElementById('rho-input-val').textContent=(rhoUser*100).toFixed(2); const rhoMin=calcRhoMin(fc,fy); const rhoMax=calcRhoMax(fc,fy); document.getElementById('rho-min-out').textContent=(rhoMin*100).toFixed(3)+'%'; document.getElementById('rho-max-out').textContent=(rhoMax*100).toFixed(3)+'%'; document.getElementById('rho-yours-out').textContent=(rhoUser*100).toFixed(2)+'%'; const maxScale=0.035; const minPct=rhoMin/maxScale*100; const maxPct=rhoMax/maxScale*100; const userPct=Math.min(rhoUser/maxScale*100,100); document.getElementById('rho-zone-min').style.width=minPct+'%'; document.getElementById('rho-zone-ok').style.left=minPct+'%'; document.getElementById('rho-zone-ok').style.width=Math.max(0,(maxPct-minPct))+'%'; document.getElementById('rho-zone-max').style.width=(100-maxPct)+'%'; document.getElementById('rho-pointer-bar').style.left=userPct+'%'; document.getElementById('rho-min-label').textContent='ฯmin='+(rhoMin*100).toFixed(3)+'%'; document.getElementById('rho-max-label').textContent='ฯmax='+(rhoMax*100).toFixed(3)+'%'; let status='', statusColor=''; if(rhoUserrhoMax){ status='โŒ Over-reinforced (> ฯmax)'; statusColor=var_rose; } else if(rhoUser<=calcRhoTC(fc,fy)){ status='โœ… OK โ€” Tension-controlled (ฯ†=0.90)'; statusColor='#84cc16'; } else{ status='โš  Transition zone โ€” reduce ฯ for full ฯ†=0.90'; statusColor='#f59e0b'; } document.getElementById('rho-status').textContent=status; document.getElementById('rho-status').style.color=statusColor; } const var_rose='#fb7185'; updateRho(); /* โ•โ• Mn CALCULATOR โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• */ function updateMn() { const b=+document.getElementById('b-sl').value; const d=+document.getElementById('d-sl').value; const As=+document.getElementById('as-sl').value; const fc=+document.getElementById('fc-sl').value; const fy=+document.getElementById('fy-sl').value; document.getElementById('b-val').textContent=b; document.getElementById('d-val').textContent=d; document.getElementById('as-val').textContent=As.toFixed(2); document.getElementById('fc-val').textContent=fc.toLocaleString(); document.getElementById('fy-val').textContent=fy.toLocaleString(); const beta1=calcBeta1(fc); const a=As*fy/(0.85*fc*b); const c=a/beta1; const et=0.003*(d-c)/c; let phi=0.90; if(et<0.004) phi=0.65; else if(et<0.005) phi=0.65+0.25*(et-0.004)/0.001; const Mn_inlb=As*fy*(d-a/2); const Mn_kft=Mn_inlb/12000; const pMn=phi*Mn_kft; const rho=As/(b*d); document.getElementById('a-out').textContent=a.toFixed(2)+' in'; document.getElementById('b1-out').textContent=beta1.toFixed(3); document.getElementById('c-out').textContent=c.toFixed(2)+' in'; document.getElementById('et-out').textContent=et.toFixed(4); document.getElementById('et-out').style.color=et>=0.005?'#84cc16':et>=0.004?'#f59e0b':'#fb7185'; document.getElementById('phi-out').textContent=phi.toFixed(3); document.getElementById('rho-out').textContent=(rho*100).toFixed(3)+'%'; document.getElementById('mn-out').textContent=Mn_kft.toFixed(1); document.getElementById('phmn-out').textContent=pMn.toFixed(1); const rhoMin=calcRhoMin(fc,fy); const rhoMax=calcRhoMax(fc,fy); const statusEl=document.getElementById('mn-status'); if(et<0.004){ statusEl.textContent='โŒ Over-reinforced: ฮตt < 0.004 โ€” NOT permitted by ACI 318'; statusEl.style.background='rgba(251,113,133,0.1)'; statusEl.style.color='#fb7185'; statusEl.style.border='1px solid rgba(251,113,133,.25)'; } else if(rho { const Rn=rho*fy*(1-rho*fy/(1.7*fc)); const Ku=0.90*Rn; const c_frac=(rho*fy)/(0.85*beta1*fc); const et=0.003*(1-c_frac)/c_frac; let status='',color=''; if(rhorhoMax){status='> ฯmax (N/A)';color='#fb7185';} else if(et>=0.005){status='โœ“ TC (ฯ†=0.90)';color='#84cc16';} else{status='Transition';color='#f59e0b';} const tr=document.createElement('tr'); tr.style.opacity=rho>rhoMax?'0.4':'1'; tr.innerHTML=` ${(rho*100).toFixed(2)} ${Math.round(Rn)} ${Math.round(Ku)} ${et.toFixed(4)} ${status}`; tbody.appendChild(tr); }); drawRnChart(fc, fy); } /* โ•โ• Rn CHART โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• */ function drawRnChart(fc, fy) { const canvas=document.getElementById('rnChart'); if(!canvas) return; const ctx=canvas.getContext('2d'); const W=canvas.width, H=canvas.height; ctx.clearRect(0,0,W,H); ctx.fillStyle='#080b10'; ctx.fillRect(0,0,W,H); const pad={l:70,r:30,t:30,b:50}; const cw=W-pad.l-pad.r, ch=H-pad.t-pad.b; const rhoMin=calcRhoMin(fc,fy); const rhoMax=calcRhoMax(fc,fy); const rhoMaxPlot=Math.min(rhoMax*1.4, 0.028); // Grid ctx.strokeStyle='#1e2733'; ctx.lineWidth=1; for(let i=0;i<=5;i++){ const y=pad.t+i*ch/5; ctx.beginPath(); ctx.moveTo(pad.l,y); ctx.lineTo(pad.l+cw,y); ctx.stroke(); } for(let i=0;i<=7;i++){ const x=pad.l+i*cw/7; ctx.beginPath(); ctx.moveTo(x,pad.t); ctx.lineTo(x,pad.t+ch); ctx.stroke(); } // Axes ctx.strokeStyle='#2dd4bf'; ctx.lineWidth=1.5; ctx.beginPath(); ctx.moveTo(pad.l,pad.t); ctx.lineTo(pad.l,pad.t+ch); ctx.lineTo(pad.l+cw,pad.t+ch); ctx.stroke(); // Calculate max Rn for scale const maxRn=rhoMaxPlot*fy*(1-rhoMaxPlot*fy/(1.7*fc))*1.15; const toX=rho => pad.l+rho/rhoMaxPlot*cw; const toY=Rn => pad.t+ch-(Rn/maxRn)*ch; // Shading zones ctx.fillStyle='rgba(251,113,133,0.1)'; ctx.fillRect(toX(rhoMax),pad.t,cw-(toX(rhoMax)-pad.l),ch); ctx.fillStyle='rgba(251,113,133,0.07)'; ctx.fillRect(pad.l,pad.t,toX(rhoMin)-pad.l,ch); // Main Rn curve ctx.strokeStyle='#2dd4bf'; ctx.lineWidth=2.5; ctx.beginPath(); let first=true; for(let rho=0.001;rho<=rhoMaxPlot;rho+=0.0002){ const Rn=rho*fy*(1-rho*fy/(1.7*fc)); const x=toX(rho), y=toY(Rn); if(first){ctx.moveTo(x,y);first=false;}else ctx.lineTo(x,y); } ctx.stroke(); // ฯ†*Rn curve (dashed) ctx.strokeStyle='#f59e0b'; ctx.lineWidth=1.5; ctx.setLineDash([4,3]); ctx.beginPath(); first=true; for(let rho=0.001;rho<=rhoMaxPlot;rho+=0.0002){ const Rn=rho*fy*(1-rho*fy/(1.7*fc)); const x=toX(rho), y=toY(0.90*Rn); if(first){ctx.moveTo(x,y);first=false;}else ctx.lineTo(x,y); } ctx.stroke(); ctx.setLineDash([]); // Vertical limit lines const drawVline=(rho,color,label) => { const x=toX(rho); ctx.strokeStyle=color; ctx.lineWidth=1.5; ctx.setLineDash([5,4]); ctx.beginPath(); ctx.moveTo(x,pad.t); ctx.lineTo(x,pad.t+ch); ctx.stroke(); ctx.setLineDash([]); ctx.fillStyle=color; ctx.font='bold 8.5px Space Mono,monospace'; ctx.textAlign='center'; ctx.fillText(label, x, pad.t-10); ctx.fillText((rho*100).toFixed(3)+'%', x, pad.t-1); }; drawVline(rhoMin,'#fb7185','ฯmin'); drawVline(rhoMax,'#fb7185','ฯmax'); // Axis labels ctx.fillStyle='#6b7a90'; ctx.font='8px Space Mono,monospace'; for(let i=0;i<=5;i++){ const Rn_val=maxRn*i/5; ctx.textAlign='right'; ctx.fillText(Math.round(Rn_val), pad.l-6, pad.t+ch-i*ch/5+4); } for(let i=0;i<=7;i++){ const rho_val=rhoMaxPlot*i/7; ctx.textAlign='center'; ctx.fillText((rho_val*100).toFixed(2)+'%', pad.l+i*cw/7, pad.t+ch+18); } // Axis titles ctx.fillStyle='#94a3b8'; ctx.font='9px Space Mono,monospace'; ctx.textAlign='center'; ctx.fillText('ฯ (reinforcement ratio)', pad.l+cw/2, H-8); ctx.save(); ctx.translate(14, pad.t+ch/2); ctx.rotate(-Math.PI/2); ctx.fillText('Rn (psi)', 0, 0); ctx.restore(); // Legend ctx.fillStyle='#2dd4bf'; ctx.fillRect(pad.l+cw-130,pad.t+10,20,3); ctx.fillStyle='#6b7a90'; ctx.font='8px Space Mono,monospace'; ctx.textAlign='left'; ctx.fillText('Rn (psi)', pad.l+cw-106, pad.t+14); ctx.fillStyle='#f59e0b'; ctx.fillRect(pad.l+cw-130,pad.t+22,20,3); ctx.fillText('ฯ†Rn (ฯ†=0.90)', pad.l+cw-106, pad.t+26); } updateTable(); /* โ•โ• QUIZ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• */ const qData = { q1:{ correct:'Tension-controlled โ€” steel yields well before crushing, ฯ† = 0.90', explain:'โœ“ Correct! ฮตt = 0.006 exceeds 0.005, so ACI classifies this as tension-controlled. The steel has plenty of ductility before the concrete could ever crush. ฯ† = 0.90 applies.' }, q2:{ correct:'a = 4.41 in', explain:'โœ“ Right! a = Asfy/(0.85f\'cb) = (3.0 ร— 60,000)/(0.85 ร— 4,000 ร— 12) = 180,000/40,800 = 4.41 in. The stress block is 4.41 inches deep.' }, q3:{ correct:'Prevents sudden brittle failure right at the cracking load โ€” without steel, cracking = collapse', explain:'โœ“ Exactly! Without minimum steel, the moment capacity of the cracked section (carried by steel) is actually less than the cracking moment. The beam would collapse at the instant it first cracks. ฯmin ensures the post-cracking capacity is always greater than Mcr.' }, q5:{ correct:'d = 17.625 in', explain:'โœ“ Correct! d = h โˆ’ cover โˆ’ d_stirrup โˆ’ d_bar/2 = 20 โˆ’ 1.5 โˆ’ 0.375 โˆ’ 1.0/2 = 20 โˆ’ 1.5 โˆ’ 0.375 โˆ’ 0.5 = 17.625 in. Always subtract half the main bar diameter โ€” the centroid of the bar is at its center.' }, q6:{ correct:'If the neutral axis is shallow (small c), the strain at A\'s may fall below yield strain โ€” assuming fy would overestimate the compression force Cโ‚‚', explain:'โœ“ Exactly. ฮต\'s = 0.003(cโˆ’d\')/c depends on c. If c is small, d\' can represent a large fraction of c, making ฮต\'s small. Using fy when the bar hasn\'t yielded would overestimate Cโ‚‚ and Mn, giving an unconservative answer.' }, q7:{ correct:'Case 1 โ€” a = 1.47 in < hf = 4 in, treat as rectangular with b = be = 60 in', explain:'โœ“ Right! a = Asยทfy/(0.85ยทf\'cยทbe) = (5.0ร—60,000)/(0.85ร—4,000ร—60) = 300,000/204,000 = 1.47 in. Since 1.47 in < hf = 4 in, the entire stress block lies within the slab. Use b = be = 60 in like a standard rectangular beam.' } }; /* โ•โ• COVER CALCULATOR โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• */ function updateCover() { const h = +document.getElementById('hh-sl').value; const cov= +document.getElementById('cov-sl').value; const dst= +document.getElementById('dst-sl').value; const db = +document.getElementById('db-sl').value; document.getElementById('hh-val').textContent = h; document.getElementById('cov-val').textContent = cov.toFixed(3); document.getElementById('dst-val').textContent = dst.toFixed(3); document.getElementById('db-val').textContent = db.toFixed(3); const cgFromBot = cov + dst + db/2; const d = h - cgFromBot; document.getElementById('eff-d').textContent = d.toFixed(3) + ' in'; document.getElementById('dh-ratio').textContent= (d/h).toFixed(3); document.getElementById('cg-bot').textContent = cgFromBot.toFixed(3) + ' in'; drawCoverSection(h, cov, dst, db, d); } function drawCoverSection(h, cov, dst, db, d) { const canvas = document.getElementById('coverCanvas'); if (!canvas) return; const ctx = canvas.getContext('2d'); const W = canvas.width, H = canvas.height; ctx.clearRect(0,0,W,H); ctx.fillStyle = '#080b10'; ctx.fillRect(0,0,W,H); const bw = 80, pad = 60; const scale = (H - 40) / h; const bh = h * scale; const bx = (W - bw) / 2, by = (H - bh) / 2; // Beam body ctx.fillStyle = '#0f1318'; ctx.strokeStyle = '#2dd4bf'; ctx.lineWidth = 1.5; ctx.beginPath(); ctx.roundRect(bx, by, bw, bh, 4); ctx.fill(); ctx.stroke(); // Cover zone shading const covPx = cov * scale; ctx.fillStyle = 'rgba(245,158,11,0.12)'; ctx.fillRect(bx, by+bh-covPx-dst*scale-db/2*scale*2, bw, covPx+dst*scale+db/2*scale*2); // Stirrup line const stirrupY = by + bh - (cov + dst) * scale; ctx.strokeStyle = '#a78bfa'; ctx.lineWidth = 1; ctx.setLineDash([3,2]); ctx.beginPath(); ctx.moveTo(bx+4, stirrupY); ctx.lineTo(bx+bw-4, stirrupY); ctx.stroke(); ctx.setLineDash([]); // Main bar const barY = by + bh - (cov + dst + db/2) * scale; ctx.fillStyle = '#38bdf8'; const r = Math.max(3, Math.min(10, db * scale / 2)); [[bx+bw*0.28, barY],[bx+bw*0.72, barY]].forEach(([x,y]) => { ctx.beginPath(); ctx.arc(x,y,r,0,Math.PI*2); ctx.fill(); }); // Dimension annotations const annotX = bx + bw + 12; ctx.fillStyle = '#f59e0b'; ctx.font = '8px Space Mono,monospace'; ctx.textAlign = 'left'; // cover bracket ctx.strokeStyle = '#f59e0b'; ctx.lineWidth=1; ctx.beginPath(); ctx.moveTo(annotX, by+bh); ctx.lineTo(annotX, by+bh-covPx); ctx.stroke(); ctx.fillText('cov='+cov+'"', annotX+4, by+bh-covPx/2+3); // d bracket ctx.strokeStyle = '#2dd4bf'; ctx.lineWidth=1; ctx.beginPath(); ctx.moveTo(annotX+48, by); ctx.lineTo(annotX+48, barY); ctx.stroke(); ctx.fillStyle='#2dd4bf'; ctx.fillText('d='+d.toFixed(2)+'"', annotX+52, (by+barY)/2+3); // h label ctx.strokeStyle='#84cc16'; ctx.lineWidth=1; ctx.beginPath(); ctx.moveTo(bx-18, by); ctx.lineTo(bx-18, by+bh); ctx.stroke(); ctx.fillStyle='#84cc16'; ctx.font='8px Space Mono,monospace'; ctx.textAlign='right'; ctx.fillText('h='+h+'"', bx-22, by+bh/2+3); } updateCover(); /* โ•โ• DOUBLY REINFORCED CALCULATOR โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• */ function updateDR() { const b = +document.getElementById('dr-b').value; const d = +document.getElementById('dr-d').value; const As = +document.getElementById('dr-as').value; const Asc= +document.getElementById('dr-asc').value; const dp = +document.getElementById('dr-dp').value; const fc = +document.getElementById('dr-fc').value; const fy = 60000; const Es = 29000000; document.getElementById('dr-b-val').textContent = b; document.getElementById('dr-d-val').textContent = d; document.getElementById('dr-as-val').textContent = As.toFixed(2); document.getElementById('dr-asc-val').textContent= Asc.toFixed(2); document.getElementById('dr-dp-val').textContent = dp.toFixed(2); document.getElementById('dr-fc-val').textContent = fc.toLocaleString(); const beta1 = calcBeta1(fc); // Assume A's yields: As*fy = 0.85*fc*beta1*c*b + Asc*fy // c = (As - Asc)*fy / (0.85*fc*beta1*b) let c = (As - Asc) * fy / (0.85 * fc * beta1 * b); let es_prime = 0.003 * (c - dp) / c; let fs_prime = Math.min(Es * es_prime, fy); // if A's didn't yield, re-solve: As*fy = 0.85*fc*beta1*c*b + Asc*(Es*0.003*(c-dp)/c) // quadratic in c: 0.85*fc*beta1*b*c + Asc*Es*0.003*(1-dp/c) = As*fy // => 0.85*fc*beta1*b*cยฒ + Asc*Es*0.003*c - Asc*Es*0.003*dp = As*fy*c (multiply by c) // => (0.85*fc*beta1*b)*cยฒ + (Asc*Es*0.003 - As*fy)*c - Asc*Es*0.003*dp = 0 if (es_prime < fy/Es) { const A_coef = 0.85 * fc * beta1 * b; const B_coef = Asc * Es * 0.003 - As * fy; const C_coef = -Asc * Es * 0.003 * dp; c = (-B_coef + Math.sqrt(B_coef*B_coef - 4*A_coef*C_coef)) / (2 * A_coef); es_prime = 0.003 * (c - dp) / c; fs_prime = Es * es_prime; } const a = beta1 * c; const et = 0.003 * (d - c) / c; let phi = 0.90; if (et < 0.004) phi = 0.65; else if (et < 0.005) phi = 0.65 + 0.25*(et-0.004)/0.001; const As1 = As - Asc; const Mn_inlb = As1*fy*(d - a/2) + Asc*fs_prime*(d - dp); const Mn_kft = Mn_inlb / 12000; const pMn = phi * Mn_kft; // Compare with singly-reinforced (Asc=0) const a_single = As*fy/(0.85*fc*b); const Mn_single = As*fy*(d - a_single/2)/12000; const pMn_single= 0.90 * Mn_single; const gain = pMn - pMn_single; document.getElementById('dr-c-out').textContent = c.toFixed(2)+' in'; document.getElementById('dr-es-out').textContent = es_prime.toFixed(4); document.getElementById('dr-es-out').style.color = es_prime >= fy/Es ? '#84cc16' : '#fb7185'; document.getElementById('dr-fs-out').textContent = Math.round(fs_prime).toLocaleString()+' psi'; document.getElementById('dr-et-out').textContent = et.toFixed(4); document.getElementById('dr-et-out').style.color = et>=0.005?'#84cc16':et>=0.004?'#f59e0b':'#fb7185'; document.getElementById('dr-pmn-out').textContent= pMn.toFixed(1)+' kยทft'; document.getElementById('dr-gain-out').textContent= '+'+gain.toFixed(1)+' kยทft'; const st = document.getElementById('dr-status'); if (et < 0.004) { st.textContent='โŒ Over-reinforced: ฮตt < 0.004 โ€” NOT permitted by ACI 318'; st.style.cssText='background:rgba(251,113,133,0.1);color:#fb7185;border:1px solid rgba(251,113,133,.25);border-radius:8px;'; } else if (es_prime < fy/Es) { st.textContent='โš  A\'s did NOT yield (ฮต\'s='+es_prime.toFixed(4)+' < '+( fy/Es).toFixed(4)+') โ€” f\'s = Esยทฮต\'s used'; st.style.cssText='background:rgba(245,158,11,0.1);color:#f59e0b;border:1px solid rgba(245,158,11,.25);border-radius:8px;'; } else { st.textContent='โœ… Valid โ€” A\'s yielded (f\'s = fy), ฯ†='+phi.toFixed(2)+', ฮตt='+et.toFixed(4); st.style.cssText='background:rgba(132,204,22,0.1);color:#84cc16;border:1px solid rgba(132,204,22,.25);border-radius:8px;'; } } updateDR(); /* โ•โ• T-BEAM CALCULATOR โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• */ function updateTbeam() { const bw = +document.getElementById('tb-bw').value; const d = +document.getElementById('tb-d').value; const hf = +document.getElementById('tb-hf').value; const As = +document.getElementById('tb-as').value; const ln = +document.getElementById('tb-ln').value * 12; // convert to inches const fc = +document.getElementById('tb-fc').value; const fy = 60000; document.getElementById('tb-bw-val').textContent = bw; document.getElementById('tb-d-val').textContent = d; document.getElementById('tb-hf-val').textContent = hf; document.getElementById('tb-as-val').textContent = As.toFixed(2); document.getElementById('tb-ln-val').textContent = ln/12; document.getElementById('tb-fc-val').textContent = fc.toLocaleString(); const beta1 = calcBeta1(fc); // ACI be: min of ln/4, bw+16hf, available (assume interior beam โ€” use ln/4 and bw+16hf) const be = Math.min(ln/4, bw + 16*hf); // Trial a with b = be const a_trial = As * fy / (0.85 * fc * be); let Mn_inlb, a_eff, caseNum, c_depth; if (a_trial <= hf) { // Case 1 โ€” rectangular with b = be caseNum = 1; a_eff = a_trial; Mn_inlb = As * fy * (d - a_eff/2); c_depth = a_eff / beta1; } else { // Case 2 โ€” true T-beam caseNum = 2; const Asf = 0.85 * fc * (be - bw) * hf / fy; const Asw = As - Asf; const aw = Asw * fy / (0.85 * fc * bw); a_eff = aw; // web block depth Mn_inlb = Asf*fy*(d - hf/2) + Asw*fy*(d - aw/2); // approximate c from total compression depth const total_comp = hf + aw; // rough c_depth = total_comp / beta1; } const et = 0.003 * (d - c_depth) / c_depth; let phi = 0.90; if (et < 0.004) phi = 0.65; else if (et < 0.005) phi = 0.65 + 0.25*(et-0.004)/0.001; const Mn_kft = Mn_inlb / 12000; const pMn = phi * Mn_kft; document.getElementById('tb-be-out').textContent = be.toFixed(1)+' in'; document.getElementById('tb-a-out').textContent = a_trial.toFixed(2)+' in'; document.getElementById('tb-case-out').textContent = caseNum===1 ? 'โœ… Case 1 (rect.)' : 'โš  Case 2 (T-beam)'; document.getElementById('tb-case-out').style.color = caseNum===1 ? '#84cc16' : '#f59e0b'; document.getElementById('tb-et-out').textContent = et.toFixed(4); document.getElementById('tb-et-out').style.color = et>=0.005?'#84cc16':et>=0.004?'#f59e0b':'#fb7185'; document.getElementById('tb-mn-out').textContent = Mn_kft.toFixed(1)+' kยทft'; document.getElementById('tb-pmn-out').textContent = pMn.toFixed(1)+' kยทft'; const st = document.getElementById('tb-status'); if (et < 0.004) { st.textContent='โŒ Over-reinforced: ฮตt < 0.004 โ€” reduce As or increase d'; st.style.cssText='background:rgba(251,113,133,0.1);color:#fb7185;border:1px solid rgba(251,113,133,.25);border-radius:8px;'; } else { const caseDesc = caseNum===1 ? 'Case 1: a='+a_trial.toFixed(2)+'" โ‰ค hf='+hf+'" โ†’ rectangular analysis with b=be='+be.toFixed(0)+'"' : 'Case 2: a='+a_trial.toFixed(2)+'" > hf='+hf+'" โ†’ T-beam split (Cf + Cw)'; st.textContent='โœ… '+caseDesc+' ยท ฯ†='+phi.toFixed(2); st.style.cssText='background:rgba(132,204,22,0.1);color:#84cc16;border:1px solid rgba(132,204,22,.25);border-radius:8px;'; } drawTbeamSection(bw, d, hf, be, a_trial, hf, caseNum); } function drawTbeamSection(bw, d, hf, be, a_trial, hf_val, caseNum) { const canvas = document.getElementById('tbCanvas'); if (!canvas) return; const ctx = canvas.getContext('2d'); const W = canvas.width, H = canvas.height; ctx.clearRect(0,0,W,H); ctx.fillStyle = '#080b10'; ctx.fillRect(0,0,W,H); const totalH = d + 5; const scale = (H - 30) / totalH; const webW = bw * scale; const webH = (d - hf_val) * scale; const flangeH = hf_val * scale; const flangeW = Math.min(be * scale, W - 20); const cx = W / 2; const topY = 15; // Flange ctx.fillStyle = '#0f1318'; ctx.strokeStyle = '#2dd4bf'; ctx.lineWidth = 1.5; ctx.beginPath(); ctx.roundRect(cx - flangeW/2, topY, flangeW, flangeH, 3); ctx.fill(); ctx.stroke(); // Web ctx.strokeStyle = '#60a5fa'; ctx.beginPath(); ctx.roundRect(cx - webW/2, topY + flangeH, webW, webH, 3); ctx.fill(); ctx.stroke(); // Stress block shading const aH = Math.min(a_trial * scale, flangeH + webH); const blockColor = caseNum===1 ? 'rgba(245,158,11,0.28)' : 'rgba(251,113,133,0.22)'; ctx.fillStyle = blockColor; if (caseNum === 1) { ctx.fillRect(cx - flangeW/2, topY, flangeW, aH); } else { ctx.fillRect(cx - flangeW/2, topY, flangeW, flangeH); ctx.fillRect(cx - webW/2, topY + flangeH, webW, (a_trial - hf_val)*scale); } // Rebar dots at bottom const barY = topY + flangeH + webH - 8; ctx.fillStyle = '#38bdf8'; [cx-webW*0.28, cx, cx+webW*0.28].forEach(x => { ctx.beginPath(); ctx.arc(x, barY, 4, 0, Math.PI*2); ctx.fill(); }); // Labels ctx.fillStyle = '#2dd4bf'; ctx.font = '7.5px Space Mono,monospace'; ctx.textAlign = 'center'; ctx.fillText('be = '+Math.round(be)+'"', cx, topY - 4); ctx.fillStyle = '#60a5fa'; ctx.fillText('bw = '+bw+'"', cx, topY + flangeH + webH/2 + 4); ctx.fillStyle = '#f59e0b'; ctx.textAlign = 'right'; ctx.fillText('hf='+hf_val+'"', cx - flangeW/2 - 3, topY + flangeH/2 + 3); ctx.fillStyle = '#84cc16'; ctx.textAlign = 'left'; ctx.fillText('d='+d+'"', cx + flangeW/2 + 3, topY + (d*scale)/2 + 3); } updateTbeam(); function qCheck(btn, isCorrect, qid) { const opts = btn.closest('.quiz-opts').querySelectorAll('.quiz-opt'); opts.forEach(o => o.disabled=true); const q=qData[qid]; opts.forEach(o => { if(o.textContent.trim()===q.correct.trim()) o.classList.add('correct'); }); if(!isCorrect) btn.classList.add('wrong'); const fb=document.getElementById(qid+'-fb'); fb.textContent = isCorrect ? q.explain : 'โœ— Not quite. '+q.explain; fb.className='quiz-fb show '+(isCorrect?'ok':'no'); }