Redundanzen in den Ergebniswerten von sin() und cos()

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Flush

Betreff: Redundanzen in den Ergebniswerten von sin() und cos()

BeitragMo, März 26, 2018 14:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo zusammen Very Happy ,

Ich hab einen Teil eines kleinen AutoIt Tutorials in Blitz3D umgesetzt, wenn es fertig ist könnte man
es vllt. als Tutorial für Anfänger nutzen: Sin & Cos/ Bewegung und ihre Mathematik.
Es funktioniert eigentlich genau wie es soll, zwei kreisförmige Flächen drehen sich umeinander auf einer
Kreisbahn durch Phasenverschiebung.

Was mich stört ist die Tatsache, dass die Bewegung gelegentlich ruckelt, langsamer wird und dann wieder scheller.
Ich denke dass es an den Sinuswerten liegt. Bis zur Stelle 81 ist die Sache O.K. es werden nur Sprünge
von 1 bis 2 Pixel gemacht, doch dann beginnen Wiederholungen in den Sinus- bzw. Cosinuswerten.
Die Stelle 93, 95, 96 werden jeweils zweimal, die Stellen 97 und 98 dreimal, die Stelle 99 viermal
und die Stelle 100 sogar elfmal wiederholt. Auf dem absteigenden Ast sieht es natürlich genauso aus, Stelle 99 viermal etc..
D.h. dass die Bewegung an den Wiederholungen festsitzt und so die Ruckler entstehen. Hier liegt der Hund begraben!
Dass es sich um ein Rundungsproblem handelt ist klar aber wie kann mans lösen?

Habt Ihr eine Ahnung wie ich die die Redundanzen bei den Werten vermeiden oder
irgendwie glätten kann und somit die Animation smoother läuft?

Ich habe am Ende noch ein kleines Hilfsprogramm angehängt das Sinuswerte in eine Textdatei schreibt, so kann man besser testen!

Hier der Source des Hauptprogramms:
BlitzBasic: [AUSKLAPPEN]

Graphics 640, 480, 24, 2
AppTitle "Vollsynchrone Kreisbewegung mit sin() und cos() durch Periodenverschiebung!!!"

;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Global X_Frames ;Variablen für FPS Counter
Global X_Framezeit ;Variablen für FPS Counter
Global X_FramesProSekunde ;Variablen für FPS Counter
;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
;Erstellung der Types TypSine und TypCos mit jeweils den Integer Arrays arrBlau[360] und arrRot[360]

Type TypeSine
Field arrBlau%[360] ;361 Stellen
Field arrRot%[360] ;361 Stellen
End Type

Type TypeCos
Field arrBlau%[360] ;361 Stellen
Field arrRot%[360] ;361 Stellen
End Type
;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

Kreisbewegung_durch_Periodenverschiebung() ;Aufruf der Hauptfunktion

Function Kreisbewegung_durch_Periodenverschiebung()

Local TSinus.TypeSine = CalcSine(0, 120)
Local TCos.TypeCos = CalcCos(0, 120)
Color 0,0,255
gfxBallblau=CreateImage(100,100)
SetBuffer ImageBuffer(gfxBallblau)
Oval 0 , 0 ,100,100,1

Color 255,0,0
gfxBallrot=CreateImage(100,100)
SetBuffer ImageBuffer(gfxBallrot)
Oval 0 , 0 ,100,100,1

SetBuffer BackBuffer ()
For iAngle = 0 To 360; Step 3
DrawImage gfxBallblau, 280 + TSinus\arrBlau[iAngle], 200 + TCos\arrBlau[iAngle]
DrawImage gfxBallrot, 280 + TSinus\arrRot[iAngle] , 200 + TCos\arrRot[iAngle]
Text 0,0,"FPS:" + FPS()
Flip
Cls
If iAngle = 360 Then iAngle = 0
Next

End Function

Function CalcSine.TypeSine(blau, rot)

Local TSine.TypeSine = New TypeSine; Anlegen von neuem lokalen Type TSin vom Typ TypeSin
phasenverschiebungBlau = blau
phasenverschiebungRot = rot
k = 0

For j = 0 To 360
sinus = Sin(j + phasenverschiebungBlau)*100
TSine\arrBlau%[k] = sinus
k = k + 1
Next

k = 0
For j = 0 To 360
sinus = Sin(j + phasenverschiebungRot)*100
TSine\arrRot%[k] = sinus
k = k + 1
Next

Return TSine

End Function

Function CalcCos.TypeCos(blau, rot)

Local TCos.TypeCos = New TypeCos
phasenverschiebungBlau = blau
phasenverschiebungRot = rot
k = 0

For j = 0 To 360
cosinus = Cos(j + phasenverschiebungBlau)*100
TCos\arrBlau%[k] = cosinus
k = k + 1
Next

k = 0
For j = 0 To 360
cosinus = Cos(j + phasenverschiebungRot)*100
TCos\arrRot%[k] = cosinus
k = k + 1
Next

Return TCos

End Function

Function FPS()
Color 255, 255, 255
X_Frames = X_Frames + 1
If X_Framezeit + 1000 < MilliSecs() Then
X_FramesProSekunde = X_Frames
X_Frames = 0
X_Framezeit = MilliSecs()
EndIf
Return X_FramesProSekunde
End Function





Hier der Source des Hifsprogramms:
BlitzBasic: [AUSKLAPPEN]

Graphics 640,480,24,2
AppTitle "Brauchbare Sinusberechnung !!!!"
Local Datei$, DateiHandle%

Type TypeSine
Field arr%[360] ;361 Stellen
End Type
Local tSine.TypeSine = New TypeSine
tSine = CalcSine.TypeSine(0)

Datei = "SinusWerte.txt"
DateiHandle = WriteFile(Datei)

For i = 0 To 100

WriteLine DateiHandle, tSine\arr[i]

Next
CloseFile DateiHandle

Print "DATEI GESCHRIEBEN !!!!"
Print "ENDE !!!!"


WaitMouse


Function CalcSine.TypeSine(blau)

Local TSine.TypeSine = New TypeSine; Anlegen von neuem lokalen Type TSin vom Typ TypeSin
phasenverschiebung% = blau
phasenverschiebungRot = rot
k = 0

For j = 0 To 180
sinus = Sin(j + phasenverschiebung)*100
TSine\arr%[k] = sinus
k = k + 1
Next


Return TSine

End Function




Viele Grüße und danke für Eure Hilfe vorab,
Flush

Flush

BeitragMo, März 26, 2018 18:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi,

ist die Frage doof, zu viel Code oder hab ich falsch gepostet Embarassed ?

Die einzige Möglichkeit die mir einfällt das Sinus/ Cosinus Problem zu lösen ist die, die Werte von Hand anzupassen?!
Nicht gerade elegant aber wie gesagt die einzige Möglichkeit die mir auch nach langem googeln, herumrechnen und ausprobieren einfällt Crying or Very sad !

Was meint Ihr?


Viele Grüße,
Flusher

Lobby

BeitragMo, März 26, 2018 20:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Kannst du vielleicht mal die Ausgabe deines Testprogramms hochladen? Ist dort das Problem denn schon vorhanden?

Und generell, gibt es einen bestimmten Grund, Sinus und Cosinus vor zu berechnen? Der Laufzeitunterschied sollte den Mehraufwand bei der Programmierung nicht rechtfertigen können (Paradigma beim Optimieren: optimiere nur dort, wo es sich auch lohnt).
TheoTown - Eine Stadtaufbausimulation für Android, iOS, Windows, Mac OS und Linux

Flush

BeitragMo, März 26, 2018 20:30
Antworten mit Zitat
Benutzer-Profile anzeigen
@Lobby
Ich berechne vor weil LookUp Tables immer schneller als Berechnungen in Realtime sind. Aber Du hast mit der Optimiererei schin recht!
Ausgabe Sinus:
BlitzBasic: [AUSKLAPPEN]
                                   
0
2
3
5
7
9
10
12
14
16
17
19
21
22
24
26
28
29
31
33
34
36
37
39
41
42
44
45
47
48
50
52
53
54
56
57
59
60
62
63
64
66
67
68
69
71
72
73
74
75
77
78
79
80
81
82
83
84
85
86
87
87
88
89
90
91
91
92
93
93
94
95
95
96
96
97
97
97
98
98
98
99
99
99
99
100
100
100
100
100
100
100
100
100
100
100
99
99
99
99
98
98
98
97
97
97
96
96
95
95
94
93
93
92
91
91
90
89
88
87
87
86
85
84
83
82
81
80
79
78
77
75
74
73
72
71
69
68
67
66
64
63
62
60
59
57
56
54
53
52
50
48
47
45
44
42
41
39
37
36
34
33
31
29
28
26
24
22
21
19
17
16
14
12
10
9
7
5
3
2
0



Ausgabe Cosinus:
BlitzBasic: [AUSKLAPPEN]
 
100
100
100
100
100
100
99
99
99
99
98
98
98
97
97
97
96
96
95
95
94
93
93
92
91
91
90
89
88
87
87
86
85
84
83
82
81
80
79
78
77
75
74
73
72
71
69
68
67
66
64
63
62
60
59
57
56
54
53
52
50
48
47
45
44
42
41
39
37
36
34
33
31
29
28
26
24
22
21
19
17
16
14
12
10
9
7
5
3
2
0
-2
-3
-5
-7
-9
-10
-12
-14
-16
-17
-19
-21
-22
-24
-26
-28
-29
-31
-33
-34
-36
-37
-39
-41
-42
-44
-45
-47
-48
-50
-52
-53
-54
-56
-57
-59
-60
-62
-63
-64
-66
-67
-68
-69
-71
-72
-73
-74
-75
-77
-78
-79
-80
-81
-82
-83
-84
-85
-86
-87
-87
-88
-89
-90
-91
-91
-92
-93
-93
-94
-95
-95
-96
-96
-97
-97
-97
-98
-98
-98
-99
-99
-99
-99
-100
-100
-100
-100
-100
-100


Viele Grüße und vielen Dank für die Hilfe vorab,
Flush

Xeres

Moderator

BeitragMo, März 26, 2018 20:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Also, das Grundproblem liegt da:
BlitzBasic: [AUSKLAPPEN]
Field arrBlau%[360]

Du definierst deine Werte als Ganzzahlen. Das kann niemals Flüssig aussehen. Benutze Floats, dann gibt es wenigstens die Change, dass es besser aussehen kann.

Generelle Hinweise:
BlitzBasic: [AUSKLAPPEN]
;361 Stellen

Das ist die Definition eines schlechten Kommentars: da steht genau das, was man auch im Code ablesen kann. Wenn man Kommentare schreibt, dann um zu erklären, warum das so ist. Plus: Warum denn 361? Winkel gehen von 0 bis 359.

Das sieht komisch aus:
BlitzBasic: [AUSKLAPPEN]
For iAngle = 0 To 360;  Step 3
[...]
If iAngle = 360 Then iAngle = 0
Next


Warum gibt es zwei Schleifen in der CalcSine Funktion? Warum benutzt du dann die Variablen j und k? Du machst dir richtig Mühe um Werte vor zu berechnen und machst das dann halb so effizient wie möglich. Wink
Warum sind Sinus und Cosinus in zwei unterschiedliche Types aufgeteilt?
Wenn du zwei Programme hast - warum importieren die nicht die Types & Funktionen aus einer gemeinsamen Datei?
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Flush

BeitragMo, März 26, 2018 21:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi Xeres,

1.)
ich habe aus Integern % Floats # gemacht, das Problem besteht immer noch da jetzt 100.0 statt 100 im Array steht also das gleiche.

2.)
Stimmt der Kommentar ist verunglückt.

3.)
Warum siht das komisch aus? Ist einfach nur eine Endlosschleife einer Animation.
BlitzBasic: [AUSKLAPPEN]

For iAngle = 0 To 360
[...]
If iAngle = 360 Then iAngle = 0
Next


3.)
Ich hab herumexperimentiert deshalb die Designmängel, die werden noch behoben!
Die schleifen haben keinen Einfluss auf die Geschwindigkeit der Animation da Sie nur zur Vorberechnung der LUT's
dienen. Wird wie gesagt noch behoben!


Viele Grüße und vielen Dank für die Hilfe vorab,
Flush

Lobby

BeitragMo, März 26, 2018 23:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich weiß nicht was du für ein Programm schreibst, aber ich habe Zweifel, dass du durch das Vorberechnen von cos und sin einen relevanten Performancevorteil erreichen kannst.

1) Hier hat sinus nach wie vor den Typ int denke ich:
BlitzBasic: [AUSKLAPPEN]
sinus = Sin(j + phasenverschiebung)*100
TSine\arr%[k] = sinus

Also entweder direkt dem Array zuweisen oder sinus als float deklarieren.
TheoTown - Eine Stadtaufbausimulation für Android, iOS, Windows, Mac OS und Linux

Holzchopf

Meisterpacker

BeitragDi, März 27, 2018 9:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Ob schlussendlich look up tables schneller sind als die Cos/Sin-Funktionsaufrufe oder ob sie gar langsamer sind wegen Caching-Engpässen müsste man wohl messen. Es wird auch erst in's Gewicht fallen, wenn du abertausende Objekte hast, die auf trigonometrische Funktionen angewiesen sind, oder z.B. Fouriertransformationen von Signalen machst (wo ganz viele Ko- und Sinuswertchen einfliessen). So oder so muss man sich die Frage stellen ob 1° Winkelauflösung genug ist oder ob es evtl. sogar schon zu hoch aufgelöst ist... Aber bei gerademal 4 Aufrufen (2x Sin, 2x Cos) pro Hauptschleifendurchgang fällt das einfach noch nicht ins Gewicht.


Apropos Hauptschleife:

Du missbrauchst eine For-Schleife dafür. Lass das! Ich mein's ernst, sowas tut man nicht. Also die Zählervariable einer For-Schleife in der Schleife manipulieren. Das ist wirklich sehr sehr schlimm Sad Der arme Computer denkt, da käme eine kleine Schleife, die mal eben schwups abgearbeitet wird und dann setzt du kurz vor Schluss den Zähler wieder zurück. Wie gemein Crying or Very sad

Weniger schlimm - gar schön oder an Perfektion kaum mehr zu übertreffen - ist eine While-Schleife, bei der eine schöne Abbruchbedingung im Kopf steht. BlitzBasic: [AUSKLAPPEN]
	While Not KeyHit(1)		; 1 = ESCAPE
... Schleifenkörper ...
Wend



Aber zurück zu deiner eigentlichen Frage:
Flush hat Folgendes geschrieben:
Dass es sich um ein Rundungsproblem handelt ist klar aber wie kann mans lösen?

Gar nicht! Mad Zumindest in BB nicht. Denn spätestens, wenn das Bild gezeichnet wird, werden die Koordinaten auf ganze Pixel gerundet.


Ich habe dein Programm mal so angepasst, dass Sin/Cos direkt in ihrer majestätischen Fliesskomapräzision bei der Koordinaten-Berechnung der Bilder angewendet werden und man sieht bei tiefen Geschwindigkeiten immer noch schön das von dir beschriebene Phänomen: BlitzBasic: [AUSKLAPPEN]
Graphics 640, 480, 24, 2
AppTitle "Vollsynchrone Kreisbewegung mit sin() und cos() durch Periodenverschiebung!!!"

; Variablen für FPS Counter
Global X_Frames
Global X_Framezeit
Global X_FramesProSekunde

;Aufruf der Hauptfunktion (mit Hauptschleife)
Kreisbewegung_durch_Periodenverschiebung()

Function Kreisbewegung_durch_Periodenverschiebung()
; blauen Ball rendern
gfxBallblau=CreateImage(100,100)
SetBuffer ImageBuffer(gfxBallblau)
Color 0,0,255
Oval 0,0, 100,100, 1
; roten Ball rendern
gfxBallrot=CreateImage(100,100)
SetBuffer ImageBuffer(gfxBallrot)
Color 255,0,0
Oval 0,0, 100,100, 1

SetBuffer BackBuffer()

; Hauptschleife
Local angle#
While Not KeyHit(1) ; 1 = ESCAPE
angle = angle + 0.1

Cls
DrawImage gfxBallblau, 280 + Sin(angle) * 100, 200 + Cos(angle) * 100
DrawImage gfxBallrot, 280 + Sin(angle+120) * 100 , 200 + Cos(angle+120) * 100
Text 0,0,"FPS:" + FPS()
Flip
Wend
End Function

; FPS-Zähler
Function FPS()
Color 255, 255, 255
X_Frames = X_Frames + 1
If X_Framezeit + 1000 < MilliSecs() Then
X_FramesProSekunde = X_Frames
X_Frames = 0
X_Framezeit = MilliSecs()
EndIf
Return X_FramesProSekunde
End Function



Um Bilder Subpixel-genau positionieren zu können, müsstest B3D in Kombination mit einer 2D-Sprite-Engine (nennen die sich so?) oder BlitzMax nehmen. Dann werden auch die Animation smoother Smile


Liebe Grüsse
Holzchopf
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm

Flush

BeitragDi, März 27, 2018 15:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo zusammen,

@Holzchopf
Die Sache mit der Hauptschleife nehm ich mir zu Herzen Embarassed , ich lass meinen armen Computer nicht leiden, versprochen !
Zusammenfassen kann man also sagen, dass man das Phänomen mit Blitz3D nicht abschalten, wird Zeit für BlitzMax. Ich komm aus der OOP, sollte also nicht verkehrt sein Very Happy

@Lobby
Ob Float Oder Integer, das Phänomen lasst sich nicht abschalten.

Vielen Dank für Eure Hilfe und fröhliche Ostern!


Viele Grüße,
Flush

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group