Kepler's Laws Planetary Motion
Select Calculation
Inputs
kg
(dimensionless)
Results
Error: Invalid Semi-Major Axis (a > 0), Eccentricity (0 ≤ e < 1), or Central Mass (M > 0).
'; } else { // vp² = (G * M / a) * ((1+e) / (1-e)) // va² = (G * M / a) * ((1-e) / (1+e)) const GM_a = (G * M_kg) / a_m; const vp2 = GM_a * (1 + e) / (1 - e); // Avoid division by zero if e=1 (already checked) const va2 = GM_a * (1 - e) / (1 + e); const vp_ms = Math.sqrt(vp2); const va_ms = Math.sqrt(va2); resultsHTML = `Perihelion Speed (vp): ${formatSpeed(vp_ms)}
Aphelion Speed (va): ${formatSpeed(va_ms)}
`;
lastCalculationData.results.speed_p_ms = vp_ms;
lastCalculationData.results.speed_a_ms = va_ms;
}
} else if (mode === 'law3_simple') {
// T² = a³ where T is years, a is AU
const a_AU = getValueSI(axisInput, axisUnitSelect, { AU: 1 }); // Get value directly in AU
const T_yr = getValueSI(periodInput, periodUnitSelect, { year: 1 }); // Get value directly in years
// User needs to provide *either* a_AU OR T_yr
if (!isNaN(a_AU) && a_AU > 0 && isNaN(T_yr)) { // Calculate T from a
const T_calc_yr = Math.sqrt(Math.pow(a_AU, 3));
resultsHTML = `Orbital Period (T): ${T_calc_yr.toFixed(4)} years
`;
lastCalculationData.results.period_yr = T_calc_yr;
lastCalculationData.inputs.axis_unit = 'AU'; // Override for PDF clarity
} else if (!isNaN(T_yr) && T_yr > 0 && isNaN(a_AU)) { // Calculate a from T
const a_calc_AU = Math.cbrt(Math.pow(T_yr, 2));
resultsHTML = `Semi-Major Axis (a): ${a_calc_AU.toFixed(4)} AU
`;
lastCalculationData.results.axis_AU = a_calc_AU;
lastCalculationData.inputs.period_unit = 'year'; // Override for PDF clarity
} else {
isValid = false; resultsHTML = 'Error: For T²=a³ mode, please provide EITHER Semi-Major Axis (in AU) OR Orbital Period (in years).
'; } } else { isValid = false; resultsHTML = 'Error: Invalid calculation mode selected.
'; } } catch (error) { isValid = false; resultsHTML = `An unexpected error occurred: ${error.message}
`; console.error("Calculation Error:", error); } // --- Display Results --- if (isValid) { resultsOutputDiv.innerHTML = resultsHTML; resultsSection.style.display = 'block'; } else { resultsOutputDiv.innerHTML = resultsHTML; // Show error message resultsSection.style.display = 'block'; // Still show section for error lastCalculationData = null; // Invalidate PDF data on error } } // --- PDF Generation --- function downloadPdf() { if (!lastCalculationData || Object.keys(lastCalculationData.results).length === 0) { alert("Please perform a successful calculation first."); return; } if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') { alert('Error: PDF generation library (jsPDF) is not loaded.'); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF(); // --- Colors & Setup --- const primaryColor = getCssVariable('--kep-primary-color'); const textColor = '#333333'; // Use standard dark text for PDF readability const accentColor = '#5C6BC0'; // Keep accent consistent const backgroundColor = '#FFFFFF'; // White background const pageHeight = doc.internal.pageSize.height || doc.internal.pageSize.getHeight(); const pageWidth = doc.internal.pageSize.width || doc.internal.pageSize.getWidth(); let yPos = 20; const leftMargin = 15; const indent = 20; const valueIndent = leftMargin + 75; const lineHeight = 7; const sectionSpacing = 10; // PDF Helper functions (similar to previous tool, adapted for white BG) function addTitle(text) { /* ... standard implementation ... */ if (yPos > pageHeight - 30) { doc.addPage(); yPos = 20; } doc.setFontSize(16); doc.setFont(undefined, 'bold'); doc.setTextColor(primaryColor); doc.text(text, pageWidth / 2, yPos, { align: 'center' }); yPos += lineHeight * 2; } function addSectionHeader(text) { /* ... standard implementation ... */ if (yPos > pageHeight - 25) { doc.addPage(); yPos = 20; } doc.setFontSize(12); doc.setFont(undefined, 'bold'); doc.setTextColor(accentColor); doc.text(text, leftMargin, yPos); yPos += lineHeight * 1.5; doc.setFontSize(10); doc.setFont(undefined, 'normal'); doc.setTextColor(textColor); } function addLine(label, value, valueColor = textColor, isBold = false) { /* ... standard implementation ... */ if (yPos > pageHeight - 15) { doc.addPage(); yPos = 20; } doc.setFont(undefined, isBold ? 'bold' : 'normal'); doc.setTextColor(textColor); doc.text(label, indent, yPos); doc.setTextColor(valueColor); doc.text(String(value), valueIndent, yPos); yPos += lineHeight; } // --- PDF Content --- const modeText = modeSelect.options[modeSelect.selectedIndex].text; addTitle(`Kepler's Laws Calculation: ${modeText}`); // Inputs Section addSectionHeader("Inputs Used"); const inputs = lastCalculationData.inputs; // Conditionally show inputs based on mode if (modeSelect.value.includes('law3') && modeSelect.value !== 'law3_simple' || modeSelect.value === 'law2_speeds') { let massText = `${inputs.mass_raw} kg`; if (inputs.mass_preset !== 'custom') massText += ` (${inputs.mass_preset})`; addLine("Central Mass (M):", massText); } if (modeSelect.value !== 'law3_axis' && modeSelect.value !== 'law3_simple') { addLine("Semi-Major Axis (a):", `${inputs.axis_raw} ${inputs.axis_unit}`); } else if (modeSelect.value === 'law3_simple' && lastCalculationData.results.period_yr) { // If 'a' was the input for simple mode addLine("Semi-Major Axis (a):", `${inputs.axis_raw} AU`); } if (modeSelect.value === 'law1_distances' || modeSelect.value === 'law2_speeds') { addLine("Eccentricity (e):", inputs.ecc_raw); } if (modeSelect.value !== 'law3_period' && modeSelect.value !== 'law3_simple') { addLine("Orbital Period (T):", `${inputs.period_raw} ${inputs.period_unit}`); } else if (modeSelect.value === 'law3_simple' && lastCalculationData.results.axis_AU) { // If 'T' was the input for simple mode addLine("Orbital Period (T):", `${inputs.period_raw} years`); } yPos += sectionSpacing; // Results Section addSectionHeader("Calculated Results"); const results = lastCalculationData.results; if (results.perihelion_m !== undefined) { addLine("Perihelion Distance:", formatValue(results.perihelion_m, lengthFactors), accentColor, true); } if (results.aphelion_m !== undefined) { addLine("Aphelion Distance:", formatValue(results.aphelion_m, lengthFactors), accentColor, true); } if (results.period_s !== undefined) { addLine("Orbital Period (T):", formatValue(results.period_s, timeFactors), accentColor, true); addLine("", `(${results.period_s.toExponential(4)} seconds)`, textColor); } if (results.period_yr !== undefined) { // Simple mode T result addLine("Orbital Period (T):", `${results.period_yr.toFixed(4)} years`, accentColor, true); } if (results.axis_m !== undefined) { addLine("Semi-Major Axis (a):", formatValue(results.axis_m, lengthFactors), accentColor, true); addLine("", `(${results.axis_m.toExponential(4)} meters)`, textColor); } if (results.axis_AU !== undefined) { // Simple mode a result addLine("Semi-Major Axis (a):", `${results.axis_AU.toFixed(4)} AU`, accentColor, true); } if (results.mass_kg !== undefined) { addLine("Central Body Mass (M):", formatMass(results.mass_kg), accentColor, true); } if (results.speed_p_ms !== undefined) { addLine("Perihelion Speed (vp):", formatSpeed(results.speed_p_ms), accentColor, true); } if (results.speed_a_ms !== undefined) { addLine("Aphelion Speed (va):", formatSpeed(results.speed_a_ms), accentColor, true); } // --- Save PDF --- try { doc.save('Keplers_Laws_Calculation.pdf'); } catch (e) { console.error("Error saving PDF:", e); alert("An error occurred while generating the PDF."); } } })(); // End IIFE