Javascript: ещё линейная пропорция или пересчёт интервалов онлайн
Расчёт вида "пересчитать значение x
, принадлежащее интервалу допустимых значений [a,b]
в значение y
, принадлежащее интервалу [c,d]
" часто встречается в компьютерной графике (масштабировать объект в нужный прямоугольник на экране), да и при любой другой обработке данных.
Формула для такого расчёта -
y = c + (x-a) * (d-c) / (b-a)
Разумеется, она работает, если все данные корректны. Ну или их можно корректировать в процессе ввода.
Ниже для онлайн-решения этой "супер-задачи" прилагается код из моей коллекции учебных скриптов, он, на самом деле, похож на вот этот.
Любопытно в коде разве что управление фокусом в форме - при необходимости меньшее и большее значения границ интервалов [a,b]
, [c,d]
меняются местами, а курсор сам "скачет" в нужное поле ввода.
Если значение x
изначально не принадлежит интервалу [a,b]
, это, в принципе, никак не меняет формулы, но на всякий случай в форме при таких данных выводится дополнительное предупреждение.
Ниже показаны скрипт в работе и его полный листинг.
<script type="text/javascript"> var whichFocus=null; function deltrim(string) { return string.replace (/\s+/g,""); } function toFixed(n) { var z = document.formpro.fixedN.options[document.formpro.fixedN.selectedIndex].value; return (z==-1 ? n : n.toFixed(z)); } function isLastPoint (a) { return a.substring(a.length-1)=='.' && a.lastIndexOf('.') == a.indexOf('.'); } function calcMe () { //Обработка интервала "откуда" var x=parseFloat(deltrim(document.formpro.x.value)); var a=parseFloat(deltrim(document.formpro.a.value)); var b=parseFloat(deltrim(document.formpro.b.value)); document.getElementById('formnote').innerHTML = ''; if (!isNaN(a) && !isNaN(b)) { if (a>b) { var temp = a; a = b; b = temp; document.formpro.a.value = toFixed(a); document.formpro.b.value = toFixed(b); if (whichFocus) { if (whichFocus.name=='a') document.formpro.b.focus(); else if (whichFocus.name=='b') document.formpro.a.focus(); } } if (!(x>=a && x<=b)) { document.getElementById('formnote').innerHTML = 'Исходное значение не попадает в интервал!'; } } //Обработка интервала "куда" var c=parseFloat(deltrim(document.formpro.c.value)); var d=parseFloat(deltrim(document.formpro.d.value)); if (!isNaN(c) && !isNaN(d) && c>d) { var temp = c; c = d; d = temp; document.formpro.c.value = toFixed(c); document.formpro.d.value = toFixed(d); if (whichFocus) { if (whichFocus.name=='c') document.formpro.d.focus(); else if (whichFocus.name=='d') document.formpro.c.focus(); } } //Расчёт и вывод if (isNaN(x) || isNaN(a) || isNaN(b) || isNaN(c) || isNaN(d)) { document.formpro.y.value = ''; return; } document.formpro.x.value = x + (isLastPoint(document.formpro.x.value) ? '.' : ''); document.formpro.a.value = a + (isLastPoint(document.formpro.a.value) ? '.' : ''); document.formpro.b.value = b + (isLastPoint(document.formpro.b.value) ? '.' : ''); document.formpro.c.value = c + (isLastPoint(document.formpro.c.value) ? '.' : ''); document.formpro.d.value = d + (isLastPoint(document.formpro.d.value) ? '.' : ''); var y = c + (x-a) * (d-c) / (b-a); document.formpro.y.value = (isNaN(y) ? "Ошибка" : toFixed(y)); } function clearMe () { document.formpro.x.value = ''; document.formpro.a.value = ''; document.formpro.b.value = ''; document.formpro.y.value = ''; document.formpro.c.value = ''; document.formpro.d.value = ''; document.formpro.fixedN.selectedIndex = 0; } </script> <noscript> <div align="center"><p>Извините, для работы приложения нужен включённый Javascript</p></div> </noscript> <form name="formpro" method="post" onsubmit="return false;"> <table align="center" cellpadding="0" cellspacing="4" border="0"> <tr> <td align="center" valign="middle">Значение</td> <td align="center" valign="middle"><input type="text" name="x" size="10" maxlength="8" value="" tabindex="1" onselect="calcMe();" onclick="calcMe();" onkeyup="calcMe();" onfocus="whichFocus=this;" /></td> <td align="center" valign="middle">из интервала [</td> <td align="center" valign="middle"><input type="text" name="a" size="10" maxlength="8" value="" tabindex="2" onselect="calcMe();" onclick="calcMe();" onkeyup="calcMe();" onfocus="whichFocus=this;" /></td> <td width="8" align="center" valign="middle">,</td> <td align="center" valign="middle"><input type="text" name="b" size="10" maxlength="8" value="" tabindex="3" onselect="calcMe();" onclick="calcMe();" onkeyup="calcMe();" onfocus="whichFocus=this;" /></td> <td width="8" align="center" valign="middle">]</td> <td align="center" valign="middle"> <input type="button" name="clear" value="Очистить" onclick="clearMe();" tabindex="6"/> </td> </tr> <tr> <td colspan="8" align="center" valign="middle"><p id="formnote"></p></td> </tr> <tr> <td align="center" valign="middle">=</td> <td align="center" valign="middle"><input type="text" name="y" size="10" value="" tabindex="8" readonly /></td> <td align="center" valign="middle">из интервала [</td> <td align="center" valign="middle"><input type="text" name="c" size="10" maxlength="8" value="" tabindex="4" onselect="calcMe();" onclick="calcMe();" onkeyup="calcMe();" onfocus="whichFocus=this;" /></td> <td width="8" align="center" valign="middle">,</td> <td align="center" valign="middle"><input type="text" name="d" size="10" maxlength="8" value="" tabindex="5" onselect="calcMe();" onclick="calcMe();" onkeyup="calcMe();" onfocus="whichFocus=this;" /></td> <td width="8" align="center" valign="middle">]</td> <td align="center" valign="middle"> <select name="fixedN" size="1" tabindex="7" onchange="calcMe();"> <option value="-1" selected>не округлять <option value="0">в целых <option value="1">1 знак <option value="2">2 знака <option value="3">3 знака <option value="4">4 знака <option value="5">5 знаков <option value="6">6 знаков <option value="7">7 знаков <option value="8">8 знаков <option value="9">9 знаков </select> </td> </tr> </table> </form>
скриншот приложения в работе, если стили блога отключены
08.12.2016, 12:23 [4023 просмотра]