Online Planetary Science Impact Crater Estimator

Online Planetary Science Impact Crater Estimator

Estimate the size of an impact crater based on projectile and target properties.

Impactor Properties

Target Properties

${formatEnergy(kineticEnergy)}

`; // Generate SVG const craterDepth = Df / (isComplex ? 8 : 4); // Approximation const svgWidth = 300; const svgHeight = 150; const rimHeight = craterDepth * 0.1; craterSvgContainer.innerHTML = ` Diameter: ${formatDistance(Df)} `; resultsSection.classList.remove('hidden'); }; /** * Generates and triggers the download of a PDF report. */ const generatePdf = () => { if (!lastResult) return; const { jsPDF } = window.jspdf; const doc = new jsPDF(); doc.setFontSize(20); doc.text("Impact Crater Estimation Report", 105, 20, { align: 'center' }); doc.setFontSize(12); doc.setTextColor(100); doc.text(`Date: ${new Date().toLocaleDateString()}`, 14, 30); // Input Parameters Table doc.autoTable({ startY: 35, head: [['Input Parameter', 'Value']], body: [ ['Impactor Diameter', `${lastResult.inputs.L} m`], ['Impactor Velocity', `${lastResult.inputs.v} km/s`], ['Impact Angle', `${lastResult.inputs.theta}°`], ['Target Body', lastResult.inputs.targetBody], ['Target Surface', lastResult.inputs.targetType], ], theme: 'grid', headStyles: { fillColor: [30, 58, 138] }, // blue-800 }); // Results Table doc.autoTable({ startY: doc.lastAutoTable.finalY + 10, head: [['Calculated Result', 'Value']], body: [ ['Impact Energy', formatEnergy(lastResult.outputs.kineticEnergy)], ['Transient Crater Diameter', formatDistance(lastResult.outputs.Dt)], ['Final Crater Type', lastResult.outputs.isComplex ? 'Complex' : 'Simple'], [{ content: 'Estimated Final Diameter', styles: { fontStyle: 'bold' } }, { content: formatDistance(lastResult.outputs.Df), styles: { fontStyle: 'bold' } }], ], theme: 'striped', headStyles: { fillColor: [30, 64, 175] }, // blue-700 }); doc.save('Impact_Crater_Report.pdf'); }; // --- EVENT LISTENERS --- calculateBtn.addEventListener('click', handleCalculation); downloadPdfBtn.addEventListener('click', generatePdf); angleInput.addEventListener('input', (e) => { angleLabel.textContent = e.target.value; }); });
Scroll to Top