let graphA; let graphB; let graphC; let graphD; let graphE; let graphF; let graphG; let graphH; let graphI; document.addEventListener('DOMContentLoaded', () => { initBDist(); }); function initBDist() { funA(); funB(); funC(); funD(); funE(); funF(); funG(); funH(); funI(); } document.querySelectorAll('input').forEach(input => { input.addEventListener('input', funA); input.addEventListener('input', funB); input.addEventListener('input', funC); input.addEventListener('input', funD); input.addEventListener('input', funE); input.addEventListener('input', funF); input.addEventListener('input', funG); input.addEventListener('input', funH); input.addEventListener('input', funI); }); function showTab(tabId) { document.querySelectorAll('.tab-content').forEach(tab => { tab.classList.remove('active'); }); document.querySelectorAll('.subtab-content').forEach(subtab => { subtab.classList.remove('active'); }); document.querySelectorAll('.subsubtab-content').forEach(subsubtab => { subsubtab.classList.remove('active'); }); const activeTab = document.getElementById(tabId); activeTab.classList.add('active'); document.querySelectorAll('.tab').forEach(tab => { tab.classList.remove('active'); }); const activeTabElement = document.querySelector(`.tab[onclick*="${tabId}"]`); if (activeTabElement) { activeTabElement.classList.add('active'); } const firstSubtab = activeTab.querySelector('.subtab-content'); if (firstSubtab) { firstSubtab.classList.add('active'); const firstSubsubtab = firstSubtab.querySelector('.subsubtab-content'); if (firstSubsubtab) { firstSubsubtab.classList.add('active'); } } } function showSubTab(subTabId) { document.querySelectorAll('.tab-content.active .subtab-content').forEach(subtab => { subtab.classList.remove('active'); }); const subtabToShow = document.getElementById(subTabId); subtabToShow.classList.add('active'); document.querySelectorAll('.subtab').forEach(subtab => { subtab.classList.remove('active'); }); const activeSubtabElement = document.querySelector(`.subtab[onclick*="${subTabId}"]`); if (activeSubtabElement) { activeSubtabElement.classList.add('active'); } const firstSubsubtab = subtabToShow.querySelector('.subsubtab-content'); if (firstSubsubtab) { firstSubsubtab.classList.add('active'); } } function showSubSubTab(subSubTabId) { document.querySelectorAll('.subtab-content.active .subsubtab-content').forEach(subsubtab => { subsubtab.classList.remove('active'); }); const subsubtabToShow = document.getElementById(subSubTabId); subsubtabToShow.classList.add('active'); document.querySelectorAll('.subsubtab').forEach(subsubtab => { subsubtab.classList.remove('active'); }); const activeSubsubtabElement = document.querySelector(`.subsubtab[onclick*="${subSubTabId}"]`); if (activeSubsubtabElement) { activeSubsubtabElement.classList.add('active'); } } //FRICTION CONSTANT (TANGENT) (A) function funA() { const a = parseFloat(document.getElementById('a').value) || 0; const b = parseFloat(document.getElementById('b').value) || 0; const g = parseFloat(document.getElementById('g').value / 100) || 0; const fl = parseFloat(document.getElementById('fl').value) || 0; const t = parseFloat(document.getElementById('t').value) || 0; const bdA = (b ** 2 - a ** 2) / (254 * (fl + g)); const reactionA = (b * t) / 3.6; const totalResA = bdA + reactionA; document.getElementById('bdA').innerText = bdA.toFixed(0); document.getElementById('reactionA').innerText = reactionA.toFixed(0); document.getElementById('totalResA').innerText = totalResA.toFixed(0); if (!graphA) { const ctxA = document.getElementById('graphA').getContext('2d'); graphA = new Chart(ctxA, { type: 'bar', data: { labels: [''], datasets: [{ label: 'Reaction distance', data: [reactionA], backgroundColor: '#2c8c0a', indexAxis: 'y', }, { label: 'Braking distance (BD)', data: [bdA], backgroundColor: '#124200', }] }, options: { plugins: { legend: { labels: { color: 'black', } } }, indexAxis: 'y', scales: { x: { stacked: true, ticks: { color: 'black', callback: function (value) { return value; } } }, y: { stacked: true, } } } }); } else { updateGraphA(bdA, reactionA); } } function updateGraphA(bdA, reactionA) { if (graphA) { graphA.data.datasets[0].data = [reactionA]; graphA.data.datasets[1].data = [bdA]; graphA.update(); } } //FRICTION LINEAR (TANGENT) (B) function funB() { const floB = parseFloat(document.getElementById('floB').value) || 0; const betaB = parseFloat(document.getElementById('betaB').value) || 0; const aB = parseFloat(document.getElementById('aB').value) || 0; const bB = parseFloat(document.getElementById('bB').value) || 0; const gB = parseFloat(document.getElementById('gB').value / 100) || 0; const nB = 100; const tB = parseFloat(document.getElementById('tB').value) || 0; function funcionB(vB) { return vB / (127 * (floB - betaB * vB + gB)); } function calcIntB(funcionB, aB, bB, nB) { const hB = (bB - aB) / nB; let sumaB = 0.5 * (funcionB(aB) + funcionB(bB)); for (let i = 1; i < nB; i++) { const vB = aB + i * hB; sumaB += funcionB(vB); } return hB * sumaB; } const calcBdB = calcIntB(funcionB, aB, bB, nB); const bdB = calcBdB; const vB = bB; const fricB = floB - betaB * vB; const reactionB = (bB * tB) / 3.6; const totalResB = bdB + reactionB; document.getElementById('bdB').innerText = bdB.toFixed(0); document.getElementById('frictionB').innerText = fricB.toFixed(2); document.getElementById('reactionB').innerText = reactionB.toFixed(0); document.getElementById('totalResB').innerText = totalResB.toFixed(0); if (!graphB) { const ctxB = document.getElementById('graphB').getContext('2d'); graphB = new Chart(ctxB, { type: 'bar', data: { labels: [''], datasets: [{ label: 'Reaction distance', data: [0], backgroundColor: '#2c8c0a', indexAxis: 'y', }, { label: 'Braking distance (BD)', data: [0], backgroundColor: '#124200', }] }, options: { plugins: { legend: { labels: { color: 'black', } } }, indexAxis: 'y', scales: { x: { stacked: true, ticks: { color: 'black', callback: function (value) { return value; } } }, y: { stacked: true, } } } }); } else { updateGraphB(bdB, reactionB); } } function updateGraphB(bdB, reactionB) { if (graphB) { graphB.data.datasets[0].data = [reactionB]; graphB.data.datasets[1].data = [bdB]; graphB.update(); } } //FRICTION EXPONENTIAL (TANGENT) (C) function funC() { const floC = parseFloat(document.getElementById('floC').value); const betaC = parseFloat(document.getElementById('betaC').value); const aC = parseFloat(document.getElementById('aC').value); const bC = parseFloat(document.getElementById('bC').value); const gC = parseFloat(document.getElementById('gC').value / 100); const nC = 100; const tC = parseFloat(document.getElementById('tC').value); function funcionC(vC) { let flvC = floC * (math.E ** (-betaC * vC)); return vC / (127 * (flvC + gC)); } function calcIntC(funcionC, aC, bC, nC) { const hC = (bC - aC) / nC; let sumaC = 0.5 * (funcionC(aC) + funcionC(bC)); for (let i = 1; i < nC; i++) { const vC = aC + i * hC; sumaC += funcionC(vC); } return hC * sumaC; } const bdC = calcIntC(funcionC, aC, bC, nC); const vC = bC; const fricC = floC * (math.E ** (-betaC * vC)); const reactionC = (bC * tC) / 3.6; const totalResC = bdC + reactionC; document.getElementById('bdC').innerText = bdC.toFixed(0); document.getElementById('frictionC').innerText = fricC.toFixed(2); document.getElementById('reactionC').innerText = reactionC.toFixed(0); document.getElementById('totalResC').innerText = totalResC.toFixed(0); if (!graphC) { const ctxC = document.getElementById('graphC').getContext('2d'); graphC = new Chart(ctxC, { type: 'bar', data: { labels: [''], datasets: [{ label: 'Reaction distance', data: [0], backgroundColor: '#2c8c0a', indexAxis: 'y', }, { label: 'Braking distance (BD)', data: [0], backgroundColor: '#124200', }] }, options: { plugins: { legend: { labels: { color: 'black', } } }, indexAxis: 'y', scales: { x: { stacked: true, ticks: { color: 'black', callback: function funResultC(value) { return value; } } }, y: { stacked: true, } } } }); } else { updateGraphC(bdC, reactionC); } } function updateGraphC(bdC, reactionC) { if (graphC) { graphC.data.datasets[0].data = [reactionC]; graphC.data.datasets[1].data = [bdC]; graphC.update(); } } //FRICTION LEU AND HENRY (TANGENT) (D) function funD() { const bpnD = parseFloat(document.getElementById('bpnD').value); const spD = parseFloat(document.getElementById('spD').value); const aD = parseFloat(document.getElementById('aD').value); const bD = parseFloat(document.getElementById('bD').value); const gD = parseFloat(document.getElementById('gD').value / 100); const nD = 100; const tD = parseFloat(document.getElementById('tD').value); function funcionD(vD) { let snoD = -31 + (1.38 * bpnD); let pnfsgD = 0.45 * (spD ** (-0.47)); let flvD = 0.01 * snoD * math.E ** (-(pnfsgD / 100) * vD); return vD / (127 * (flvD + gD)); } function calcIntD(funcionD, aD, bD, nD) { const hD = (bD - aD) / nD; let sumaD = 0.5 * (funcionD(aD) + funcionD(bD)); for (let i = 1; i < nD; i++) { const vD = aD + i * hD; sumaD += funcionD(vD); } return hD * sumaD; } const bdD = calcIntD(funcionD, aD, bD, nD); const vD = bD; let snoD = -31 + (1.38 * bpnD); let pnfsgD = 0.45 * (spD ** (-0.47)); const fricD = 0.01 * snoD * math.E ** (-(pnfsgD / 100) * vD); const reactionD = (bD * tD) / 3.6; const totalResD = bdD + reactionD; document.getElementById('bdD').innerText = bdD.toFixed(0); document.getElementById('frictionD').innerText = fricD.toFixed(2); document.getElementById('reactionD').innerText = reactionD.toFixed(0); document.getElementById('totalResD').innerText = totalResD.toFixed(0); if (!graphD) { const ctxD = document.getElementById('graphD').getContext('2d'); graphD = new Chart(ctxD, { type: 'bar', data: { labels: [''], datasets: [{ label: 'Reaction distance', data: [0], backgroundColor: '#2c8c0a', indexAxis: 'y', }, { label: 'Braking distance (BD)', data: [0], backgroundColor: '#124200', }] }, options: { plugins: { legend: { labels: { color: 'black', } } }, indexAxis: 'y', scales: { x: { stacked: true, ticks: { color: 'black', callback: function funResultD(value) { return value; } } }, y: { stacked: true, } } } }); } else { updateGraphD(bdD, reactionD); } } function updateGraphD(bdD, reactionD) { if (graphD) { graphD.data.datasets[0].data = [reactionD]; graphD.data.datasets[1].data = [bdD]; graphD.update(); } } //DECELERATION RATE (TANGENT) (E) function funE() { const aE = parseFloat(document.getElementById('aE').value); const bE = parseFloat(document.getElementById('bE').value); const gE = parseFloat(document.getElementById('gE').value / 100); const decelE = parseFloat(document.getElementById('decelE').value); const gravE = 9.8; const tE = parseFloat(document.getElementById('tE').value); const bdE = (bE ** 2 - aE ** 2) / (254 * ((decelE / gravE) + gE)); const reactionE = (bE * tE) / 3.6; const totalResE = bdE + reactionE; document.getElementById('bdE').innerText = bdE.toFixed(0); document.getElementById('gravE').innerText = gravE.toFixed(1); document.getElementById('reactionE').innerText = reactionE.toFixed(0); document.getElementById('totalResE').innerText = totalResE.toFixed(0); if (!graphE) { const ctxE = document.getElementById('graphE').getContext('2d'); graphE = new Chart(ctxE, { type: 'bar', data: { labels: [''], datasets: [{ label: 'Reaction distance', data: [0], backgroundColor: '#2c8c0a', indexAxis: 'y', }, { label: 'Braking distance (BD)', data: [0], backgroundColor: '#124200', }] }, options: { plugins: { legend: { labels: { color: 'black', } } }, indexAxis: 'y', scales: { x: { stacked: true, ticks: { color: 'black', callback: function funResultE(value) { return value; } } }, y: { stacked: true, } } } }); } else { updateGraphE(bdE, reactionE); } } function updateGraphE(bdE, reactionE) { if (graphE) { graphE.data.datasets[0].data = [reactionE]; graphE.data.datasets[1].data = [bdE]; graphE.update(); } } //FRICTION CONSTANT (CURVE) (F) function funF() { const aF = parseFloat(document.getElementById('aF').value); const bF = parseFloat(document.getElementById('bF').value); const gF = parseFloat(document.getElementById('gF').value / 100); const flF = parseFloat(document.getElementById('flF').value); const eF = parseFloat(document.getElementById('eF').value); const rF = parseFloat(document.getElementById('rF').value); const tF = parseFloat(document.getElementById('tF').value); const bdF = (bF ** 2 - aF ** 2) / (254 * (math.sqrt(flF ** 2 - ((bF ** 2 / (127 * rF)) - eF) ** 2) + gF)); const reactionF = (bF * tF) / 3.6; const totalResF = bdF + reactionF; document.getElementById('bdF').innerText = bdF.toFixed(0); document.getElementById('reactionF').innerText = reactionF.toFixed(0); document.getElementById('totalResF').innerText = totalResF.toFixed(0); if (!graphF) { const ctxF = document.getElementById('graphF').getContext('2d'); graphF = new Chart(ctxF, { type: 'bar', data: { labels: [''], datasets: [{ label: 'Reaction distance', data: [0], backgroundColor: '#2c8c0a', indexAxis: 'y', }, { label: 'Braking distance (BD)', data: [0], backgroundColor: '#124200', }] }, options: { plugins: { legend: { labels: { color: 'black', } } }, indexAxis: 'y', scales: { x: { stacked: true, ticks: { color: 'black', callback: function funResultF(value) { return value; } } }, y: { stacked: true, } } } }); } else { updateGraphF(bdF, reactionF); } } function updateGraphF(bdF, reactionF) { if (graphF) { graphF.data.datasets[0].data = [reactionF]; graphF.data.datasets[1].data = [bdF]; graphF.update(); } } //FRICTION LINEAR (CURVE) (G) PENDING!!!!!!!!! function funG() { const floG = parseFloat(document.getElementById('floG').value); const betaG = parseFloat(document.getElementById('betaG').value); const aG = parseFloat(document.getElementById('aG').value); const bG = parseFloat(document.getElementById('bG').value); const gG = parseFloat(document.getElementById('gG').value / 100); const eG = parseFloat(document.getElementById('eG').value); const rG = parseFloat(document.getElementById('rG').value); const tG = parseFloat(document.getElementById('tG').value); const fG = floG - (betaG * bG); const bdG = (bG ** 2 - aG ** 2) / (254 * (Math.sqrt(fG ** 2 - ((bG ** 2 / (127 * rG)) - eG) ** 2) + gG)); const reactionG = (bG * tG) / 3.6; const totalResG = bdG + reactionG; document.getElementById('bdG').innerText = bdG.toFixed(0); document.getElementById('frictionG').innerText = fG.toFixed(2); document.getElementById('reactionG').innerText = reactionG.toFixed(0); document.getElementById('totalResG').innerText = totalResG.toFixed(0); if (!graphG) { const ctxG = document.getElementById('graphG').getContext('2d'); graphG = new Chart(ctxG, { type: 'bar', data: { labels: [''], datasets: [{ label: 'Reaction distance', data: [0], backgroundColor: '#2c8c0a', indexAxis: 'y', }, { label: 'Braking distance (BD)', data: [0], backgroundColor: '#124200', }] }, options: { plugins: { legend: { labels: { color: 'black', } } }, indexAxis: 'y', scales: { x: { stacked: true, ticks: { color: 'black', callback: function funResultG(value) { return value; } } }, y: { stacked: true, } } } }); } else { updateGraphG(bdG, reactionG); } } function updateGraphG(bdG, reactionG) { if (graphG) { graphG.data.datasets[0].data = [reactionG]; graphG.data.datasets[1].data = [bdG]; graphG.update(); } } //FRICTION EXPONENTIAL (CURVE) (H) PENDING!!!!!!!!!!!! function funH() { const floH = parseFloat(document.getElementById('floH').value); const betaH = parseFloat(document.getElementById('betaH').value); const aH = parseFloat(document.getElementById('aH').value); const bH = parseFloat(document.getElementById('bH').value); const gH = parseFloat(document.getElementById('gH').value / 100); const eH = parseFloat(document.getElementById('eH').value); const rH = parseFloat(document.getElementById('rH').value); const tH = parseFloat(document.getElementById('tH').value); const fEH = floH * Math.E ** (-betaH * bH); const bdH = (bH ** 2 - aH ** 2) / (254 * (Math.sqrt(fEH ** 2 - ((bH ** 2 / (127 * rH)) - eH) ** 2) + gH)); const reactionH = (bH * tH) / 3.6; const totalResH = bdH + reactionH; document.getElementById('bdH').innerText = bdH.toFixed(0); document.getElementById('frictionH').innerText = fEH.toFixed(2); document.getElementById('reactionH').innerText = reactionH.toFixed(0); document.getElementById('totalResH').innerText = totalResH.toFixed(0); if (!graphH) { const ctxH = document.getElementById('graphH').getContext('2d'); graphH = new Chart(ctxH, { type: 'bar', data: { labels: [''], datasets: [{ label: 'Reaction distance', data: [0], backgroundColor: '#2c8c0a', indexAxis: 'y', }, { label: 'Braking distance (BD)', data: [0], backgroundColor: '#124200', }] }, options: { plugins: { legend: { labels: { color: 'black', } } }, indexAxis: 'y', scales: { x: { stacked: true, ticks: { color: 'black', callback: function funResultH(value) { return value; } } }, y: { stacked: true, } } } }); } else { updateGraphH(bdH, reactionH); } } function updateGraphH(bdH, reactionH) { if (graphH) { graphH.data.datasets[0].data = [reactionH]; graphH.data.datasets[1].data = [bdH]; graphH.update(); } } //FRICTION LEU AND HENRY (CURVE) (I) PENDING!!!!!!!!!! function funI() { const bpnI = parseFloat(document.getElementById('bpnI').value); const spI = parseFloat(document.getElementById('spI').value); const aI = parseFloat(document.getElementById('aI').value); const bI = parseFloat(document.getElementById('bI').value); const gI = parseFloat(document.getElementById('gI').value / 100); const eI = parseFloat(document.getElementById('eI').value); const rI = parseFloat(document.getElementById('rI').value); const tI = parseFloat(document.getElementById('tI').value); const snoI = -31 + (1.38 * bpnI); const pnfsgI = 0.45 * (spI ** (-0.47)); const fI = 0.01 * snoI * Math.E ** (-(pnfsgI / 100) * bI); const bdI = (bI ** 2 - aI ** 2) / (254 * (Math.sqrt(fI ** 2 - ((bI ** 2 / (127 * rI)) - eI) ** 2) + gI)); const reactionI = (bI * tI) / 3.6; const totalResI = bdI + reactionI; document.getElementById('bdI').innerText = bdI.toFixed(0); document.getElementById('frictionI').innerText = fI.toFixed(2); document.getElementById('reactionI').innerText = reactionI.toFixed(0); document.getElementById('totalResI').innerText = totalResI.toFixed(0); if (!graphI) { const ctxI = document.getElementById('graphI').getContext('2d'); graphI = new Chart(ctxI, { type: 'bar', data: { labels: [''], datasets: [{ label: 'Reaction distance', data: [0], backgroundColor: '#2c8c0a', indexAxis: 'y', }, { label: 'Braking distance (BD)', data: [0], backgroundColor: '#124200', }] }, options: { plugins: { legend: { labels: { color: 'black', } } }, indexAxis: 'y', scales: { x: { stacked: true, ticks: { color: 'black', callback: function funResultI(value) { return value; } } }, y: { stacked: true, } } } }); } else { updateGraphI(bdI, reactionI); } } function updateGraphI(bdI, reactionI) { if (graphI) { graphI.data.datasets[0].data = [reactionI]; graphI.data.datasets[1].data = [bdI]; graphI.update(); } }