[FRAGE] Winkel im voraus berechnen?

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

[FRAGE] Winkel im voraus berechnen?

Beitrag von Mijikai »

Eventuell eine dumme Frage :oops:
Ist es möglich alle Winkel im voraus zu berechnen?

Bei -> sin oder cos(Winkel.f)
Wobei Winkel ja irgendwas sein kann 11.2938.. !?

Wie machen das die Spiele?
Derren
Beiträge: 557
Registriert: 23.07.2011 02:08

Re: [FRAGE] Winkel im voraus berechnen?

Beitrag von Derren »

Naja, es gibt unendlich viele Winkel.
Du kannst aber einfach jeden ganzen Winkel berechnen, das sind dann immerhin 360. Oder jeden halben oder viertelten.
Dann guckst du einfach ob das ausreicht für deine Anwendung (wenn du z.B. ein Spiel programmierst, dann guck ob die Drehung bei 360 oder 720 Schritten flüssig aussieht).

Die Frage ist auch, wozu? Hast du 100e Objekte gleichzeitig auf dem Bildschirm, die alle mehrmals pro Sekunde eine Winkelberechnung benötigen?

Möglicherweise hast du Anfangs wenige und später mehrere Berechnungen, dann kannst du den Winkel berechnen und anschließend abspeichern. Wenn das nächste mal ein Winkel benötigt wird, greifst du auf dein Array zu, oder falls der Eintrag leer/nicht vorhanden ist, berechnest du ihn neu.
Signatur und so
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: [FRAGE] Winkel im voraus berechnen?

Beitrag von STARGÅTE »

Man kann so eine Tabelle anlegen (z.B. in einem Array), allerdings gibt es dann ein paar Nachteile, die den Vorteil des schnellen Zugriffs wieder zu nichte machen:
Du wirst nicht alle Winkel abdecken können, somit brauchst du sowas wie Round() oder komplizierter, um den beliebigen Winkel in einen Vorberechneten umzuwandeln.
Du musst Mod() verwenden, damit auch Winkel >360 oder <0 in die richtige Range gebracht werden, außer das machst du schon vorher, wenn sich z.B. dein Objekt dreht.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: [FRAGE] Winkel im voraus berechnen?

Beitrag von NicTheQuick »

Wenn man ein Array in der Größe einer Zweierpotenz nutzt, kann man sich das Mod sparen und einfach mit ein bisschen Bit-Arithmetik arbeiten.

Code: Alles auswählen

EnableExplicit

; Hier kann man die Präzision der Sinus-Tabelle einstellen
#SINE_PRECISION = 12

; Hier berechnen wir ein paar Werte vor, die wir benötigen
#_sineMax = 1 << #SINE_PRECISION
#_sineFac = #_sineMax / #PI / 2
#_sineMask = #_sineMax - 1
Global Dim _sineTable.f(#_sineMax - 1)

; Muss aufgerufen werden um die Sinus-Tabelle zu initialisieren
Procedure initSineTable()
	Protected i.i
	For i = 0 To #_sineMax - 1
		_sineTable(i) = Sin(i * 2 * #PI / #_sineMax)
	Next
EndProcedure

; Das ist nun unsere neue Sinus-Funktion, aber als Makro
Macro fastSin(a)
	_sineTable(Int(a * #_sineFac) & #_sineMask)
EndMacro

initSineTable()

; Hier berechnen wir die durchschnittliche Abweichung zwischen der
; Sinus-Tabelle und der originalen Sinus-Funktion
Define i.i, sumDiff.d
For i = -100 To 100
	sumDiff + Abs(Sin(i) - fastSin(i))
Next
Debug "Durchschnittliche Abweichung: " + StrD(sumDiff / 201.0, 20)
Man könnte sogar nur die Hälfte der kompletten Sinusperiode im Array speichern, aber dann würde das Makro wieder komplexer werden. Da müsste man mal ausprobieren, ob sich das lohnt. Solange die Sinus-Tabelle noch locker in den Cache passt, sollte sie aber noch schnell funktionieren. In meinem Beispiel nutze ich eine Präzision von 12, d.h. es werden 2^12 = 4096 Werte in der Tabelle gespeichert, mal 4 Bytes pro Float sind das dann 16 kB, die in heutige Caches locker passen sollten.
Bild
Antworten