Spaces:
Sleeping
Sleeping
<html lang="ru"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Расчёт удобрений с плотностью</title> | |
<style> | |
body { font-family: Arial, sans-serif; margin: 20px; } | |
input { padding: 8px; margin: 5px; width: 200px; } | |
button { padding: 8px 12px; cursor: pointer; margin-top: 10px; } | |
.result { margin-top: 20px; } | |
</style> | |
</head> | |
<body> | |
<h1>Расчёт удобрений с учётом плотности</h1> | |
<div> | |
<h3>Введите состав удобрений (%):</h3> | |
<label>Ca в Ca(NO₃)₂·4H₂O:</label><input id="ca_content_ca" value="19" step="0.1"><br> | |
<label>NO3 в Ca(NO₃)₂·4H₂O:</label><input id="ca_content_no3" value="14.9" step="0.1"><br> | |
<label>P в KH₂PO₄:</label><input id="p_content" value="22" step="0.1"><br> | |
<label>K в KH₂PO₄:</label><input id="k_content_kh2po4" value="28" step="0.1"><br> | |
<label>K в KNO₃:</label><input id="k_content_kno3" value="46" step="0.1"><br> | |
<label>NO3 в KNO₃:</label><input id="n_content_kno3" value="13.5" step="0.1"><br> | |
<label>Mg в MgSO₄·7H₂O:</label><input id="mg_content_mgso4" value="16" step="0.1"><br> | |
<label>S в MgSO₄·7H₂O:</label><input id="s_content_mgso4" value="13.5" step="0.1"><br> | |
<label>Mg в Mg(NO₃)₂·6H₂O:</label><input id="mg_content_mgno3" value="9.8" step="0.1"><br> | |
<label>NO3 в Mg(NO₃)₂·6H₂O:</label><input id="n_content_mgno3" value="11" step="0.1"><br> | |
<label>K в K₂SO₄:</label><input id="k_content_k2so4" value="41.5" step="0.1"><br> | |
<label>S в K₂SO₄:</label><input id="s_content_k2so4" value="18" step="0.1"><br> | |
<label>NH4 в NH₄NO₃:</label><input id="nh4_content_nh4no3" value="17" step="0.1"><br> | |
<label>NO3 в NH₄NO₃:</label><input id="no3_content_nh4no3" value="17" step="0.1"><br> | |
<label>K в KCl:</label><input id="k_content_kcl" value="52.4" step="0.1"><br> | |
<label>Cl в KCl:</label><input id="cl_content_kcl" value="47.6" step="0.1"><br> | |
<h3>Требуемые концентрации (мг/л):</h3> | |
<label>NO3:</label><input id="no3" value="210"><br> | |
<label>NH4:</label><input id="nh4" value="17"><br> | |
<label>P:</label><input id="p" value="46"><br> | |
<label>K:</label><input id="k" value="371"><br> | |
<label>Ca:</label><input id="ca" value="216"><br> | |
<label>Mg:</label><input id="mg" value="58"><br> | |
<label>S:</label><input id="s" value="141"><br> | |
<label>Cl:</label><input id="cl" value="35"><br> | |
<button onclick="calculate()">Рассчитать</button> | |
</div> | |
<div class="result" id="result"></div> | |
<script> | |
const DENSITY_DATA = { | |
"NH4NO3": [[5, 1.001], [690, 1.2528]], | |
"Ca(NO3)2*4H2O": [[5, 1.0015], [920, 1.4208]], | |
"MgSO4*7H2O": [[5, 1.0014], [695, 1.2974]], | |
"Mg(NO3)2*6H2O": [[5, 1.0001], [500, 1.2007]], | |
"KNO3": [[5, 1.0011], [280, 1.1627]], | |
"K2SO4": [[5, 1.002], [110, 1.0825]], | |
"KH2PO4": [[5, 1.0016], [110, 1.0719]], | |
"KCl": [[5, 1.002], [100, 1.045]] // Примерные данные для KCl | |
}; | |
function getDensity(fertilizer, mass) { | |
const data = DENSITY_DATA[fertilizer]; | |
if (!data || mass <= 0) return 1; | |
for (let i = 0; i < data.length - 1; i++) { | |
if (mass >= data[i][0] && mass <= data[i + 1][0]) { | |
const [x1, y1] = data[i]; | |
const [x2, y2] = data[i + 1]; | |
return y1 + (mass - x1) * (y2 - y1) / (x2 - x1); | |
} | |
} | |
return data[data.length - 1][1]; | |
} | |
function round(value, precision = 2) { | |
return Number(value.toFixed(precision)); | |
} | |
function calculate() { | |
// Состав удобрений (% → доли) | |
const fertilizers = { | |
"Ca(NO3)2*4H2O": { Ca: parseFloat(document.getElementById("ca_content_ca").value) / 100, NO3: parseFloat(document.getElementById("ca_content_no3").value) / 100 }, | |
"KH2PO4": { P: parseFloat(document.getElementById("p_content").value) / 100, K: parseFloat(document.getElementById("k_content_kh2po4").value) / 100 }, | |
"KNO3": { K: parseFloat(document.getElementById("k_content_kno3").value) / 100, NO3: parseFloat(document.getElementById("n_content_kno3").value) / 100 }, | |
"MgSO4*7H2O": { Mg: parseFloat(document.getElementById("mg_content_mgso4").value) / 100, S: parseFloat(document.getElementById("s_content_mgso4").value) / 100 }, | |
"Mg(NO3)2*6H2O": { Mg: parseFloat(document.getElementById("mg_content_mgno3").value) / 100, NO3: parseFloat(document.getElementById("n_content_mgno3").value) / 100 }, | |
"K2SO4": { K: parseFloat(document.getElementById("k_content_k2so4").value) / 100, S: parseFloat(document.getElementById("s_content_k2so4").value) / 100 }, | |
"NH4NO3": { NH4: parseFloat(document.getElementById("nh4_content_nh4no3").value) / 100, NO3: parseFloat(document.getElementById("no3_content_nh4no3").value) / 100 }, | |
"KCl": { K: parseFloat(document.getElementById("k_content_kcl").value) / 100, Cl: parseFloat(document.getElementById("cl_content_kcl").value) / 100 } | |
}; | |
// Целевые концентрации | |
const need = { | |
NO3: parseFloat(document.getElementById("no3").value), | |
NH4: parseFloat(document.getElementById("nh4").value), | |
P: parseFloat(document.getElementById("p").value), | |
K: parseFloat(document.getElementById("k").value), | |
Ca: parseFloat(document.getElementById("ca").value), | |
Mg: parseFloat(document.getElementById("mg").value), | |
S: parseFloat(document.getElementById("s").value), | |
Cl: parseFloat(document.getElementById("cl").value) | |
}; | |
// Приоритеты | |
const priority = { Ca: 3000, P: 3000, K: 2000, Mg: 2000, S: 2000, NO3: 1500, NH4: 1500, Cl: 1000 }; | |
const weights = {}; | |
const calcElements = { NO3: 0, NH4: 0, P: 0, K: 0, Ca: 0, Mg: 0, S: 0, Cl: 0 }; | |
let remaining = { ...need }; | |
// Итеративный расчёт с ограничением превышения | |
for (let i = 0; i < 10; i++) { | |
for (const [id, elements] of Object.entries(fertilizers)) { | |
const sorted = Object.entries(elements) | |
.filter(([_, v]) => v > 0) | |
.sort(([a], [b]) => (priority[b] || 0) - (priority[a] || 0) + (remaining[b] || 0) / (elements[b] || 1) - (remaining[a] || 0) / (elements[a] || 1)); | |
const primary = sorted[0]?.[0]; | |
if (!primary || remaining[primary] <= 0) continue; | |
let weight = remaining[primary] / elements[primary]; | |
weights[id] = weight; // Перезаписываем, а не суммируем | |
// Проверяем вклад и корректируем вес, чтобы не превысить цель | |
for (const [elem, value] of Object.entries(elements)) { | |
const contribution = weight * value; | |
if (calcElements[elem] + contribution > need[elem]) { | |
weight = (need[elem] - calcElements[elem]) / value; | |
weights[id] = weight > 0 ? weight : 0; | |
} | |
} | |
// Обнуляем предыдущий вклад этого удобрения | |
for (const [elem] of Object.entries(elements)) { | |
calcElements[elem] -= (weights[id] * elements[elem] || 0); | |
} | |
// Добавляем новый вклад | |
for (const [elem, value] of Object.entries(elements)) { | |
const contribution = weights[id] * value; | |
calcElements[elem] += contribution; | |
remaining[elem] = (need[elem] || 0) - calcElements[elem]; | |
} | |
// Учёт плотности | |
const density = Object.keys(weights).reduce((acc, key) => acc + getDensity(key, weights[key] || 0), 0) / Object.keys(weights).length || 1; | |
for (const key in weights) { | |
weights[key] *= density; | |
} | |
} | |
} | |
// Финальная плотность и концентрации | |
const density = Object.keys(weights).reduce((acc, key) => acc + getDensity(key, weights[key] || 0), 0) / Object.keys(weights).length || 1; | |
const finalElements = {}; | |
for (const [id, weight] of Object.entries(weights)) { | |
for (const [elem, value] of Object.entries(fertilizers[id])) { | |
finalElements[elem] = (finalElements[elem] || 0) + (weight * value) / density; | |
} | |
} | |
// Вывод результата | |
let resultText = "<h3>Результаты (г/1000 л):</h3>"; | |
for (const [id, weight] of Object.entries(weights)) { | |
resultText += `<p>${id}: ${round(weight)}`; | |
const contributions = Object.entries(fertilizers[id]).map(([e, v]) => `${e}: ${round(weight * v / density)}`).join(", "); | |
resultText += ` (${contributions})</p>`; | |
} | |
resultText += `<h3>Итоговые концентрации (мг/л, плотность ${round(density, 4)}):</h3>`; | |
resultText += `NO3: ${round(finalElements.NO3 || 0)}, NH4: ${round(finalElements.NH4 || 0)}, P: ${round(finalElements.P || 0)}, K: ${round(finalElements.K || 0)}, Ca: ${round(finalElements.Ca || 0)}, Mg: ${round(finalElements.Mg || 0)}, S: ${round(finalElements.S || 0)}, Cl: ${round(finalElements.Cl || 0)}`; | |
document.getElementById("result").innerHTML = resultText; | |
} | |
</script> | |
</body> | |
</html> |