rechnen mit Winkelfunktionen
matze511
- javascript
- mathematik
Hallo liebe Profis,
ich stehe vor einem Problem mit den Winkelfunktionen bei dem rechtwinkligen Dreieck. Ich habe hier ein kleines JavaScript:
function addieren() {
grundmaß = parseFloat(document.getElementById('grundmaß').value.replace(',', '.'));
dachneigung = parseFloat(document.getElementById('dachneigung').value.replace(',', '.'));
dachüberstand = parseFloat(document.getElementById('dachüberstand').value.replace(',', '.'));
traufhöhe = parseFloat(document.getElementById('traufhöhe').value.replace(',', '.'));
fußpfettenrücksprung = parseFloat(document.getElementById('fußpfettenrücksprung').value.replace(',', '.'));
raumhöheRohbau = parseFloat(document.getElementById('raumhöheRohbau').value.replace(',', '.'));
firsthöhe = parseFloat(((grundmaß + dachüberstand) * (Math.tan(dachneigung))).toPrecision(4));
document.getElementById('firsthöhe').value = firsthöhe;
}
Wenn ich jetzt für Grundmaß 5,00 einsetze, für Dachüberstand 0,50 und für Dachneigung 30° dann gibt es mir -35.23 aus. Die richtige Lösung laut den Winkelsätzen wäre aber 3,175, wo hab ich hier den Denkfehler?
LG matze
@@matze511
Dachneigung 30°
Das gibts du wie an? Als Wert 30
?
wo hab ich hier den Denkfehler?
Vermutlich an der Stelle, wo du denkst, Winkelfunktionen würden als Argument den Winkel in Grad erwarten. Tun sie aber nicht, sondern im Bogenmaß (Radiant).
Kwakoni Yiquan
Also heißt das ich muß im Vorfeld noch eine Funktion haben, die den Wert errechnet.
const degreesToRads = deg => (deg * Math.PI) / 180.0;
degreesToRads(90.0); // ~1.5708
oder geht das auch alles in einem?
@@matze511
const degreesToRads = deg => (deg * Math.PI) / 180.0; degreesToRads(90.0); // ~1.5708
Warum 180.0
und 90.0
? JavaScript ist nicht C, wo man ganzzahlige Werte nicht auch ohne Nachkommaanteil als Fließkommazahlen verwenden kann.
oder geht das auch alles in einem?
firsthöhe = (grundmaß + dachüberstand) * Math.tan(dachneigung * Math.PI/180);
Oder wie @Rolf B sagte: dachneigung
gleich beim Einlesen in Radiant umrechnen.
firsthöhe
würde ich hier als Zahlenwert belassen, nicht in einen String umwandeln. Das Runden auf die gewünschte Anzahl von Nachkommastellen geschieht erst bei der Ausgabe, nicht schon bei der Berechnung.
Kwakoni Yiquan
@@Gunnar Bittersmann
Oder wie @Rolf B sagte
Ist hier was kaputt? Warum wird die @
-Erwähnung nicht zu einem Link aufgelöst?
Edit: Huch, auf einmal geht’s wieder.
Kwakoni Yiquan
Hallo matze511,
abgesehen von den Winkeleinheiten, die Gunnar benannte, hätte ich folgende Anmerkungen:
die Funktion heißt addieren
, tut aber nachweislich mehr als das. Ich sehe eine Multiplikation und einen Tangens. Benenne deine Funktionen so, dass ihr Zweck aus dem Namen ersichtlich ist.
Du deklariest deine Variablen nicht. Damit werden globale Variablen daraus, die ihren Wert auch behalten, wenn die Funktion beendet ist. Ich bin sicher, dass das nicht deine Absicht ist. Verwende const, wenn du der Variablen nur einmal einen Wert zuweist und sie dann ihren Wert behält, oder let, wenn Du während eines Funktionsdurchlaufs den Wert zuweisen und nochmal ändern musst.
// so
const grundmaß = parseFloat(...);
// oder so
let grundmaß = parseFloat(...);
Du liest den value aus den Eingabefeldern. Sind das Texteingabefelder? Wenn ja, dann musst Du das so tun, ABER du hast auch das Problem, dass die Eingabewerte möglicherweise keine Float-Zahl darstellen. D.h. parseFloat liefert Dir eventuell NaN (not a number). Damit weiterzurechnen führt am Ende zu NaN in der firsthöhe, und das möchtest Du nicht im Ausgabefeld sehen. Frage also mit isNaN() ab, ob du eine gültige Zahl hast.
Oder besser: probiere input type="number" aus. Setze den step-Wert so, dass die Zahl der Nachkommastellen für den Sachverhalt passt. Dann kannst Du den Eingabewert mit valueAsNumber
statt value
abholen und hast gleich eine Zahl. Die Frage "Dezimalkomma oder Dezimalpunkt" löst dann der Browser für Dich.
Du klammerst Math.tan(wert) ein. Das ist nicht kein Fehler, aber unnötig
Du berechnest die Firsthöhe mit einer Formel. Auf das Ergebnis wendest Du toPrecision(4) an, um auf 4 Nachkommastellen zu runden, dann machst Du mit parseFloat() wieder eine Zahl daraus. Wenn es Dir nur um die gerundete Darstellung geht, dann lass das parseFloat weg. Wenn du mit dem gerundeten Wert weiterrechnen willst, dann - ja - hast Du eine fehlendes JavaScript-Feature gefunden: Runden auf N Nachkommastellen. Ob man nun mit parseFloat(x.toPrecision(4))
arbeitet oder mit Math.round(x*10000)/10000
, ist wohl eher egal. Aber wenn Du das öfter tun musst, schreib Dir eine Funktion. Das ist zwar mehr Code, aber weniger Rechenaufwand für den Computer.
function runden(wert, stellen = 0) {
const skalierung = 10 ** stellen;
return Math.round(wert * skalierung) / skalierung;
}
function getFloatValue(id) {
const element = document.getElementById(id);
if (element)
return parseFloat(element.value.replace(',', '.'));
else
return NaN;
}
function berechnen() {
const grundmaß = getFloatValue('grundmaß'),
dachneigung = getFloatValue('dachneigung') / 180 * Math.PI,
...
raumhöheRohbau = getFloatValue('raumhöheRohbau');
const firsthöhe = (grundmaß + dachüberstand) * Math.tan(dachneigung);
document.getElementById('firsthöhe').value = firsthöhe.toPrecision(4);
}
Die Dachneigung rechne ich gleich beim Auslesen ins Bogenmaß um.
Beachte in dem mehrzeiligen const: jede Deklaration endet mit einem Komma, außer der letzten, da muss das Semikolon stehen, dass das Statement beendet
Wegen der Verwendung von toPrecision: siehe weiter oben…
Rolf
Hallo und erstmal vielen dank für die ausführliche Antwort! Besteht auch die Möglichkeit das sofort nach Eingabe selber rechnet ohne das ich einen Button drücken muss?
Hallo
Hallo und erstmal vielen dank für die ausführliche Antwort! Besteht auch die Möglichkeit das sofort nach Eingabe selber rechnet ohne das ich einen Button drücken muss?
Du kannst für das Eingabefeld einen Eventhandler „change“ definieren. Der wird bei jeder Änderung des Inhalts des Eingabefelds ausgelöst. Die Frage, was du mit dem Zwischenstand tust - die Eingabe muss in diesem Moment ja nicht vollständig sein –, sei aber gestattet. Im Zweifelsfall ist der Eventhandler „blur“ besser geeignet, der ausgeführt wird, wenn das Element/das Eingabefeld den Fokus verliert, also dann, wenn die Eingabe (mutmaßlich) fertig ist und ein anderes Feld fokussiert wird.
Tschö, Auge
@@Auge
Hallo und erstmal vielen dank für die ausführliche Antwort! Besteht auch die Möglichkeit das sofort nach Eingabe selber rechnet ohne das ich einen Button drücken muss?
Du kannst für das Eingabefeld einen Eventhandler „change“ definieren. Der wird bei jeder Änderung des Inhalts des Eingabefelds ausgelöst.
Nein, wird er nicht. Das hast du wohl mit dem input
-Event verwechselt? ☞ Codepen
Im Zweifelsfall ist der Eventhandler „blur“ besser geeignet, der ausgeführt wird, wenn das Element/das Eingabefeld den Fokus verliert, also dann, wenn die Eingabe (mutmaßlich) fertig ist und ein anderes Feld fokussiert wird.
Nö, blur
ist nicht so gut geeignet. Das feuert nicht bei den Pfeiltasten.
Besser geeignet ist change
. ☞ Codepen
Kwakoni Yiquan
Hallo
Im Zweifelsfall ist der Eventhandler „blur“ besser geeignet, der ausgeführt wird, wenn das Element/das Eingabefeld den Fokus verliert, also dann, wenn die Eingabe (mutmaßlich) fertig ist und ein anderes Feld fokussiert wird.
Nö,
blur
ist nicht so gut geeignet. Das feuert nicht bei den Pfeiltasten.
Warum sollte es auch, wenn ich doch mit den Pfeiltasten nur den Cursor innerhalb des Feldes bewege, dieses aber nicht verlasse (wobei dann „blur“ ausgelöst würde)?
Tschö, Auge
Hallo Auge,
change
feuert bei Tastatureingaben auch erst, wenn das Input-Feld den Focus verliert. input
feuert dagegen bei jedem Tastendruck. Wenn man da 123 eingibt, wird erst für 1, dann für 12 und dann erst für 123 gerechnet. Wenn das stört, muss man das Ausführen des Eventhandlers verzögern.
Ich habe schon beides gemacht: bei change habe ich einen OK-Button plaziert, dessen einzige Aufgabe war, den Usern etwas zum draufklicken zu bieten, statt "Klicken Sie irgendwo hin".
Bei meinem Energierechner verwende ich inzwischen ein verzögertes Input-Event und lese die <input type="number>
mit valueAsNumber aus.
Gruß
Jürgen
Hallo Rolf,
das hat alles wunderbar geklappt aber nun steh ich wieder vor einem Problem, wie kann ich es anstellen das es eine Rechnung nach der anderen Ausführt, da es mehrere Rechnungen für das Endergebnis sind. Ach und wie speichert man werte die nirgends auf der Webseite auftauchen da sie nur zum rechnen sind?
function getFloatValue(id) {
const element = document.getElementById(id);
if (element)
return parseFloat(element.value.replace(',', '.'));
else
return NaN;
}
function traufhöVordachNeigung() {
let grundmaß = getFloatValue('grundmaß'),
dachneigung = getFloatValue('dachneigung') / 180 * Math.PI,
dachüberstand = getFloatValue('dachüberstand')
traufhöhe = getFloatValue('traufhöhe')
raumhöheRohbau = getFloatValue('raumhöheRohbau'),
//firsthöhe = getFloatValue('firsthöhe'),
okFußpfette = getFloatValue('okFußpfette'),
okFirstpfette = getFloatValue('okFirstpfette');
let firsthöhe = (grundmaß + dachüberstand) * Math.tan(dachneigung) + traufhöhe,
let okKniestock = (dachüberstand* Math.tan(Dachneigung)),
let lotrechtesObholz = (sparrenhöhe - klauentiefe) / Math.cos(dachneigung);
document.getElementById('firsthöhe').value = firsthöhe.toPrecision(4),
document.getElementById('okKniestock').value = okKniestock.toPrecision(4),
document.getElementById('lotrechtesObholz').value = lotrechtesObholz.toPrecision(4);
LG matze
Hallo matze,
ich verstehe deine Fragen nicht.
Die Anweisungen in Javascript werden - innerhalb einer Funktion - nacheinander ausgeführt (unter Berücksichtigung von Abfragen und schleifen, natürlich).
Funktionen laufen in der Reihenfolge, wie sie aufgerufen werden.
Wie wird denn derzeit deine Traufhöhevordachneigung-Funktion aufgerufen?
Rolf
Hallo,
die Gegenfrage und der Hinweis von Rolf haben mir schon weiter geholfen und siehe da ich hab noch einen Rechenfehler in den Formeln entdeckt.
Ja und für meinen Namensvetter, das ist nicht die erste Webseite die schreibe, allerdings möchte ich dies nicht Serverseitig haben also brauchte ich JavaScript. Also warum sollte ich das auch noch lernen, wenn es nette Leute gibt die einem Helfen und nicht nur hinweise, lern dies und lern das. Das sind keine konstruktiven Antworten, wenn es wenigstens ein Link zu meiner Frage wäre aber das nenn ich mal nur Punktehascherei um hier im Forum aufzusteigen.😒
Und ja ich versuche immer im Vorfeld eine Lösung im WWW zu finden aber wenn ich ohne die richtigen Schlagwörter nicht weiter komme nutze ich halt so etwas hier!
Und das ganze soll nicht öffentlich werden sondern nur für mich als Arbeitserleichterung für meinen Job, ich hatte dies alles schonmal als App in Swift geschrieben aber ich bin nicht gewillt jedes Jahr hunderte von Euro in die Tasche der großen Konzerne zu spülen, nur damit man die App überhaupt auf dem Handy hat und immer neue Hardware um auf den neuesten Stand zu sein weil die alten Geräte nicht mehr unterstützt werden.
So ich wünsche allen ein schönes langes WE aber das mußt ich jetzt mal loswerden.
LG matze
Hallo Namensvetter!
@JürgenB hatte Dir schon vor 2 Wochen geschrieben:
du wirst nicht umhin kommen, HTML und Javascript zu lernen. Aber dafür haben wir einiges in unserem Wiki:
- Wie fange ich an, und da speziell der Einstieg in HTML und der Einstieg in Javascript.
- Für deine Rechnungen brauchst du das Math-Objekt .
- Ein Beispiel für Eingabe, Berechnung und Ausgabe von Zahlen: BMI-Rechner
Fang mal an und wenn du nicht weiter weißt, frag hier nach.
Diesem Rat kann ich mich nur anschließen! Frag, wenn etwas nicht funktioniert!
Schau Dir mal dein Beispiel im Seiteninspektor an.
→ Arbeiten mit dem Seiteninspektor
Schick uns einen Link zu deiner Testseite.
→ Warum online-Beispiele besser als das Posten von Code sind!
Herzliche Grüße
Matthias Scharwies