PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C# Probleme mit Kollisionen



Multithread
18.06.2013, 10:06
Hallo Zusammen

Ich arbeite Grad an eine Game Engine die sowas wie die 2D Mario spiele ermöglichen soll. Die gesamte Steuerung ist im Readme Spoiler weiter unten erklärt.

Mein Problem sind die Kollisionsabfragen und die Kollisionen, bzw dann später noch das 'Physikalisch korrekte' abprallen.
Dabei geht es nicht um den Fakt das man ab einer gewissen geschwindigkeit durch wände gehen kann, dafür gibt es ja eine maximale Geschwndigkeit der Figuren.
Das Problem lässt sich realtiv gut am rechten Rand darstellen, dort geht die Spielfigur(das Violette ding:D) öfters mal durch die Wand, und teilweise zurück ins Feld.
An der linken Wand und am Boden lässt sich das Problem jedoch nicht nachstellen.


Die Klasse worin ich die Physik berechne, ist public class PhysikBerechnen : Aufgabe.
Alles was von Aufgabe abgeleitet wird, wird in einem seperaten Thread ausgeführt, der Thread ruft dann abarbeiten() auf, das ist noch wichtig zu wissen. In diesem fall Ohne rückgabe, also was wie ein Timer mit einem eigenen Thread, da muss aber vermutlich noch was besseres hin. Aktuelle hat es aber einige Vorteile was das erkennen von Performance Lücken betrifft.

Um Ideen und Vorschläge wie ich das besser/Performanter hinbekomme bin ich auch dankbar, das wichtigste ist mir aber momentan ein Vorschlag wie ich die Kollisionen richtig hinbekomme, das problem besteht nun schon von Anfang an und ich habs immer noch nicht in den Griff bekommen.


Der Gesamte Code der Engien Klasse mitsamt DLL's und aktuellem Stand der dateien, solle einfach per VS zu öffnen sein und direkt laufen:)
2D_Game_Engine_Demo.zip (http://upload.worldofplayers.de/files9/2D_Game_Engine_Demo.zip)

Ich möchte noch um verzeihung bitten wegen der absoluten Hässlichkeit das ich auf point1 des IZeichenelement direkt zugreife§wink


Readme:
Spielfeld linien leeren mit eingabe von 'clean' ganz im style von marvin in Gothic 2
Mit gedrückthalten der Rechten Maustaste kann man auf dem Spielfeld umherfahren.

Tastenbelegung:
Linke Maustaste: Block setzten
Rechte Maustaste gedrückt: Block löschen
Mittlere Maustaste: Blöcke abspeichern
Mausrad scrollen: zoom verändern
zahlen 1-6: Block wählen


Spielen:
Mit den Pfeiltasten kann man die Richtung wählen
Mit der Entertaste hält die Spielfigur in der Luft an.
Mit der Leertaste kann man, sofern man nahe genug ist, einen NPC ansprechen
Mit den Tasten 1-9 kann man die Quest/Antwort wählen aus den Antwortmöglichkeiten
Mit Esc blendet man das MenuOverlay aus.

PC Anforderungen:
Dual Core mit mindestens 2GHz
300MB Ram für das Spiel
Tastatur + Maus

Das Pinke etwas entfernen kann man indem man die PinkiePie.char Datei im Charakter Ordner löscht.
ausserdem besteht die Möglichkeit die Graviationsrichtung und einige andere Dinge in der Physik klasse zu ändern.$§p4


Gruss Lara Croft

Sergej Petrow
18.06.2013, 18:11
Das Programm kann ich nicht starten. Gibt eine Fehlermeldung. Vermute aber mal, dass es nur auf einem 64bit-System läuft?!? Habe nur ein 32-bit-System.

Multithread
18.06.2013, 18:13
Das Programm kann ich nicht starten. Gibt eine Fehlermeldung. Vermute aber mal, dass es nur auf einem 64bit-System läuft?!? Habe nur ein 32-bit-System.
nein, sollte eigentlich auch auf 32 Bit Systemen laufen.

Kann es sein das die CoRG.dll den Fehler wirft? Diese ist im Any CPU Modus erstellt worden. Wenn ja, würde ich da noch ein neues Kompilat nachlegen.

Delta 38
19.06.2013, 10:00
Versuch es mal mit Raytracing (http://de.wikipedia.org/wiki/Raytracing#Schnittpunkttests)für die Kollisionabfrage.

Gruß Delta

Multithread
19.06.2013, 15:30
Versuch es mal mit Raytracing (http://de.wikipedia.org/wiki/Raytracing#Schnittpunkttests)für die Kollisionabfrage.

Gruß Delta
Ich sehe leider nicht wie mir das zum Erfolg verhelfen soll, ich habe immer 2 Polygone welche auch Kollision überprüft werden müssen, Raytracing aber beschränkt sich auf einen Punkt und das Objekt das dargestellt werden soll.

Wenn ich nur die Polygone beachte für die Kollisionsabfrage, dann ist das ganze so langsam das selbst mein i5 ins schwitzen kommt, deshalb beachte ich nur noch Gegenstände deren Mittelpunkte sich so nahe kommen, das eine Kollision Wahrscheinlich ist.

§wink

Delta 38
19.06.2013, 18:59
Kannst du einmal kurz aufschreiben, wie genau dein Programmablauf ist? Ich steig da ehrlich gesagt nicht so ganz durch.
Arbeitet die ThreadQueue die Threads nacheinander ab, wie es der Name vermuten lässt? Das wäre doch irgendwie genau dem Zweck mehrerer Threads entgegengesetzt, oder? §kratz


Ich sehe leider nicht wie mir das zum Erfolg verhelfen soll, ich habe immer 2 Polygone welche auch Kollision überprüft werden müssen, Raytracing aber beschränkt sich auf einen Punkt und das Objekt das dargestellt werden soll.
(Ich glaube ich meinte eigentlich Raycasting ... )
Das ist grundsätzlich richtig, aber du hast, soweit ich das sehe, einen Bewegungsvektor für deine bewegten Objekte. Nun prüfst du einfach ob dieser Strahl (eben dein Bewegungsvektor/Richtungsvektor in eine Geradengleichung eingebaut (Stützvektor + t * Richtungsvektor)) ein Objekt schneidet, errechnest wie weit es entfernt ist (s = v*t) und wenn es kleiner als deine maximaler Abstand zwischen zwei Objekten ist, dann hast du eine Kollision.
(Ich hoffe das ist alles richtig so, ist schon ein bisschen her, dass ich mich mit Vektoren ausseinander gesetzt habe :D)
Gruß Delta

Multithread
19.06.2013, 19:42
Kannst du einmal kurz aufschreiben, wie genau dein Programmablauf ist? Ich steig da ehrlich gesagt nicht so ganz durch.
Arbeitet die ThreadQueue die Threads nacheinander ab, wie es der Name vermuten lässt? Das wäre doch irgendwie genau dem Zweck mehrerer Threads entgegengesetzt, oder? §kratz

Die Thread Queue arbeitet die Threads in einem Threadpool ab den ich selber erstellt habe, und entsprechend kontrollieren kann.
In der Aktuellen Version werden 7 Threads initialisiert, ein paar davon werde ich als eine Art Timer verwenden, die anderen können per Queue.Add({Aufgabe}); verwendet werden.




(Ich glaube ich meinte eigentlich Raycasting ... )
Das ist grundsätzlich richtig, aber du hast, soweit ich das sehe, einen Bewegungsvektor für deine bewegten Objekte. Nun prüfst du einfach ob dieser Strahl (eben dein Bewegungsvektor/Richtungsvektor in eine Geradengleichung eingebaut (Stützvektor + t * Richtungsvektor)) ein Objekt schneidet, errechnest wie weit es entfernt ist (s = v*t) und wenn es kleiner als deine maximaler Abstand zwischen zwei Objekten ist, dann hast du eine Kollision.
(Ich hoffe das ist alles richtig so, ist schon ein bisschen her, dass ich mich mit Vektoren ausseinander gesetzt habe :D)
Gruß Delta
Dann habe ich Pro bewegliches Objekt also ca. 3-300 punkte (der umriss) von denen aus ich ein Tracing machen muss.
Wie kann ich bestimmen ob ein solcher Trace sich mit einer Strecke schneidet, bzw. wie gross der Abstand in Richtung Bewegungsvektor geht? Das verstehe ich auch noch nicht.

Delta 38
19.06.2013, 22:20
Mir ist gerade eingefallen, dass es im 2d-Bereich ja eigentlich viel einfacher ist. Jeder Steinblock hat ja eine gewisse Höhe und Breite, also ein x- und ein y-Intervall, in dem das Rechteck definiert ist. Da dein Spieler ein Quadrat ist, kannst du dort vom Mittelpunkt ausgehen. Wenn du dein Spieler bewegst und sein x- oder y-Intervall sich mit dem des anderen Objektes überschneidet, dann hast du eine Kollision. Ich würde dir ja gerne auch•Beispielcode geben aber ich steig durch dein Programm nicht so richtig durch. Besonders mit den ganzen Listen wie wall, waende und walls (ist das nicht irgendwie alles das selbe?)
Gruß Delta

Multithread
20.06.2013, 05:47
Mir ist gerade eingefallen, dass es im 2d-Bereich ja eigentlich viel einfacher ist. Jeder Steinblock hat ja eine gewisse Höhe und Breite, also ein x- und ein y-Intervall, in dem das Rechteck definiert ist. Da dein Spieler ein Quadrat ist, kannst du dort vom Mittelpunkt ausgehen. Wenn du dein Spieler bewegst und sein x- oder y-Intervall sich mit dem des anderen Objektes überschneidet, dann hast du eine Kollision. Ich würde dir ja gerne auch•Beispielcode geben aber ich steig durch dein Programm nicht so richtig durch. Besonders mit den ganzen Listen wie wall, waende und walls (ist das nicht irgendwie alles das selbe?)
Gruß Delta
Eben leider ist es nicht so einfach mit den Kollisionen, aktuell sind es Vierecke, aber es sollten später mal Polygone werden, gleiches gilt für die schwarzen linien die du im Hintergrund siehst, mit 2-3 Zeilen Code kannst du auch diese in die Kollisionsabfrage einbinden, auch dann muss die Kollision noch überall funktionieren.

wenn wir uns mal die ini vornehmen aus Charakter, dann sieht man, das man das problemlos verändern kann:

[info]
typ=Charakter
pos=200,200
bewegungsrichtung=3,1
animation=Twilight
speedcorrection=false

[form]
0,0=0,64
0,64=64,64
64,64=64,0
64,0=0,0

[animationen]
X<1.0&X>-1.0=idle
X<0=walking<
X>0=walking>
Ich möchte das ganze so weit bringen das nichts mehr im code ist, was nicht explizite Abarbeitung ist, und entsprechend sollte auch der Code arbeiten, vielleicht hilft dieser Grundgedanke auch etwas weiter§wink.

Die listen haben zwar idetiscche wände drin, aber nicht in der gleichen menge.
wande ist der Rückgabewert, sämtliche linien der umgebung und von anderen gegenständen mit denen sich der char schneidet.
walls ist der rückgabewert aus kollidiert, also die schnittpunkte für den aktuellen Gegenstand/Objekt
wall schliesslich dient dazu festzustellen ob etwas in walls ist, das ist mehr ein workaround das noch weg sollte.

überhaupt hat kollidiert aktuell noch 2-3 Worakrounds drin die irgendwann weg müssen, aber erstmal muss es funktionieren, sonst ist es eher witzlos da was zu machen.
Ich hab mal etwas umbenannt:
wand zu _gegenstand
wande zu output
walls zu wande
eventuell ist es damit etwas ersichtlicher.

PS: Für Blockkollisionen habe ich es schon mal gemacht (http://upload.worldofplayers.de/files9/2DGameEngine.zip)

Thidrek
21.06.2013, 08:48
Vielleicht hilft dir dieses Tutorial hier (http://gamedev.tutsplus.com/tutorials/implementation/create-custom-2d-physics-engine-aabb-circle-impulse-resolution/) weiter.

Multithread
21.06.2013, 10:54
Vielleicht hilft dir dieses Tutorial hier (http://gamedev.tutsplus.com/tutorials/implementation/create-custom-2d-physics-engine-aabb-circle-impulse-resolution/) weiter.
Ist ebenfalls nur mit Boxen, funktioniert also mit einem Fünfeck als Kollisionsumriss nicht, dort sollte es aber auch gehen.

So schwer kann es doch nicht sein den Fehler ausfindig zu machen? Insbesondere da er absolut reproduzierbar ist....

Delta 38
21.06.2013, 13:45
Wahrscheinlich nicht, aber ohne Kommentare ist dein Code echt schwer zu verstehen :D Du willst also eine Kollisionsabfrage zwischen n-gons haben?

Multithread
21.06.2013, 16:24
Wahrscheinlich nicht, aber ohne Kommentare ist dein Code echt schwer zu verstehen :D Du willst also eine Kollisionsabfrage zwischen n-gons haben?
jap, genau so, Kollision zwischen N-gons, das klappt auch, zumindest meistens§gnah

Und sorry wegen den wenigen Kommentaren, ich habe die Dumme Angewohnheit Kommentare dann zu machen wenn ich eine Funktion das 2te mal sehe§gnah
Würde es euch sehr helfen wenn ich alle Wichtigen Funktionen/Variablen Kommentieren würde?

Delta 38
21.06.2013, 20:21
Nunja, ein allgemeiner Ablaufplan mit Benennung der aufgerufenen Funktion/Klassen und die wichtigsten Variablen würde wohl auch reichen.
Das Problem ist, dass du auch viele Variablen drin hast, die von der Superklasse geerbt werden und die dann auch benutzt. Der Sinn der Variable erschließt sich mir leider oft nicht durch den Namen.

Gruß Delta

Multithread
23.06.2013, 14:43
Hab ich mal gemacht:
2D_Game_Engine_Demo.zip (http://upload.worldofplayers.de/files9/dtQTkaxkGbbMvPLy2D_Game_Engine_Demo.zip)
Sollte noch mehr der Kommentierung bedürfen, schreibts einfach§wink


Ich glaube zudem das ich den Fehler gefunden habe:

Und zwar in der Physik Klasse unter abprallen
wo steht:

else if (x > position.X)
Folgte


umrechnung.Y = -1;
if (alteRichtung.Y < 0.0M)
{
alteRichtung.Y += g.Widerstand;
}
else if (alteRichtung.Y > 0.0M)
{
alteRichtung.Y -= g.Widerstand;
}

Macht wenig Sinn, nicht§gnah

Natürlich muss da überall X stehen.

Um Das herauszufinden habe ich jetzt fast 20 Stunden gebraucht, und am ende hab ichs durch nen dummen Zufall gefunden:C:

Jetzt sollten die Kollisionen Funktionieren.

Sergej Petrow
25.06.2013, 18:02
^^
Das kenne ich. Solche Sachen lassen sich eigentlich nur finden, wenn man Schritt für Schritt mit Testwerten rangeht. :D
Aber eine Hilfe dabei ist, definitiv mehr Kommentierung zu nutzen. Auch wenn es schwerfällt.

Multithread
25.06.2013, 21:05
^^
Das kenne ich. Solche Sachen lassen sich eigentlich nur finden, wenn man Schritt für Schritt mit Testwerten rangeht. :D
Aber eine Hilfe dabei ist, definitiv mehr Kommentierung zu nutzen. Auch wenn es schwerfällt.
hmmm.

Leider ist das ganze noch nicht durch.
Es gibt da immer noch ein Punkt den ich nicht hinbekomme, schlicht weil mir Mathematischen Kenntnisse in Trigonometrie komplett fehlen.

Und zwar geht es ums abprallen:

/// <summary>
/// Abprallen lassen des Characters
/// </summary>
/// <param name="g">Gegenstand welcher Kollidiert</param>
/// <param name="_wande">Kollidierende wände der Umgebung</param>
/// <param name="position">Position des Gegenstandes, kann man später wegnehmen</param>
/// <param name="_richtung">Richtung der Gravitation</param>
/// <returns>gibt den neuen Bewegunsvektor für den Gegenstand zurück</returns>
public Vektor abprallen(Gegenstand g, List<Wand> _wande, Point position, GravitationRichtung _richtung)
{
Vektor alteRichtung = g.Bewegungsrichtung;
Vektor umrechnung = new Vektor(1.0M, 1.0M);//zur umrechnung bei Kollisionen an schrägen flächen, aktuell nur für Richtungswechsel zuständig
int x = 0;
int y = 0;
List<Point> pointlist = new List<Point>();

//Richtung der Kollision bestimmen
foreach (Wand w in _wande)
{
x = position.X - (w.Point1.X + w.point2.X) / 2;
y = position.Y - (w.Point1.Y + w.point2.Y) / 2;
//Aber in 2D kannst du es auch besonders leicht analytisch...so, wie Shadowblade sagt.
//Du willst die Funktion f(x) = (x-position.X)² + (y(x)-position.Y)² minimieren,
//wobei y(x) durch die Geradengleichung gegeben ist. Dabei ist a = (a1,a2),
//also die Koordinaten des Punktes, zu dem der Abstand minimal werden soll.
//Normale Extremwertbestimmung. Das machst du für alle Geraden und berechnest die 4 Abstände,
//die du dann erhälst. Du schmeißt das dann alle Abstände heraus, die gar nicht auf dem Viereck liegen
//(möglich, weil die Extremstellen irgendwo auf der Gerade liegen, die gar nicht mehr zum Viereck gehören).
//indestens einer MUSS aber übrig bleiben. Wenn es mehrerer sind, nimmst eben den kleineren Wert

if (w.Point1.X == w.point2.X)
{
if (between(position.Y, w.Point1.Y, w.point2.Y))
{
pointlist.Add(new Point(w.point2.X, position.Y));
}
}
else if (w.Point1.Y == w.point2.Y)
{
if (between(position.X, w.Point1.X, w.point2.X))
{
pointlist.Add(new Point(position.X, w.point2.Y));
}
}
else if (Math.Abs(w.Point1.X - position.X) < Math.Abs(w.Point1.Y - position.Y))
{
pointlist.Add(new Point((w.Point1.X + w.point2.X) / 2, (w.Point1.Y + w.point2.Y) / 2));
}
else if (Math.Abs(w.Point1.X - position.X) > Math.Abs(w.Point1.Y - position.Y))
{
pointlist.Add(new Point((w.Point1.X + w.point2.X) / 2, (w.Point1.Y + w.point2.Y) / 2));
}
}

decimal tempwiderstand = g.Widerstand;
//Wenn ich shcon an einer Wand bin, muss ich in Die anderen Richtungen keinen Widerstand mehr leisten
if (g.KolisionX)
{
g.Widerstand = 0.0M;
}
//Effektives ändern der Bewegungsrichtung
if (pointlist.Count > 0)
{
x = pointlist[0].X;
y = pointlist[0].Y;

if (x < position.X)
{
umrechnung.X = -1;
if (alteRichtung.X < 0.0M)
{
alteRichtung.X += g.Widerstand;
}
else if (alteRichtung.X > 0.0M)
{
alteRichtung.X -= g.Widerstand;
}
if (Math.Abs(alteRichtung.X) <= g.Widerstand)
{
alteRichtung.X = 0;
}
}
else if (x > position.X)
{
umrechnung.X = -1;
if (alteRichtung.X < 0.0M)
{
alteRichtung.X += g.Widerstand;
}
else if (alteRichtung.X > 0.0M)
{
alteRichtung.X -= g.Widerstand;
}
if (Math.Abs(alteRichtung.X) <= g.Widerstand)
{
alteRichtung.X = 0;
}
}
else if (y < position.Y)
{
umrechnung.Y = -1;
if (alteRichtung.Y < 0.0M)
{
alteRichtung.Y += g.Widerstand;
}
else if (alteRichtung.Y > 0.0M)
{
alteRichtung.Y -= g.Widerstand;
}
if (Math.Abs(alteRichtung.Y) <= g.Widerstand)
{
alteRichtung.Y = 0;
}
}
else if (y > position.Y)
{
umrechnung.Y = -1;
if (alteRichtung.Y < 0.0M)
{
alteRichtung.Y += g.Widerstand;
}
else if (alteRichtung.Y > 0.0M)
{
alteRichtung.Y -= g.Widerstand;
}
if (Math.Abs(alteRichtung.Y) <= g.Widerstand)
{
alteRichtung.Y = 0;
}
}
}

//ändern aufgrund des umrechnungswertes
alteRichtung.X *= umrechnung.X;
alteRichtung.Y *= umrechnung.Y;

//dämpfung vorläufig deaktiviert
//alteRichtung.X *= g.Daempfung;
//alteRichtung.Y *= g.Daempfung;

g.Widerstand = tempwiderstand;
return alteRichtung;
}
Das ganze ist mehr schlecht als recht und funktioniert bei schrägen nicht korrekt, wen wunderts?

Meine Idee wäre nun:
1. Für jede Kollidierende wand den Schnittpunkt mit dem Gegenstand Herausfinden.
2. Mittelwert aus allen schnittpunkten ziehen
3. Vektor von Mittelpunkt Gegenstand zu wert aus 2.
4. Vektor umkehren so das eine Senkrechte durch den alten Vektor gezogen wird.
5. aufgrund dieser Senkrechten den alten Bewegungsvektor umrechnen

Punkte 1, 3 und 5 Kriege ich selber nicht hin.

Die schnittpunkteberechnung selber, habe ich, jedoch weiss ich nicht wo ich da den Punkt wo sich die beiden schneiden herausbekomme. Funktion ist Wand.Kolidieren(Wand wand)
kann es sein das sx und sy der Schnittpunkt ist?

Um hilfestellung wäre ich dankbar§wink


Hier noch den aktuellen Code, mit einigen Kommentaren:
2D_Game_Engine_Demo.zip (http://upload.worldofplayers.de/files9/CvhTP2D_Game_Engine_Demo.zip)

Lehona
26.06.2013, 10:31
Sind deine Gegenstände kreisförmig?

Du brauchst keine Schnittpunkte bestimmen, da deine Wände ja gerade sind (nehme ich an). Mit Einfallswinkel == Ausfallswinkel kannst du doch recht simpel den neuen Vektor berechnen? Einfach den Winkel zwischen Richtungsvektor und Wand berechnen (dazu die Wand am besten vektorialisieren, da sie ja vermutlich nicht alle achsenparallel sind).

Multithread
26.06.2013, 19:22
Sind deine Gegenstände kreisförmig?

nein, sind Sie nicht, meist sind es n-Polygone.
Da ich aber aktuell nicht plane Drehung beim Abprallen zu haben, reicht mit ein kreisförmiger Bezug für das abprallen.



Du brauchst keine Schnittpunkte bestimmen, da deine Wände ja gerade sind (nehme ich an). Mit Einfallswinkel == Ausfallswinkel kannst du doch recht simpel den neuen Vektor berechnen? Einfach den Winkel zwischen Richtungsvektor und Wand berechnen (dazu die Wand am besten vektorialisieren, da sie ja vermutlich nicht alle achsenparallel sind).
Also:
Die Grundidee was du vorhast habe ich wohl verstanden.

Aber:
1. Schnittpunkte brauche ich so oder so wegen der Kollision
2. Ich hab immer mindestens 2 Punkte an denen ich mit Wänden Kollidiere
3. die wand zu Vektorisieren, das kriege ich vielleicht gerade so noch hin, nen Vinkel zwischen zwei Vektoren liegt aber ausserhalb von dem was ich bisher gelernt habe.

Selbst das mit den Vektoren haben wir in der Schule nie gemacht:(


Kannst du mir sagen ob dieses sx/sy wirklich der Schnittpunkt ist? wenn ja, könnte ich diesen wert als Punkt zurückgeben.

Lehona
26.06.2013, 21:19
a∙b=|a|*|b| * cos α

Wobei α der Winkel zwischen den beiden Vektoren ist und sich das Skalarprodukt a∙b = a1*b1+a2*b2+...an*bn berechnet.

Multithread
27.06.2013, 20:20
So, ich habe mal die Kollision umgeschrieben, jetzt habe ich den Mittelpunkt aller Wandkollisionen ( p ).


public Vektor abprallen(Gegenstand g, List<Point> _wande, GravitationRichtung _richtung)
{
Point position = new Point(g.X, g.Y);
Vektor alteRichtung = g.Bewegungsrichtung;
Vektor umrechnung = new Vektor(1.0M, 1.0M);//zur umrechnung bei Kollisionen an schrägen flächen, aktuell nur für Richtungswechsel zuständig
int x = 0;
int y = 0;
Point kollisionPunkt = Point.Empty;

if (_wande.Count > 0)
{
long lx = 0;
long ly = 0;
foreach (Point p in _wande)
{
lx += p.X;
ly += p.Y;
}
kollisionPunkt = (new Point((int)(lx / _wande.Count), (int)(ly / _wande.Count)));
}
//Bis hier ist neu, vieles weggefallen


decimal tempwiderstand = g.Widerstand;
//Wenn ich shcon an einer Wand bin, muss ich in Die anderen Richtungen keinen Widerstand mehr leisten
if (g.KolisionX)
{
g.Widerstand = 0.0M;
}
//Effektives ändern der Bewegungsrichtung
if (kollisionPunkt != Point.Empty)
{
x = kollisionPunkt.X;
y = kollisionPunkt.Y;

if (x < position.X)
{
umrechnung.X = -1;
if (alteRichtung.X < 0.0M)
{
alteRichtung.X += g.Widerstand;
}
else if (alteRichtung.X > 0.0M)
{
alteRichtung.X -= g.Widerstand;
}
if (Math.Abs(alteRichtung.X) <= g.Widerstand)
{
alteRichtung.X = 0;
alteRichtung.Y = -alteRichtung.Y;
}
}
else if (x > position.X)
{
umrechnung.X = -1;
if (alteRichtung.X < 0.0M)
{
alteRichtung.X += g.Widerstand;
}
else if (alteRichtung.X > 0.0M)
{
alteRichtung.X -= g.Widerstand;
}
if (Math.Abs(alteRichtung.X) <= g.Widerstand)
{
alteRichtung.X = 0;
}
}
else if (y < position.Y)
{
umrechnung.Y = -1;
if (alteRichtung.Y < 0.0M)
{
alteRichtung.Y += g.Widerstand;
}
else if (alteRichtung.Y > 0.0M)
{
alteRichtung.Y -= g.Widerstand;
}
if (Math.Abs(alteRichtung.Y) <= g.Widerstand)
{
alteRichtung.Y = 0;
}
}
else if (y > position.Y)
{
umrechnung.Y = -1;
if (alteRichtung.Y < 0.0M)
{
alteRichtung.Y += g.Widerstand;
}
else if (alteRichtung.Y > 0.0M)
{
alteRichtung.Y -= g.Widerstand;
}
if (Math.Abs(alteRichtung.Y) <= g.Widerstand)
{
alteRichtung.Y = 0;
}
}
}

//ändern aufgrund des umrechnungswertes
alteRichtung.X *= umrechnung.X;
alteRichtung.Y *= umrechnung.Y;

//dämpfung vorläufig deaktiviert
//alteRichtung.X *= g.Daempfung;
//alteRichtung.Y *= g.Daempfung;

g.Widerstand = tempwiderstand;
return alteRichtung;
}

Nun habe ich einige Fragen zu deinen Rechnungen:
1. Vektor Adition verstehe ich grade so, aber Multiplikation, wie geht das?
2. Skalarprodukt habe ich da, ich weiss zwar nicht wie es geht, aber verwenden kann ich es: wie mache ich mithilfe des Skalarproduktes einen Abprallwinkel?
3. Wie mache ich aus zwei Vektoren einen Winkel, und wie aus einem Winkel und nem Vektor nen 2ten Vektor?
4. Ich habe keine Mathe studiert, entsprechend sind mir die Zeichen Teilweise fremd, bitte erkläre doch solche dinge wie |. was der Cosinus ist, begreife ich gerade so.

Daepilin
27.06.2013, 20:34
1) in dem fall über das skalarprodukt, also elementweise. du hast zwei vektoren (a1, a2, a3) und (b1, b2, b3), das skalarprodukt ist also: x = a1*b1 + a2*b2 + a3*b3
2)skalarprodukt ist auch |a| * |b| * cos (ß) ß = winkel zwischen a und b
3) halt den winkel dazwischen, indem du 1) = 2) setzt und nach dem winkel umstellst
4) das zweite is nich ganz einfach, da es unendlich solcher vektoren gibt die in einem winkel ß auf einem anderen vektor stehen können. du musst 2 von 3 werten festlegen und kannst dann über das skalarprodukt (aus 1) den dritten bestimmen.

und die zeichen sidn doch normale multiplikations(*) und betragszeichen(|)?
Fettgedruckt heißt hier vektor.
wenn du allein nich zurecht kommst sag bescheid, dabei sollte ich dir dann auch ( ohne mathestudium, das is alles schulstoff :P auch wenn ichs in der uni auch nochmal hatte) helfen können.

Multithread
28.06.2013, 08:34
1) in dem fall über das skalarprodukt, also elementweise. du hast zwei vektoren (a1, a2, a3) und (b1, b2, b3), das skalarprodukt ist also: x = a1*b1 + a2*b2 + a3*b3
2)skalarprodukt ist auch |a| * |b| * cos (ß) ß = winkel zwischen a und b
3) halt den winkel dazwischen, indem du 1) = 2) setzt und nach dem winkel umstellst
4) das zweite is nich ganz einfach, da es unendlich solcher vektoren gibt die in einem winkel ß auf einem anderen vektor stehen können. du musst 2 von 3 werten festlegen und kannst dann über das skalarprodukt (aus 1) den dritten bestimmen.

und die zeichen sidn doch normale multiplikations(*) und betragszeichen(|)?
Fettgedruckt heißt hier vektor.
wenn du allein nich zurecht kommst sag bescheid, dabei sollte ich dir dann auch ( ohne mathestudium, das is alles schulstoff :P auch wenn ichs in der uni auch nochmal hatte) helfen können.
§kratz
Was beudeutet das Zeichen für Gestorbene? also dieses +?
:D
Zumindest *,+,-,/, sqrt, log, Potenz und Summe sind mir geläufige Zeichen die ich auch anwenden kann^2^

Ich habe jetzt mal den Vektor der Abprallwand, sofern ich den richtig berechnet habe:


abprallwand = new Vektor(kollisionPunkt.Y - position.Y, kollisionPunkt.X - position.X);
Skalarwert aus den beiden Vektoren:


decimal skalar = abprallwand.X * alteRichtung.X + alteRichtung.Y * abprallwand.Y;

So, wie bekomme ich jetzt da den Winkel raus§kratz
Oder anders herum, welches ist jetzt der schnellste weg zum Abprallwinkel, ich brauche ja nur einen Weg.

Multithread
28.06.2013, 12:26
Scannen0021.jpg (http://upload.worldofplayers.de/files9/Scannen0021.jpg)

Genau so hatte ich mir das vorgestellt:)




Ist die Wand jetzt, wie in meinem Beispiel einfacherheitshalber gewählt, nicht die X-Achse, sind die Vektoren bzw. die Punkte halt nicht so einfach, aber die Punkte, die gebraucht werden, ändern sich entsprechend. Wenn du den Kollisionspunkt berechnet hast, musst du ausgehend von diesem nur 'zurückrechnen'. Zeichne es dir dann am besten mal mit Variablen auf und schreibe es allgemein auf - so kannst du es dann hoffentlich einfach ausrechnen. Kann denn deine Programmierungssoftwar die arc-Funktionen?

Winkel Alpha muss ich dann also umkehren um den Abprallvektor zu erhalten.
Arc: keine Ahnung ob und wie ich das in C# verwenden kann.

Mein Problem ist weiterhin: ich habe keine Ahnung wie ich den Arc- whatever aus Vektoren berechnen kann:dnuhr:
Bzw in diesem Fall: wie ich den Winkel Alpha berechnen kann aus M und C.




Edit: wobei das mit dem Geschwindigkeitsvektor bzw. dessen Betrag noch nicht stimmt. Den musst du, wenn du den Abstand r zur Wand erreicht hast, verlängern, bis er auch tatsächlich auf die Wand trifft (oder verkürzen, je nachdem).
Am einfachtsten sollte das gehen, in dem du den Mittelpunkt der Kugel zum Zeitpunkt der Kollision vom Punkt der Wand an dem der Mittelpunkt auftreffen würde abziehst. Das ist der Geschwindigkeitsvektor, wie du ihn für diesen Betrag brauchst. Da sind die Vorzeichen auch scheiß egal, da du quadrierst - zieh also einen vom anderen Punkt ab.

Das kann ich dann ja immer noch machen, momentan ist es aber nicht so wichtig, wegen den 2-3 Pixeln daneben:dnuhr:

Daepilin
28.06.2013, 12:33
Meinst du jetzt ( aus der skizze) alpha oder beta?

http://msdn.microsoft.com/de-de/library/system.math.acos.aspx

e: aso: alpha aus m und c: nja, dein m hat ja nen bewegungsvektor auf die wand zu (in der skizze v). Um deinen punkt m ist ein kreis mit radius r.

alpha ist halt der winkel zwischen deinem bewegungsvektor und dem radius, angenommen, das der senkrecht auf der wand steht (kannst du ja annehmen, der ist ja im kreis überall gleich).
Den berechnest du dann wie von suxx angegeben mit dem cosinus? (und beta eben mit dem sinus).

sorry, wenn das nich viel bringt, ich seh dein problem grad nicht wirklich?

Multithread
28.06.2013, 13:02
Meinst du jetzt ( aus der skizze) alpha oder beta?

http://msdn.microsoft.com/de-de/library/system.math.acos.aspx

e: aso: alpha aus m und c: nja, dein m hat ja nen bewegungsvektor auf die wand zu (in der skizze v). Um deinen punkt m ist ein kreis mit radius r.

Ich brauche Beta wenn ich das richtig sehe.

Ich habe nur keine Ahnung wie man einen Cosinus /Sinus oder deren Arc anwendet das dabei ein korrektes oder sinnvolles Resultat ankommt, da ich sowas noch nie gemacht habe;)





alpha ist halt der winkel zwischen deinem bewegungsvektor und dem radius, angenommen, das der senkrecht auf der wand steht (kannst du ja annehmen, der ist ja im kreis überall gleich).
Den berechnest du dann wie von suxx angegeben mit dem cosinus? (und beta eben mit dem sinus).

sorry, wenn das nich viel bringt, ich seh dein problem grad nicht wirklich?

Annehmen das er senkrecht auf der Wand steht, das ist immer der Fall, da sich die Gerade an der abgeprallt wird, aus C und M berechnet und immer 90° zu dieser Strecke ist.

Nochmals: wir haben in der Schule nie gelernt wie man einen Sinus berechnet, geschweige denn das rechnen mit Vektoren. Ich taste mich gerade Blind durch dieses Gebiet der Mathematik ohne auch nur den blassesten Schimmer zu haben, was das Programm da gerade berechnet für meine Kollisionen und das Abprallen$§p4
Das habe ich ausm Netz zusammen kopiert, und wundersamerweise hat es bisher einigermassen geklappt.

So fühle ich mich während ich an diesen Berechnungen was mache, bzw. ausprobiere:
http://static.giantbomb.com/uploads/original/12/124959/2118856-i_have_no_idea_what_i_m_doing.jpg

Daepilin
28.06.2013, 13:17
einfach einsetzten ;) es gibt (auch in c#) sinus, cosinus und arc funktionen. Da übergibst du deine werte und bekommst das gewünschte zurückgegeben ;)

wär also sowas wie beta = Math.arcsin( (r/(sqrt(x*x + y*y))));

(keine ahnung, ob der syntax so komplett stimmt, wie gesgat hab keine ahnung von c#^^)


jo, du überprüfst halt einfach, ob der abstand zwischen wand und m = r ist und führst dann deine kollision durch.

Sergej Petrow
28.06.2013, 16:08
^^Wobei mich immer stört, dass alles in Bogenmaß gerechnet wird.
MMn ist es oftmals günstiger, dass ganze in Grad umzurechnen.

Merk dir einfach GAGAHHAG, dann hast Du alles, was Du wissen musst.
Achja, und natürlich musst Du wissen, was Hypotenuse, Gegenkathete und Ankathete sind.

GAGA
HHAG

steht für SIN, COS, TAN, COT.

Als Beispiel sinus alpha = G/H = Gegenkathete/Hypotenuse, cosinus alpha =
A/H = Ankathete durch Hypotenuse usw.

Nehmen wir an, Du hast Winkel alpha und der liegt an an der Hypotenuse. Dann ist die Ankathete die Seite des Dreiecks, die mit der Hypotenuse diesen Winkel umschliesst. Die Gegenkathete liegt dann genau gegenüber des Winkel alphas.
Oder schaust dir das hier mal an: http://commons.wikimedia.org/wiki/File:Dreieck.PNG

Kannst Du also immer so hindrehen. Wenn Du das hast und GAGAHHAG benutzt, kannst Du eigentlich schon das meiste im Dreieck berechnen.

Daepilin
28.06.2013, 16:38
also laut der microsoftseite gibt die funktion einem das in grad aus :dnuhr:

und in der uni hab ich gelernt, dass bogenmaß für ingenieurstechnische vorgänge oft praktischer ist, weil sich pi oft schön rauskürzt^^ (oder e^pi einfach übersichtlicher als e^180° ist)

Multithread
28.06.2013, 17:20
^^Wobei mich immer stört, dass alles in Bogenmaß gerechnet wird.
MMn ist es oftmals günstiger, dass ganze in Grad umzurechnen.

Merk dir einfach GAGAHHAG, dann hast Du alles, was Du wissen musst.
Achja, und natürlich musst Du wissen, was Hypotenuse, Gegenkathete und Ankathete sind.

GAGA
HHAG

steht für SIN, COS, TAN, COT.

Als Beispiel sinus alpha = G/H = Gegenkathete/Hypotenuse, cosinus alpha =
A/H = Ankathete durch Hypotenuse usw.

Nehmen wir an, Du hast Winkel alpha und der liegt an an der Hypotenuse. Dann ist die Ankathete die Seite des Dreiecks, die mit der Hypotenuse diesen Winkel umschliesst. Die Gegenkathete liegt dann genau gegenüber des Winkel alphas.
Oder schaust dir das hier mal an: http://commons.wikimedia.org/wiki/File:Dreieck.PNG

Kannst Du also immer so hindrehen. Wenn Du das hast und GAGAHHAG benutzt, kannst Du eigentlich schon das meiste im Dreieck berechnen.
Mit Eselsbrücken kann ich nicht viel anfangen, der Satz des Pytagoras ist mir aber bekannt:)

vom Wiki bild ausgehend:
Ich habe B (Gegenstand Mitte) und C (Kollisionspunkt)
c ist dann die Bewegungsrichtung

Dann müsste ich also Beta ausrechnen?

Ich hab schon mal probiert, da kommen aber falsche werte raus:(
Irgendwo muss da mindestens ein Fehler drin sein, beta ist immer NaN.


public Vektor abprallen(Gegenstand g, List<Point> _wande, GravitationRichtung _richtung)
{
Point position = new Point(g.X, g.Y);
Vektor alteRichtung = g.Bewegungsrichtung;
Vektor abprallwand = null;

Vektor umrechnung = new Vektor(1.0M, 1.0M);//zur umrechnung bei Kollisionen an schrägen flächen, aktuell nur für Richtungswechsel zuständig
int x = 0;
int y = 0;
Point kollisionPunkt = Point.Empty;

if (_wande.Count > 0)
{
long lx = 0;
long ly = 0;
foreach (Point p in _wande)
{
lx += p.X;
ly += p.Y;
}
kollisionPunkt = (new Point((int)(lx / _wande.Count), (int)(ly / _wande.Count)));
abprallwand = new Vektor(kollisionPunkt.Y - position.Y, kollisionPunkt.X - position.X);
}
decimal skalar = abprallwand.X * alteRichtung.X + alteRichtung.Y * abprallwand.Y;
decimal dx = alteRichtung.X;
decimal dy = alteRichtung.Y;
double beta = Math.Asin(((double)-skalar / (Math.Sqrt(x * x + y * y))));

Daepilin
28.06.2013, 17:45
warum das - im zähler bei dem arcsin?

und warum nutzt du hier dein skalar? brauchst du nicht! der zähler ist( im wiki bild) die strecke a, also dein abstand mittelpunkt-kollisionspunkt. (oder soll es das berechnen? tut es aber so nicht, wenn ich das nicht falsch sehe!)

Sergej Petrow
28.06.2013, 17:58
Wenn Du die Punkte B und C hast, dann hast Du auch a. Wenn Du auch noch c hast, wie Du sagst, also die Strecke AC, hast Du mehr als genug. Hm, dann hast Du sogar alles.

B bestimmt sich durch B.x und B.y, C durch C.x und C.y.

Dann ist a = sqrt((B.y-C.y)*(B.y-C.y)+(C.x-B.x)*(C.x-B.x))

Wenn Du dann beta haben willst, also den Winkel zwischen klein a und klein c, ist das der Kosinus => GAGA/HHAG, das zweite also und zwar Ankathete durch Hypotenuse.

=> cos beta = a/c

Aber ich nehme mal an, dass Du nicht alles hast.

Auf jedenfall musst Du vom Schaubild ausgehend Groß- und Kleinschreibung beachten. Kleinschreibung beschreibt die Strecke, Großschreibung die Punkte.

Wenn Du schreibst, Du hast B und C, gehe ich von Punkten aus. Danach schreibst Du, dass Du a hast und c im Prinzip auch, gehe ich von den Strecken CB und AB aus.

Wenn Du ne Digitalkamera hast, mal das doch mal auf, was Du glaubst zu haben. Ich denke, dann kommen wir wesentlich besser auf das, was Du brauchst.

Multithread
28.06.2013, 20:07
http://upload.worldofplayers.de/files9/Meine_Frage.png

Das brauche ich.
Haben tue ich die Rote Linie als Bewegungsvektor und die beiden Endpunkte der Violetten. Mehr nicht.


warum das - im zähler bei dem arcsin?

und warum nutzt du hier dein skalar? brauchst du nicht! der zähler ist( im wiki bild) die strecke a, also dein abstand mittelpunkt-kollisionspunkt. (oder soll es das berechnen? tut es aber so nicht, wenn ich das nicht falsch sehe!)
Gut, dann ist die frage wie ich die Violette Strecke korrekt berechne.




Wenn Du die Punkte B und C hast, dann hast Du auch a. Wenn Du auch noch c hast, wie Du sagst, also die Strecke AC, hast Du mehr als genug. Hm, dann hast Du sogar alles.

Na das hoffe ich doch:D




B bestimmt sich durch B.x und B.y, C durch C.x und C.y.

Dann ist a = sqrt((B.y-C.y)*(B.y-C.y)+(C.x-B.x)*(C.x-B.x))

Wenn Du dann beta haben willst, also den Winkel zwischen klein a und klein c, ist das der Kosinus => GAGA/HHAG, das zweite also und zwar Ankathete durch Hypotenuse.

=> cos beta = a/c

Aber ich nehme mal an, dass Du nicht alles hast.

Auf jedenfall musst Du vom Schaubild ausgehend Groß- und Kleinschreibung beachten. Kleinschreibung beschreibt die Strecke, Großschreibung die Punkte.

Wenn Du schreibst, Du hast B und C, gehe ich von Punkten aus. Danach schreibst Du, dass Du a hast und c im Prinzip auch, gehe ich von den Strecken CB und AB aus.

Wenn Du ne Digitalkamera hast, mal das doch mal auf, was Du glaubst zu haben. Ich denke, dann kommen wir wesentlich besser auf das, was Du brauchst.
So, aufgezeichnet habe ich:)

Die obersten 2 Sätze verstehe ich noch, beim dritten muss ich schon arg hirnen....
Ne, den 3ten verstehe ich nicht mehr:(

Daepilin
28.06.2013, 20:16
ach so, jetzt versteh ich mal genau, was du da wie machst...

dann hab ich deinen code auch nich so ganz richtig verstanden:

v (wie violett): v = c - m, wenn das alles 2d ist also: z.b. m(3, 2) c(5, 4) -> v = (-2, -2);

dann wirds (n bisschen) schwieriger, weil du blau nicht hast :/

du hast ja nun v = (-2, -2). wenn der blaue vektor orthogonal (= senkrecht) zu v sein soll heißt das, dass das skalarprodukt 0 wird. , d.h. (-2, -2) * (x, y) = 0;
dazu brauchts dann wieder a1b1 + a2b2

-2*x + -2*y = 0 -> x oder y = -2, der andere = 2, also z.B. b = (-2, 2).
Kann man dann noch normieren (= betrag = 1 setzten) -> bn = (-1, 1). der vektor + alle vielfachen davon sind senkrecht zu v, und laufen( wenn du sie so legst) durch c.
e: ups, natürlich stimmt das hier so nicht :/ betrag ist nicht = 1, hab aber später damit so weitergerechnet, änder ich jetzt also nichmehr :P (rechnung is aber korrekt, später hab ichs beachtet)


jetzt hast du also den geschwindigkeitsvektor (ich nenne ihn a) und deine wand (b) und brauchst den winkel dazwischen. Das geht dann wieder übers skalarprodukt.
ich nehme an, dass a (-4, 1) (ist jetzt n bisschen wilkürlich, sollte b aber schneiden).
mal eben die beträge: abs(a) = ~ 4,1 ; abs(b) = ~ 1,4

und weiterhin a1b1 +a2b2 = abs(a)*abs(b) * cos(alpha)
-> 5 / 5,74 = cos (alpha) -> 0.87 = cos(alpha) -> alpha = arccos(0.87) -> alpha = ~ 30°

daraus jetzt noch den abprallvektor bestimmen (huh).
Zu dem weißt du, dass er mit b ebenfalls den 30° winkel einschließt, halt in die andere richtung.

wichtig: womit ich die ganze zeit hier schon spiele: du kannst zu einem vektor beliebige faktoren zumultipizieren (sofern du zu allen komponenten den gleichen faktor multiplizierst) ohne winkelbeziehungen o.ä. zu ändern.

zur einfachheit nehm ich jetzt also an, dass abs(v_ref) = 1 (v_ref = abprallvektor). zur erinnerung, abs(b) ~ 1,4
b1v_ref1 + b2v_ref2 = 1,4 * cos( 30°) = 1.2

b1*v_ref1 + b2*v_ref2 = 1.2
b1 = -1 ; b2 = 1
-> -v_ref1 + v_ref2 = 1.2.
-> v_ref2 = 1.2 + v_ref1
außerdem: sqrt(v_ref1² + v_ref2²) = 1
da setzt man für v_ref2 ein:
1 = sqrt(v_ref1² + (v_ref1+1.2)²)
quadrieren:
1= v_ref1² + (v_ref1+1-2)²

binomische formel:

1= 2v_ref1² + 2.4v_ref1 + 1.44
das jetzt nurnoch lösen:

0.5 = v_ref1² + 1.2v_ref1 + 0.72
-0.22 = v_ref1²+1.2v_ref1
0 = v_ref1² + 1.2v_ref1 + 0.22

p/q formel:

gibt 2 lösungen: v_ref1 = -0.22 und v_ref1=-0.97, hier ist sicherlich die erste gewollt, die zweite würde uns durch die wand treiben^^

jetzt v_ref2 = v_ref1 + 1.2 -> v_ref2 = 0.98

v_ref(-0.22, 0.98)

soo, das wäre der reflektierte vektor(normiert auf abs(v_ref) = 1). Aber ob das performant genug ist? ich würd sagen, das dauert ne weile und ist recht komplex umzusetzten, wenns "nur" als kollisionsabfrage dienen soll... vor allem, weil man in nem automatisierten programm dann bei der auswahl von v_ref1 nochmal kontrolieren muss, welcher von beiden vektoren durch die wand geht und welcher nicht...

vlt kann ich (oder wer anderes) da mal überlegen, wie das einfacher "close enough" geht, oder ob das einigermaßen brauchbar umsetzbar wäre... ich würd ja sagen nein, da dürfte der rechner zu lange dran hocken... auch wenn im endeffekt alles nru an den koeffizienten hängt, die variablen sind ja statisch... hm...

sonst gieß ich das vlt morgen mal in code und guck mal wie unperformant das wirklich ist...

ps: ich hoffe du lebst jetzt noch und ich hab dich nich mit mathe erschlagen^^

Multithread
29.06.2013, 18:35
ach so, jetzt versteh ich mal genau, was du da wie machst...

dann hab ich deinen code auch nich so ganz richtig verstanden:

v (wie violett): v = c - m, wenn das alles 2d ist also: z.b. m(3, 2) c(5, 4) -> v = (-2, -2);

dann wirds (n bisschen) schwieriger, weil du blau nicht hast :/

du hast ja nun v = (-2, -2). wenn der blaue vektor orthogonal (= senkrecht) zu v sein soll heißt das, dass das skalarprodukt 0 wird. , d.h. (-2, -2) * (x, y) = 0;
dazu brauchts dann wieder a1b1 + a2b2

-2*x + -2*y = 0 -> x oder y = -2, der andere = 2, also z.B. b = (-2, 2).
Kann man dann noch normieren (= betrag = 1 setzten) -> bn = (-1, 1). der vektor + alle vielfachen davon sind senkrecht zu v, und laufen( wenn du sie so legst) durch c.
e: ups, natürlich stimmt das hier so nicht :/ betrag ist nicht = 1, hab aber später damit so weitergerechnet, änder ich jetzt also nichmehr :P (rechnung is aber korrekt, später hab ichs beachtet)

jetzt hast du also den geschwindigkeitsvektor (ich nenne ihn a) und deine wand (b) und brauchst den winkel dazwischen. Das geht dann wieder übers skalarprodukt.

So, ich glaube bis hier her hats geklappt, mit der hilfe ausm anderen Post, quote weiter unten.




ich nehme an, dass a (-4, 1) (ist jetzt n bisschen wilkürlich, sollte b aber schneiden).
mal eben die beträge: abs(a) = ~ 4,1 ; abs(b) = ~ 1,4

und weiterhin a1b1 +a2b2 = abs(a)*abs(b) * cos(alpha)
-> 5 / 5,74 = cos (alpha) -> 0.87 = cos(alpha) -> alpha = arccos(0.87) -> alpha = ~ 30°

was genau ist nun Alpha für ein Wert?




daraus jetzt noch den abprallvektor bestimmen (huh).
Zu dem weißt du, dass er mit b ebenfalls den 30° winkel einschließt, halt in die andere richtung.

wichtig: womit ich die ganze zeit hier schon spiele: du kannst zu einem vektor beliebige faktoren zumultipizieren (sofern du zu allen komponenten den gleichen faktor multiplizierst) ohne winkelbeziehungen o.ä. zu ändern.

zur einfachheit nehm ich jetzt also an, dass abs(v_ref) = 1 (v_ref = abprallvektor). zur erinnerung, abs(b) ~ 1,4
b1v_ref1 + b2v_ref2 = 1,4 * cos( 30°) = 1.2

b1*v_ref1 + b2*v_ref2 = 1.2
b1 = -1 ; b2 = 1
-> -v_ref1 + v_ref2 = 1.2.
-> v_ref2 = 1.2 + v_ref1
außerdem: sqrt(v_ref1² + v_ref2²) = 1
da setzt man für v_ref2 ein:
1 = sqrt(v_ref1² + (v_ref1+1.2)²)
quadrieren:
1= v_ref1² + (v_ref1+1-2)²

binomische formel:

1= 2v_ref1² + 2.4v_ref1 + 1.44
das jetzt nurnoch lösen:

0.5 = v_ref1² + 1.2v_ref1 + 0.72
-0.22 = v_ref1²+1.2v_ref1
0 = v_ref1² + 1.2v_ref1 + 0.22

p/q formel:

gibt 2 lösungen: v_ref1 = -0.22 und v_ref1=-0.97, hier ist sicherlich die erste gewollt, die zweite würde uns durch die wand treiben^^

jetzt v_ref2 = v_ref1 + 1.2 -> v_ref2 = 0.98

v_ref(-0.22, 0.98)

Ach du heilige Mathematik, das wirkt ja kompliziert:scared:
Können wir das bitte schritt für Schritt und ganz langsam machen? Fragen habe ich auch so schon genug.





soo, das wäre der reflektierte vektor(normiert auf abs(v_ref) = 1). Aber ob das performant genug ist? ich würd sagen, das dauert ne weile und ist recht komplex umzusetzten, wenns "nur" als kollisionsabfrage dienen soll... vor allem, weil man in nem automatisierten programm dann bei der auswahl von v_ref1 nochmal kontrolieren muss, welcher von beiden vektoren durch die wand geht und welcher nicht...

vlt kann ich (oder wer anderes) da mal überlegen, wie das einfacher "close enough" geht, oder ob das einigermaßen brauchbar umsetzbar wäre... ich würd ja sagen nein, da dürfte der rechner zu lange dran hocken... auch wenn im endeffekt alles nru an den koeffizienten hängt, die variablen sind ja statisch... hm...

sonst gieß ich das vlt morgen mal in code und guck mal wie unperformant das wirklich ist...

ps: ich hoffe du lebst jetzt noch und ich hab dich nich mit mathe erschlagen^^
Performance ist kein Problem, MT sei dank.



dein elsezweig ist so nicht korrekt. zu einem vektor (1 / 1) wäre dein ergebnis nciht senkrecht, sondern würde irgendwie in grob die gleiche richtung gehen.

wenn beide werte != 0 sind, musst du einen umkehren, der andere bleibt dann:

aus (1 / 1) wird (-1 / 1) oder (1 / -1), aus (-3 / 2) wird (3/ 2) oder (-3 / -2)

der betrag ist ansich egal.

das is blöd, das is ansich echt nichts schweres :/ weiß auch grad nicht, wie ich dir das besser erklären soll... hm..
aso, behoben^2^

Dann probieren wir es doch mit realen werten:o
alteRichtung=0/1.6 (rote linie)
Gegenstandsmitte=132/865 ('mitte' Schwarzes Viereck. M)
kollisionspunkt=124/896 (Schnittpunkt blaue/violette linie. C)
senkrechte=8/-31 (violette linie)
abprallwand=8/31 (blaue linie)?
skalarprodukt=49.6 (länge violette linie?)

Das sind meine aktuellen werte, also das was ich bisher alles habe.

Daepilin
29.06.2013, 19:59
So, ich glaube bis hier her hats geklappt, mit der hilfe ausm anderen Post, quote weiter unten.

schön :)


was genau ist nun Alpha für ein Wert?

dein auftreff/abprallwinkel.


Ach du heilige Mathematik, das wirkt ja kompliziert:scared:
Können wir das bitte schritt für Schritt und ganz langsam machen? Fragen habe ich auch so schon genug.


bis auf das ende (also lösen von quadratischen gleichungen) is das doch schritt für schritt? mal schaun, ob ich dir das noch weiter auffriemeln kann :/



Performance ist kein Problem, MT sei dank.

na dann^^


aso, behoben^2^

k


Dann probieren wir es doch mit realen werten:o
alteRichtung=0/1.6 (rote linie)
Gegenstandsmitte=132/865 ('mitte' Schwarzes Viereck. M)
kollisionspunkt=124/896 (Schnittpunkt blaue/violette linie. C)
senkrechte=8/-31 (violette linie)
abprallwand=8/31 (blaue linie)?
skalarprodukt=49.6 (länge violette linie?)

Das sind meine aktuellen werte, also das was ich bisher alles habe.

soweit korrekt, aber:

das skalarprodukt brauchst du nicht als irgend einen wert^^ das dient nur um auf den winkel zu kommen^^ (und es ist auch nicht die länge von dem violetten vektor).

Multithread
29.06.2013, 21:02
Also mit meinen Bezerichnungen:

skalarprodukt = abs(a)*abs(b) * cos(aufprallwinkel)
abs(a)*abs(b) entsprechen doch dem Skalarprodukt wenn ich das richtig verstanden habe.



-> 5 / 5,74 = cos (alpha) -> 0.87 = cos(alpha) -> alpha = arccos(0.87) -> alpha = ~ 30°

§kratz
ich muss 2 mal den Cosinus aus dem aufprallwinkel der vorhergehenden rechnung nehmen, und danach noch den arccos§kratz




wichtig: womit ich die ganze zeit hier schon spiele: du kannst zu einem vektor beliebige faktoren zumultipizieren (sofern du zu allen komponenten den gleichen faktor multiplizierst) ohne winkelbeziehungen o.ä. zu ändern.

Den satz hab ich doch mal vollumfänglich verstanden:)

Dennoch möchte ich dich bitten das nicht zu tun, ich habe so schon mehr als genug mühe irgendwas zu verstehen, dieses Cos rechnen ist mir neu, und ich stelle mich grad so schon dumm genug an§gnah



den rest des postes würde ich gerne mal unbeachtet lassen, bis ich diesen teil hier oben richtig habe:gratz

Daepilin
29.06.2013, 21:19
Also mit meinen Bezerichnungen:

skalarprodukt = abs(a)*abs(b) * cos(aufprallwinkel)
abs(a)*abs(b) entsprechen doch dem Skalarprodukt wenn ich das richtig verstanden habe.

nein, abs(a) bzw abs(b) sind nur die beträge, für das skalarprodutk gehört da noch der cos(alpha) zu



§kratz
ich muss 2 mal den Cosinus aus dem aufprallwinkel der vorhergehenden rechnung nehmen, und danach noch den arccos§kratz

nein, der pfeil ist immer der nächste schritt^^ 5 / 5.74 ist eben 0.87, das entspricht dem cosinus von alpha ( 5 war das berechnete skalarprodukt, 5.74 die mutiplizierten beträge der beiden vektoren). um alpha zu bekommen setzt du das jetzt als argument in den arccos ein und erhälst als ergebnis den winkel alpha.



Den satz hab ich doch mal vollumfänglich verstanden:)

Dennoch möchte ich dich bitten das nicht zu tun, ich habe so schon mehr als genug mühe irgendwas zu verstehen, dieses Cos rechnen ist mir neu, und ich stelle mich grad so schon dumm genug an§gnah


hab ich nichmal wirklich ausgenutzt :dnuhr: sollte dir nur zeigen, dass du die rechnung ansich auch mit normierten vektoren durchführen kannst und deine werte nicht mitschleppen musst. (1, -1) hat halt die gleiche richtung wie (17, -17). In deinem programm brauchst du es im endeffekt nicht wirklich, sofern du immer den gleichen reflexionsfaktor hast (wieviel der aufprallenergie bekommt der gegenstand wieder als kinetische energie mitgegeben).

wenn du allerdings gebrauch davon machst kann deine richtungsberechnung einfach mit normierten vektoren durchgeführt werden und du mutiplizierst später für die richtige kraft nur ein skalar( d.h. eine eindimensionale (normale) zahl) mit deinem vektor.

in der reinen rechnugn macht es das ganze nur leichter, da man eben beim ausrechnen des abprallvektors einfach den betrag = 1 nehmen kann und sich nicht da schon gedanken über den finalen betrag des vektors machen muss.

wenn man jetzt z.b. mit nem geschwindigkeitsvektor ( 0,5 ; 1) auf die wand zufliegt hat der den betrag 1.118

man möchte, dass 100% der ernergie reflektiert werden, also rechnet man jetzt den abprallvektor normiert (aka betrag = 1) aus und mutipliziert mit diesen 1.118 um das zu erreichen.
wenn man jetzt möchte, dass 50% energie verloren gehen(weiche wand z.B.) mutipliziert man den normierten abprallvektor nur mit der hälfte, also 0.559


ich weiß, das is alles nciht ganz einfach zu verstehen, aber ich weiß echt nicht, wie ich dir das viel besser erklären könnte :/ ne sehr gute skizze hat dir worldsuxx schon gemacht und das berechnen von dem abprallvektor ist halt n großteil analysis und n bisschen lineare algebra, das kann man zeichnerisch nicht wirklich zeigen.

Multithread
29.06.2013, 21:53
nein, abs(a) bzw abs(b) sind nur die beträge, für das skalarprodutk gehört da noch der cos(alpha) zu

arg, das verstehe ich nicht. Versuchen wir es mal ohne grosse Theorie dahinter? Diese abs verwirren mich nur, Math.abs(x) bedeutet in C# das aus x ein vorzeichenloser/Positiver Wert gemacht wird.




nein, der pfeil ist immer der nächste schritt^^ 5 / 5.74 ist eben 0.87, das entspricht dem cosinus von alpha ( 5 war das berechnete skalarprodukt, 5.74 die mutiplizierten beträge der beiden vektoren). um alpha zu bekommen setzt du das jetzt als argument in den arccos ein und erhälst als ergebnis den winkel alpha.

ok, skalarprodukt habe ich ja schon:
(skalarprodukt = alteRichtung.X * abprallwand.X + alteRichtung.Y * abprallwand.Y;)
Wie multipliziere ich die Beträge der beiden Vektoren?
Dann bekomme ich wieder nen Vektor raus.

Zumindest das mit der (arc)Cos Berechnung habe ich inzwischen glaub verstanden:D




ich weiß, das is alles nciht ganz einfach zu verstehen, aber ich weiß echt nicht, wie ich dir das viel besser erklären könnte :/ ne sehr gute skizze hat dir worldsuxx schon gemacht und das berechnen von dem abprallvektor ist halt n großteil analysis und n bisschen lineare algebra, das kann man zeichnerisch nicht wirklich zeigen.
ana-was?

Analysis hatte ich ebenfalls nie in der schule, ich komme mir grad so dumm vor:C:

Abprallstärke kümmert mich ebenfalls noch nicht, solange das abprallen nicht korrekt geht, ist alles andere drum herum scheiss egal.

Sergej Petrow
29.06.2013, 22:47
arg, das verstehe ich nicht. Versuchen wir es mal ohne grosse Theorie dahinter? Diese abs verwirren mich nur, Math.abs(x) bedeutet in C# das aus x ein vorzeichenloser/Positiver Wert gemacht wird.
abs heißt absolut und ja, der absolute Wert ist der positive Wert.



Zumindest das mit der (arc)Cos Berechnung habe ich inzwischen glaub verstanden:D
Vielleicht noch ergänzend:
Der Cosinus alpha ist ja Ankathete durch Hypotenuse. A/H entspricht also Cosinus alpha. Was Du aber haben willst, ist den Winkel selbst. Dafür braucht es den Arkuscosinus.

Das ist bei allen Winkelfunktionen so. Sinus alpha => alpha = Arkussinus alpha
Tangens alpha => alpha = arkustangens alpha.
Nehmen wir das bekannte Dreieck mit den Seitenlängen 3,4 und 5.
So ist 3(Ankathete)/5(Hypotenuse)=0,6=cosinus alpha, alpha = arkuscosinus alpha = arkuskosinus 0,6 = alpha = 53,13°.
4(Ankathete)/5(Hypotenuse)=0,8=cosinus alpha, alpha = arkuscosinus alpha = arkuskosinus 0,8 = 36,87°. Der Winkel zwischen a und b ist ja bekanntlich 90°. 53,13+36,87+90=180°. Passt.

Daepilin
29.06.2013, 22:54
arg, das verstehe ich nicht. Versuchen wir es mal ohne grosse Theorie dahinter? Diese abs verwirren mich nur, Math.abs(x) bedeutet in C# das aus x ein vorzeichenloser/Positiver Wert gemacht wird.


abs() = betrag, ja ;)


ok, skalarprodukt habe ich ja schon:
(skalarprodukt = alteRichtung.X * abprallwand.X + alteRichtung.Y * abprallwand.Y;)
Wie multipliziere ich die Beträge der beiden Vektoren?
Dann bekomme ich wieder nen Vektor raus.

nein, da bekommst du einfach ne zahl raus, genau wie beim skalarprodukt (ist ja auch ein weg das zu berechnen)



Zumindest das mit der (arc)Cos Berechnung habe ich inzwischen glaub verstanden:D

siehste^^



ana-was?

Analysis hatte ich ebenfalls nie in der schule, ich komme mir grad so dumm vor:C:

Abprallstärke kümmert mich ebenfalls noch nicht, solange das abprallen nicht korrekt geht, ist alles andere drum herum scheiss egal.

was bringen die euch nur bei in der schweiz O_O viel scheints nich zu sein :P (analysis is normale funktionsrechnung, also kurvendiskussion und co; lineare algebra ist z.B. das vektorenzeug)

dachte eigentlich, das sowas mal minimum ab mittlerer reife standardstoff is oO winkelrechnung sollte sogar schon in der hauptschule standardstoff sein oO (ich unterstell dir nichts, wenns halt nich im lehrplan ist... wundert mich nur n bisschen oO schweizer sidn doch sonst so gut im rechnen von zins, zinseszins und co :P)

ps: bin pennen, wenn du jetzt noch was hast muss es bis morgen warten :P

Multithread
30.06.2013, 09:12
abs() = betrag, ja ;)

nein, da bekommst du einfach ne zahl raus, genau wie beim skalarprodukt (ist ja auch ein weg das zu berechnen)

\\o//

irgendwas mache ich noch falsch, wie kommst du afu deine 5.74?
Habe ich die falschen Vektoren benutzt oder nur falsch gerechnet?


decimal skalarprodukt = alteRichtung.X * abprallwand.X + alteRichtung.Y * abprallwand.Y;
decimal absMultiplikation = Math.Abs(alteRichtung.X) * Math.Abs(abprallwand.X) + Math.Abs(alteRichtung.Y) * Math.Abs(abprallwand.Y);
decimal winkel = Math.Arccos(skalrprodukt/absMultiplikation);





was bringen die euch nur bei in der schweiz O_O viel scheints nich zu sein :P (analysis is normale funktionsrechnung, also kurvendiskussion und co; lineare algebra ist z.B. das vektorenzeug)

dachte eigentlich, das sowas mal minimum ab mittlerer reife standardstoff is oO winkelrechnung sollte sogar schon in der hauptschule standardstoff sein oO (ich unterstell dir nichts, wenns halt nich im lehrplan ist... wundert mich nur n bisschen oO schweizer sidn doch sonst so gut im rechnen von zins, zinseszins und co :P)

ps: bin pennen, wenn du jetzt noch was hast muss es bis morgen warten :P
WIr haben eben nicht den Gleichen Schulstoff wie Ihr, wir haben zb. ein Halbes Jahr lang Wahrscheinlichkeiten durchgekaut:D

Trigonometrie haben wir lediglich so weit gemacht, das wir wissen das man aus Winkeln und längen dreiecke zusammensetzten kann.
die cos und co haben wir in der Sekundar nie angewandt. Ich habe nicht die höchste Schulstufe gemacht, und in der Höheren stufe, haben wir eben Wahrscheinlichkeit anstelle von Trigonometrie gemacht:C:

Lineare Algebra kann ich noch, das ist nicht das Problem, das haben wir auch mal gelernt:)
Analysis hatte ich aber nie, klingt aber noch spannend.

Daepilin
30.06.2013, 09:34
\\o//

decimal skalarprodukt = alteRichtung.X * abprallwand.X + alteRichtung.Y * abprallwand.Y;
decimal absMultiplikation = Math.Abs(alteRichtung.X) * Math.Abs(abprallwand.X) + Math.Abs(alteRichtung.Y) * Math.Abs(abprallwand.Y);
decimal winkel = Math.Arccos(skalrprodukt/absMultiplikation);



die 5.74 ist abs(a) * abs(b). (also 4.1 * 1.4)

du machst das im zweiten schritt falsch.

Du musst die beträge der vektoren nehmen, nicht die beträge der elemente. die einzelnen elemente nimmst du nur bei der anderen formel.

betrag von nem vektor ist: abs(a) = sqrt(a1² + a2² + ... + an²)

Multithread
30.06.2013, 10:44
und weiterhin a1b1 +a2b2 = abs(a)*abs(b) * cos(alpha)
-> 5 / 5,74 = cos (alpha) -> 0.87 = cos(alpha) -> alpha = arccos(0.87) -> alpha = ~ 30°

ich habe jetzt:
Skalar = 49.6
multi aus den beiden ABS werten = ~51.225
Arccos aus(Skalar/multti aus den Abs werten) = 0.25


double skalarprodukt = (double)(alteRichtung.X * abprallwand.X + alteRichtung.Y * abprallwand.Y);
double absMultiplikation = Math.Sqrt((double)(alteRichtung.X * alteRichtung.X + alteRichtung.Y * alteRichtung.Y));
absMultiplikation *= Math.Sqrt((double)(abprallwand.X * abprallwand.X + abprallwand.Y * abprallwand.Y));
double wert = Math.Acos(skalarprodukt / absMultiplikation);

Das erscheint mir richtig, wobei die 0.25 wohl bogenmass sind.


Also: weiter gehts:)


zur einfachheit nehm ich jetzt also an, dass abs(v_ref) = 1 (v_ref = abprallvektor).

zur erinnerung, abs(b) ~ 1,4
b1*v_ref1 + b2*v_ref2 = 1,4 * cos( 30°) = 1.2


brauche ich die beiden abs werte von abprallwand-Vektor und alterBewegungsrichtung noch oft?

b1 und b2, ist das der abprall Wand Vektor?
was ist nun v_ref1 und v_ref2? Der abprallvektor, also die Bewegungsrichtung nach der Kollision?




b1*v_ref1 + b2*v_ref2 = 1.2
b1 = -1 ; b2 = 1
-> -v_ref1 + v_ref2 = 1.2.
-> v_ref2 = 1.2 + v_ref1
außerdem: sqrt(v_ref1² + v_ref2²) = 1
da setzt man für v_ref2 ein:
1 = sqrt(v_ref1² + (v_ref1+1.2)²)
quadrieren:
1= v_ref1² + (v_ref1+1-2)²


ist das nur das umschichten, oder wird da noch was anderes gemacht?

Und was hat es mit dem b = 1/1 auf sich?



binomische formel:

1= 2v_ref1² + 2.4v_ref1 + 1.44
das jetzt nurnoch lösen:

0.5 = v_ref1² + 1.2v_ref1 + 0.72
-0.22 = v_ref1²+1.2v_ref1
0 = v_ref1² + 1.2v_ref1 + 0.22

p/q formel:

gibt 2 lösungen: v_ref1 = -0.22 und v_ref1=-0.97, hier ist sicherlich die erste gewollt, die zweite würde uns durch die wand treiben^^

jetzt v_ref2 = v_ref1 + 1.2 -> v_ref2 = 0.98

v_ref(-0.22, 0.98)

soo, das wäre der reflektierte vektor(normiert auf abs(v_ref) = 1). Aber ob das performant genug ist? ich würd sagen, das dauert ne weile und ist recht komplex umzusetzten, wenns "nur" als kollisionsabfrage dienen soll... vor allem, weil man in nem automatisierten programm dann bei der auswahl von v_ref1 nochmal kontrolieren muss, welcher von beiden vektoren durch die wand geht und welcher nicht...


Den letzten teil schauen wir später an.

Daepilin
30.06.2013, 13:20
ich habe jetzt:
Skalar = 49.6
multi aus den beiden ABS werten = ~51.225
Arccos aus(Skalar/multti aus den Abs werten) = 0.25


double skalarprodukt = (double)(alteRichtung.X * abprallwand.X + alteRichtung.Y * abprallwand.Y);
double absMultiplikation = Math.Sqrt((double)(alteRichtung.X * alteRichtung.X + alteRichtung.Y * alteRichtung.Y));
absMultiplikation *= Math.Sqrt((double)(abprallwand.X * abprallwand.X + abprallwand.Y * abprallwand.Y));
double wert = Math.Acos(skalarprodukt / absMultiplikation);

Das erscheint mir richtig, wobei die 0.25 wohl bogenmass sind.
kann gut sein, musste gucken, als was dir die acos funktion den winkel gibt. bin jetzt von grad ausgegangen, aber das rechnet sich gleich, wenn alle funktionen bogenmaß nehmen.




Also: weiter gehts:)


zur einfachheit nehm ich jetzt also an, dass abs(v_ref) = 1 (v_ref = abprallvektor).

zur erinnerung, abs(b) ~ 1,4
b1*v_ref1 + b2*v_ref2 = 1,4 * cos( 30°) = 1.2


brauche ich die beiden abs werte von abprallwand-Vektor und alterBewegungsrichtung noch oft?

b1 und b2, ist das der abprall Wand Vektor?
was ist nun v_ref1 und v_ref2? Der abprallvektor, also die Bewegungsrichtung nach der Kollision?



b ist die wand, ja.

die werte brauchst du meine ich später nichtmehr.
v_ref ist der bewegungsvektor nach der kollision, ja.




b1*v_ref1 + b2*v_ref2 = 1.2
b1 = -1 ; b2 = 1
-> -v_ref1 + v_ref2 = 1.2.
-> v_ref2 = 1.2 + v_ref1
außerdem: sqrt(v_ref1² + v_ref2²) = 1
da setzt man für v_ref2 ein:
1 = sqrt(v_ref1² + (v_ref1+1.2)²)
quadrieren:
1= v_ref1² + (v_ref1+1-2)²


ist das nur das umschichten, oder wird da noch was anderes gemacht?
Und was hat es mit dem b = 1/1 auf sich?


wo siehst du da b = 1/1? das b1 = -1 und b2 = 1 sind nur die werte für b, die ich für die rechnung angenommen habe.

ansich ist das einfach nur umformen. ich geh von beiden formeln fürs skalarprodukt aus, und hab dann halt ein gleichungssystem. (eine gleichung ist der betrag vom reflekttierten vektor (definiert als 1), die zweite halt die gleichungen fürs skalarprodukt.




binomische formel:

1= 2v_ref1² + 2.4v_ref1 + 1.44
das jetzt nurnoch lösen:

0.5 = v_ref1² + 1.2v_ref1 + 0.72
-0.22 = v_ref1²+1.2v_ref1
0 = v_ref1² + 1.2v_ref1 + 0.22

p/q formel:

gibt 2 lösungen: v_ref1 = -0.22 und v_ref1=-0.97, hier ist sicherlich die erste gewollt, die zweite würde uns durch die wand treiben^^

jetzt v_ref2 = v_ref1 + 1.2 -> v_ref2 = 0.98

v_ref(-0.22, 0.98)

soo, das wäre der reflektierte vektor(normiert auf abs(v_ref) = 1). Aber ob das performant genug ist? ich würd sagen, das dauert ne weile und ist recht komplex umzusetzten, wenns "nur" als kollisionsabfrage dienen soll... vor allem, weil man in nem automatisierten programm dann bei der auswahl von v_ref1 nochmal kontrolieren muss, welcher von beiden vektoren durch die wand geht und welcher nicht...


Den letzten teil schauen wir später an.
is nurnoch lösen des gleichungssystems. die späteren lösungen kann man dann entweder mit p/q formel oder quadratischer ergänzung berechnen. letzteres kann ich nicht, deshalb nur p/q formel.

bin jetzt btw arbeiten, kann erst heute abend nochmal reingucken.

Multithread
30.06.2013, 17:04
kann gut sein, musste gucken, als was dir die acos funktion den winkel gibt. bin jetzt von grad ausgegangen, aber das rechnet sich gleich, wenn alle funktionen bogenmaß nehmen.

Mal schauen, code ist wieder etwas länger geworden:

double skalarprodukt = (double)(alteRichtung.X * abprallwand.X + alteRichtung.Y * abprallwand.Y);
double absMultiplikation = Math.Sqrt((double)(alteRichtung.X * alteRichtung.X + alteRichtung.Y * alteRichtung.Y));
absMultiplikation *= Math.Sqrt((double)(abprallwand.X * abprallwand.X + abprallwand.Y * abprallwand.Y));
double wert = Math.Acos(skalarprodukt / absMultiplikation);

double einsPunktZwei = Math.Sqrt((double)(abprallwand.X * abprallwand.X + abprallwand.Y * abprallwand.Y)) * Math.Cos(wert * 180 / Math.PI);





b ist die wand, ja.

die werte brauchst du meine ich später nichtmehr.
v_ref ist der bewegungsvektor nach der kollision, ja.

Gut:)



b1*v_ref1 + b2*v_ref2 = 1.2
b1 = -1 ; b2 = 1
-> -v_ref1 + v_ref2 = 1.2.
-> v_ref2 = 1.2 + v_ref1
außerdem: sqrt(v_ref1² + v_ref2²) = 1
da setzt man für v_ref2 ein:
1 = sqrt(v_ref1² + (v_ref1+1.2)²)
quadrieren:
1= v_ref1² + (v_ref1+1-2)²


So, jetzt den teil.
Wenn ich das richtig sehe, brauche ich den teil:

-> v_ref2 = 1.2 + v_ref1

Woher kommen da die 1.2?

und den


1= v_ref1² + (v_ref1+1-2)²

de verstehe ich sogar, abgesehen davon, wo die +1-2 herkommen.




wo siehst du da b = 1/1? das b1 = -1 und b2 = 1 sind nur die werte für b, die ich für die rechnung angenommen habe.

können wir nun also reale werte annehmen?
b1 (b.X) = 8
b2 (b.Y) = 31




ansich ist das einfach nur umformen. ich geh von beiden formeln fürs skalarprodukt aus, und hab dann halt ein gleichungssystem. (eine gleichung ist der betrag vom reflekttierten vektor (definiert als 1), die zweite halt die gleichungen fürs skalarprodukt.


is nurnoch lösen des gleichungssystems. die späteren lösungen kann man dann entweder mit p/q formel oder quadratischer ergänzung berechnen. letzteres kann ich nicht, deshalb nur p/q formel.

bin jetzt btw arbeiten, kann erst heute abend nochmal reingucken.
Gibt das da Bibliotheken zum lösen solch eines Gleichungssystems?
Oder muss ich da selber 'raten' was passen könnte?

Daepilin
30.06.2013, 18:06
obs da bibs gibt keine ahnung, raten muss man aber nicht, die p/q formel lässt sich so wie sie ist problemlos umsetzten in code.

die 1.2 kommt als ergebnis da raus, wenn du abs(b)*abs(v_ref)*cos(30°) rechnest. den betrag von v_ref haben wir als eins angenommen, abs(b) ist 1.4 und cos(30°) = 0.87, das ergibt die 1.2

die 1-2 ist n tippfehler udn soll 1.2 heißen

versteh erstmal die ganze rechnung, bevor du da andere werte einsetzt :)

Multithread
01.07.2013, 17:57
obs da bibs gibt keine ahnung, raten muss man aber nicht, die p/q formel lässt sich so wie sie ist problemlos umsetzten in code.

die 1.2 kommt als ergebnis da raus, wenn du abs(b)*abs(v_ref)*cos(30°) rechnest. den betrag von v_ref haben wir als eins angenommen, abs(b) ist 1.4 und cos(30°) = 0.87, das ergibt die 1.2

die 1-2 ist n tippfehler udn soll 1.2 heißen

versteh erstmal die ganze rechnung, bevor du da andere werte einsetzt :)
Dann wollen wir doch mal:
Mit den Variablennamen aus meinem Programm

b1*v_ref1 + b2*v_ref2 = 1.2
b1 = -1 ; b2 = 1
-> -v_ref1 + v_ref2 = 1.2.
-> neueRichtung.Y = einsPunktZwei + neueRichtung.X


1= neueRichtung.Y² + (neueRichtung.X+1.2)²


Damit habe ich zwei Gleichungen, die kann ich doch jetzt irgendwie so zusammenzupressen das es eine gibt:D
Oder kann ich für neueRichtung.Y einfach 1 annehmen solange wie neueRichtung.X nicht Richtung unendlich geht?

Daepilin
01.07.2013, 18:10
ja, du hast zwei gleichungen und kannst die jetzt zusammenwurschteln, bis du auf dein ergebnis kommst.

(hab ich aber oben angegeben :P )

wär dann einmal neueRichtung.y = 1.2 + neueRichtung.x
bzw: 1 = sqrt(neueRichtung.X² + neueRichtung.X²)

da setzt man ersteres ein:

1 = sqrt(neueRichtung.x² + (1.2 + neueRichtung.X)²)
1 = neueRichtung.x² + neueRichtung.x² + 2.4neueRichtung.x + 1.44
0 = 2*neueRichtung.x² + 2.4*neueRichtung.X + 0.44
0 = neueRichtung.x² + 1.2neueRichtung.x + 0.22

Das ganze as said mit p/q formel oder quadratischer ergänzung lösen udn fast fertig.

mit p/q formel wäre das:

p = 1.2 (koeffizient vor neueRichtung.x) und q = 0.22

wichtig: vor dem neueRichtung.x² darf nur eine 1 stehen, nichts anderes, das muss dann entsprechend umgeformt werden!

einsetzten x = (-p/2) +- sqrt((p/2)²-q), lösen, und fertig.

gibt dann 0 bis 2 Ergebnisse (sofern die wurzel negativ wird gibts garkeine reellen ergebnisse mehr udn die imaginären interessieren hier nicht).

wenn es 0 sind: mist (§ugly)
wenn es 1 ist: super
wenn es 2 sind musst du rausfinden, welches von beiden das gewünschte ist, einer wird durch die wand gehen (falsch), einer nicht (richtig)

dann nochmal einsetzten in neueRichtung.y = neueRichtung.x + 1.2 und fertig^^

Multithread
01.07.2013, 20:31
Also: soweit habe ich alles verstanden, da sind auch keine abs() oä. drin:D

Alerdings: Wie kann ich das in C# umsetzten und automatisch ausrechnen lassen, geht das nur über probieren?
oder doch mit meiner Variante das ich einfach mal x als 1 annehme und schaue ob es geht?

Daepilin
01.07.2013, 20:46
hab ich das vergessen zu schreiben (§ugly) das geht nicht so einfach, da du dadurch den betrag änderst, den du aber als bekannt angenommen has um die beziehung von x zu y zu bestimmen.

das ganze sollte sich ansich in c# umsetzten lassen, es ändern sich ja immer nur koeffizienten(variablen), die rechenschritte (und positionen von x und y) bleiben ja ansich immer gleich.

die x und y würde ich da vrmtl. einfach überall rauslassen, du willst ja nur die koeffizienten bestimmen, um x und y kümmerst du dich ja erst ganz am ende. du musst halt dann gucken, viele der zwischenschritte und umformungen kannst du dir dabei dann sparen.
p und q lassen sich, wenn man die mathematik einfach ignoriert (:ugly:) einfacher bestimmen, hängen aber von b1 und b2 ab.

mal schaun, vlt finde ich morgen zeit mal zu gucken, ob ich da ne beziehung finde, die du einfach einsetzten kannst.

kannste ja sonst auch mal durchgucken. durch die werte von b ändert sich ja die urpsrüngliche beziehung (hier v_ref2 = v_ref1 + 1.2), bzw die koeffizienten und vorzeichen von v_ref1 und 2.

kannst ja mal gucken, wie sich das je durch die rechnung fortsetzt bzw dann auf die nullstellengleichung ( 0 = x² + 1.2x + 0.22) auswirkt.

dann einfach p und q entsprechrend wählen und fertig.

Multithread
01.07.2013, 20:53
hab ich das vergessen zu schreiben (§ugly) das geht nicht so einfach, da du dadurch den betrag änderst, den du aber als bekannt angenommen has um die beziehung von x zu y zu bestimmen.

das ganze sollte sich ansich in c# umsetzten lassen, es ändern sich ja immer nur koeffizienten(variablen), die rechenschritte (und positionen von x und y) bleiben ja ansich immer gleich.
Dann kann ich also im Grunde den rechenweg, bis auf eine kleinigkeit weglassen:


1 = sqrt(neueRichtung.x² + (1.2 + neueRichtung.X)²)
1 = neueRichtung.x² + neueRichtung.x² + 2.4neueRichtung.x + 1.44 |-1
0 = 2*neueRichtung.x² + 2.4*neueRichtung.X + 0.44
die 1.2 muss ich noch umrechnen und die 0.44 erhalten, woraus entstehen die eigentlich? aus nem minus 1?

bleibt das Resultat:

0 = neueRichtung.x² + 1.2neueRichtung.x + 0.22

Das per probieren herausfinden, bzw. die Resultate davon?
Die Suchrichtung kann man ja grob durch den Gegenstandsmittelpunkt zum Abprallpunkt herausfinden, also der Abprallwand.
Dann habe ich auch schon die Ergebnisse weg, wo durch die Wand ginge.


neueRichtung.y = neueRichtung.x + 1.2
Das habe ich sogar verstanden:D

Daepilin
01.07.2013, 20:59
fast, habs jetzt nich gelesen, aber ich hab meinen post oben etwas editiert, während du geschrieben hast^^ hab das jetzt erklärt^^

e: die quadratische gleichung musst du nicht durch ausprobieren lösen, du kannst einfach p udn q einsetzten und x1 und x2 bestimmen^^ also einmal die formel mit + sqrt... und einmal mit -sqrt...

dazu jeweils überprüfen, ob da unter der wurzel auch nicht 0 rauskommt und feddich^^

Sergej Petrow
01.07.2013, 22:51
Gibt es da nicht schon vorgefertigte Funktionen für. Also beispielsweise ob ein Punkt innerhalb eines Viereckts liegt oder nicht.

Bei Java wäre das beispielsweise wenn es um ein Viereck geht Rectangle.contains(int x, int y).
Da gibt es noch zahlreiche andere Funktionen zu, beispielsweise ob es ein anderes Viereck berührt oder eine Gerade.

Multithread
02.07.2013, 07:34
hab ich das vergessen zu schreiben (§ugly) das geht nicht so einfach, da du dadurch den betrag änderst, den du aber als bekannt angenommen has um die beziehung von x zu y zu bestimmen.

das ganze sollte sich ansich in c# umsetzten lassen, es ändern sich ja immer nur koeffizienten(variablen), die rechenschritte (und positionen von x und y) bleiben ja ansich immer gleich.

die x und y würde ich da vrmtl. einfach überall rauslassen, du willst ja nur die koeffizienten bestimmen, um x und y kümmerst du dich ja erst ganz am ende. du musst halt dann gucken, viele der zwischenschritte und umformungen kannst du dir dabei dann sparen.
p und q lassen sich, wenn man die mathematik einfach ignoriert (:ugly:) einfacher bestimmen, hängen aber von b1 und b2 ab.

mal schaun, vlt finde ich morgen zeit mal zu gucken, ob ich da ne beziehung finde, die du einfach einsetzten kannst.

kannste ja sonst auch mal durchgucken. durch die werte von b ändert sich ja die urpsrüngliche beziehung (hier v_ref2 = v_ref1 + 1.2), bzw die koeffizienten und vorzeichen von v_ref1 und 2.

kannst ja mal gucken, wie sich das je durch die rechnung fortsetzt bzw dann auf die nullstellengleichung ( 0 = x² + 1.2x + 0.22) auswirkt.

dann einfach p und q entsprechrend wählen und fertig.
klingt ..... einfach?§ugly
Wie soll ich das mit den Rechenschritten in C# machen? Dafür wäre mit keine Bibliothek bekannt, und das ganze per Wolfram Alpha zu machen, ist viel zu langsam.

Was ist die p/q Formel? Der name sagt mir nichts.

Was weiss ich:
Abs(neueRichtung) = 1
abs(abprallwand)*cos(Aufprallwinkel) = einsPunktZwei

Dann noch von Irgendwoher:
neueRichtung.y = 1.2 + neueRichtung.x
1 = sqrt(neueRichtung.X² + neueRichtung.X²) -> 0 = neueRichtung.x² + 1.2neueRichtung.x + 0.22 Dieses ganze umformen, wie kann ich das Automatisieren?
Der erste Wert (1.2*neueRichtugn.X) entspricht ja einsPuntkZwei.
Der zweite wert (das +0.22) entspricht dann: (einsPunktZwei2-1)/2
wenn ich das richtig sehe.
Dann habe ich eine Gleichung mit einer Unbekannten, jetzt schlägst du mir also vor, das die Lösung:
p/q ist?
also: neueRichtung.X = einsPunktZwei/der Zweite wert (aka. 0.22)?





Vektor abprallwand = resolveSkalar(senkrechte);

double skalarprodukt = (double)(alteRichtung.X * abprallwand.X + alteRichtung.Y * abprallwand.Y);
double absMultiplikation = Math.Sqrt((double)(alteRichtung.X * alteRichtung.X + alteRichtung.Y * alteRichtung.Y));
absMultiplikation *= Math.Sqrt((double)(abprallwand.X * abprallwand.X + abprallwand.Y * abprallwand.Y));
double wert = Math.Acos(skalarprodukt / absMultiplikation);

double einsPunktZwei = Math.Sqrt((double)(abprallwand.X * abprallwand.X + abprallwand.Y * abprallwand.Y)) * Math.Cos(wert * 180 / Math.PI);

//neueRichtung.y = 1.2 + neueRichtung.x
//1 = sqrt(neueRichtung.X² + neueRichtung.X²)
//abs(neueRichtung) = 1 (Math.Sqrt((double)(neueRichtung.X * neueRichtung.X + neueRichtung.Y * neueRichtung.Y)))



fast, habs jetzt nich gelesen, aber ich hab meinen post oben etwas editiert, während du geschrieben hast^^ hab das jetzt erklärt^^

e: die quadratische gleichung musst du nicht durch ausprobieren lösen, du kannst einfach p udn q einsetzten und x1 und x2 bestimmen^^ also einmal die formel mit + sqrt... und einmal mit -sqrt...

dazu jeweils überprüfen, ob da unter der wurzel auch nicht 0 rauskommt und feddich^^
Ok, Hinweis zur Kenntnis genommen, das brauche ich später demnach noch.


Gibt es da nicht schon vorgefertigte Funktionen für. Also beispielsweise ob ein Punkt innerhalb eines Viereckts liegt oder nicht.

Bei Java wäre das beispielsweise wenn es um ein Viereck geht Rectangle.contains(int x, int y).
Da gibt es noch zahlreiche andere Funktionen zu, beispielsweise ob es ein anderes Viereck berührt oder eine Gerade.
Wenn es so einfach wäre. Vielleicht kennst du noch mein ToE, da habe ich genau das verwendet, absolut kein Problem. Das hier ist schon was ganz anderes und um ein vielfaches Komplexer (wenn man nicht mal die Grundschematik versteht zumindest).

Daepilin
02.07.2013, 15:47
nein, nicht p/q, p/q formel, hab ich auch garantiert schon in einem meiner posts stehen...

x=(-p/2)+-sqrt((p/2)²-q)
eine lösung für +sqrt... und eine für - sqrt...

rest guck ich mir nachher/morgen an, bin erstmal feddich und hab nach 8h uni wenig bock auf nochmehr formeln :/

deine erste annahme ist fürs allgemeine so aber nicht ganz richti, richtig wäre es b2*neueRichtung.y = abs(b)*cos(alpha)-b1*neueRcihtung.x

Multithread
04.07.2013, 15:25
Ich habe nun endlich etwas verstanden und das ganze auch umgesetzt:
Mein Code bezüglich berechnung:

Vektor abprallwand = resolveSkalar(senkrechte);

double skalarprodukt = (double)(alteRichtung.X * abprallwand.X + alteRichtung.Y * abprallwand.Y);
double absMultiplikation = Math.Sqrt((double)(alteRichtung.X * alteRichtung.X + alteRichtung.Y * alteRichtung.Y));
absMultiplikation *= Math.Sqrt((double)(abprallwand.X * abprallwand.X + abprallwand.Y * abprallwand.Y));
double wert = Math.Acos(skalarprodukt / absMultiplikation);

double p = Math.Sqrt((double)(abprallwand.X * abprallwand.X + abprallwand.Y * abprallwand.Y)) * Math.Cos(wert * 180 / Math.PI);
double q = (((p * p) - 1) / 2);

double wurzel = (p / 2.0d) * (p / 2.0d) - q;

if (wurzel == 0)
{
return new Vektor();
}
else if (wurzel < 0)
{
return new Vektor();
}
wurzel = Math.Sqrt(wurzel);
double x1 = (-p / 2.0d) - wurzel;
double x2 = (-p / 2.0d) + wurzel;

x1 und x2, welcher wert von meiner abprallrichtung ist das nun? bzw. was ist der andere?

Ausserdem hat es wohl noch nen Rechenfehler drin, ich habe extrem oft ein negatives Ergebniss innerhalb der Wurzel:(

Ausserdem bin ich mir nicht sicher, ob das erstellen der abprallwand korrekt ist, aber das werde ich wohl noch alsbald merken.

private Vektor resolveSkalar(Vektor senkrechte)
{
decimal x = 0;
decimal y = 0;
if (senkrechte.X == 0.0M)
{
x = senkrechte.Y;
}
else if (senkrechte.Y == 0.0M)
{
y = senkrechte.X;
}
else
{
x = senkrechte.X;
y = -senkrechte.Y;
}

return new Vektor(x, y);
}

Danke für deine Bisherige Geduld, ich hoffe doch das es bald geschaft ist§wink

Daepilin
05.07.2013, 21:50
sry, für die verzögerung, ich guck morgen vormittag mal drüber :)

Daepilin
06.07.2013, 09:30
ne, is so leider nich so ganz korrekt, hab dir das ganze mal aufgeschrieben.

e: ach fuu, scanner is nich installiert an dem pc... dann also nur die ergebnisse, alles is mir jetzt zum abtippen zu viel:

ausgangsbedingungen: Wand.x = -aufprallvektor.y
wand.y = aufprallvektor.x

dann: betrag(wand.x) = 1 setzen (also wand.x durch abs(wand.x) teilen, vorzeichen muss bleiben!, das ist der einzige grund wand.x mitzuschleifen)
wand.y muss dann natürlich auch dadurch geteilt werden.

dann hat man zwei gleichungen:

Wand.x*neueRichtung.x + wand.y*neuerichtung.y = abs(wand) * cos (alpha)
dabei: abs(wand)*cos(alpha) = c (spart schreibarbeit)

aus der gleichung folgt:

neueRichtung.y = (-wand.x*neueRichtung.x + c) / Wand.y

einsetzten in

1 =sqrt (neueRichtung.x² + neueRichtung.y²)

das ergibt: 1 = neueRichtung.x² + (neueRichtung.x²-2*c*wand.x*neueRichtung.x+c²)/wand.y²

jetzt überspringen wir ein paar schritte(sorry, is mir echt zuviel):

0 = neueRichtung.x²-((2*c*wand.x)/(1+wand.y²))*neueRichtung.x+(c²-wand.y²)/(1+wand.y²)

->
p= (-2*c*wand.x)/(1+wand.y²)

q= (c²-wand.y²)/(1+wand.y²)

das sind alles bekannte größen, kannst du also einfach einsetzten.

das ganze dann in die p/q formel einsetzten.

aus den ergebnissen baust du dann deine ergebnisvektoren:

du hast ja die beziehung: neueRichtung.y = (-wand.x*neueRichtung.x+c)/wand.y

damit bestimmst du neueRichtung.y

im "schlechten" fall hast du jetzt zwei vektoren neueRichtung.

Der richtige ist der, der mit deinem aufprallvektor einen winkel von 180°-2*alpha einschließt (übers skalarprodukt).

Multithread
06.07.2013, 13:19
Vektor Wand = new Vektor();
Wand.X = -alteRichtung.Y;
Wand.Y = alteRichtung.X;

Wand.X = Wand.X / Math.Abs(Wand.X);
Wand.Y = Wand.Y / Math.Abs(Wand.X);

double c = Math.Sqrt((double)(Wand.X * Wand.X + Wand.Y * Wand.Y)) * Math.Cos(wert * 180 / Math.PI);
q = (c * c - (double)(Wand.Y * Wand.Y)) / (1 + (double)(Wand.Y * Wand.Y));
p = (-2 * c * (double)Wand.X) / (1 + (double)(Wand.Y * Wand.Y));


double wurzel = (p / 2.0d) * (p / 2.0d) - q;
if (wurzel <= 0.0d)
{
return new Vektor();
}
wurzel = Math.Sqrt(wurzel);
double x1 = (-p / 2.0d) - wurzel;
double x2 = (-p / 2.0d) + wurzel;

Vektor neueRichtung = new Vektor();

neueRichtung.X = (decimal)x1;
neueRichtung.Y = (-Wand.X * neueRichtung.X + (decimal)c) / Wand.Y;
neueRichtung.X = (decimal)x2;
neueRichtung.Y = (-Wand.X * neueRichtung.X + (decimal)c) / Wand.Y;

:)

Welcher Wert ist dein aufprallvektor?
Ich habe jetzt mal die Bewegungsrichtung als diesen Wert genommen, scheint aber falsch zu sein.

Ausserdem hoffe ich, das ich jetzt alle Rechnungen da richtig geschrieben habe.

welcher der Beiden Abprallvektoren stimmt, werde ich wohl dann auch selber raus bekommen§wink.

Daepilin
06.07.2013, 21:50
1.) warum bin ich der einzige der dir hier hilft, hier können doch sicher mehr leute lineare algebra/analysis...
2): morgen, grad 10+h gearbeitet + nen kollegen verabschiedet (aka, das ein oder andre bierchen...), ich guck morgen drüber...

Sergej Petrow
06.07.2013, 22:13
1.) Bei mir läuft das Programm nicht. So ist es für mich nicht so gut nachvollziehbar, was sein muss und was nicht. So aus dem Bauch herraus würde ich beispielsweise hier gar nicht erst mit Vektoren arbeiten und zu kompliziert gedacht sieht es mir auch aus. Aber dazu müsste ich erstmal eine lauffähige Version haben, um mir selbst ein Bild machen zu können.

Daepilin
06.07.2013, 22:51
bei mir läufts auch nicht, seinen code guck ich mir kaum an, ich erklär nur das mathematische :dnuhr:

er wills halt mit vektoren und ich wüsste nicht, wie man das mit vektoren einfacher machen soll(bzw überhaupt einfacher/anders bei den anforderungen). Man könnte sicher die ein oder andere näherung machen, aber warum? die rechnungen die man so braucht sind für die cpu nicht so aufwändig.

Multithread
07.07.2013, 07:43
1.) Bei mir läuft das Programm nicht. So ist es für mich nicht so gut nachvollziehbar, was sein muss und was nicht. So aus dem Bauch herraus würde ich beispielsweise hier gar nicht erst mit Vektoren arbeiten und zu kompliziert gedacht sieht es mir auch aus. Aber dazu müsste ich erstmal eine lauffähige Version haben, um mir selbst ein Bild machen zu können.
Mit was würdest du denn Arbeiten?



er wills halt mit vektoren und ich wüsste nicht, wie man das mit vektoren einfacher machen soll(bzw überhaupt einfacher/anders bei den anforderungen). Man könnte sicher die ein oder andere näherung machen, aber warum? die rechnungen die man so braucht sind für die cpu nicht so aufwändig.
Inwiefern Läuft nicht? da gibts Verschiedene:
1) Code lässt sich nicht Kompilieren
2) Pfad in der game.ini welche auf der Gleichen Ordnerebene wie die Exe ist, ist Falsch.
3) Der Pfad beinhaltet Leerzeichen, damit hatte ich auch mal Probleme.

Ich habe jetzt nochmals eine Version gemacht und auf alles mögliche getestet, dort sollte auch das neue Kompilieren und Debuggen gehen.
2D_Game_Engine_Demo.zip (http://upload.worldofplayers.de/files9/VYPH2D_Game_Engine_Demo.zip)
Mit der Linken maustaste können weitere Hindernisse gesetzt werden und mit der Mittleren werden alle aktuellen Hindernisse gespeichert. Mit der rechten lassen sich Hindernisse rauslöschen.:gratz

Daepilin
07.07.2013, 09:34
einer deiner fehler: Du darfst natürlich wand.x nicht anpassen, bevor du wand.y damit berechnest ;) also erst wand.y berechnen, danach wand.x

aufprallvektor müsste der zwischen m und c (also mittelpunkt und kollisionspunkt sein. in der skizze der lilane meine ich), hab ich falsch benannt, sorry :gratz

rest sieht soweit richtig aus.

(hab jetzt nicht in den code geguckt, sondern nur in den ausschnitt den du als letztes gepostet hast)

Multithread
07.07.2013, 10:13
So: Es funktioniert, so langsam zumindest.
Jetzt muss ich wohl noch die Bewegungsgeschwidigkeit anpassen, wenn ich das Richtig gesehen habe.

Und eine Frage habe ich noch: Was mache ich Wenn Wand.X 0 ist?


Kannst du mir noch aufzeichnen wohin die Beiden Vektoren zeigen? Der 2te muss ja auch in einem bestimmten Winkel von Irgendwoher weggehen.


Vektor abprallwand = resolveSkalar(senkrechte);
double skalarprodukt = (double)(alteRichtung.X * abprallwand.X + alteRichtung.Y * abprallwand.Y);
double absMultiplikation = Math.Sqrt((double)(alteRichtung.X * alteRichtung.X + alteRichtung.Y * alteRichtung.Y));
absMultiplikation *= Math.Sqrt((double)(abprallwand.X * abprallwand.X + abprallwand.Y * abprallwand.Y));

Vektor Wand = new Vektor();
Wand.X = -senkrechte.Y;
Wand.Y = senkrechte.X;

if (Wand.X != 0)
{
Wand.Y = Wand.Y / Math.Abs(Wand.X);
Wand.X = Wand.X / Math.Abs(Wand.X);
}

double wert = Math.Acos(skalarprodukt / absMultiplikation);
double c = Math.Sqrt((double)(Wand.X * Wand.X + Wand.Y * Wand.Y)) * Math.Cos(wert * 180 / Math.PI);
double q = (c * c - (double)(Wand.Y * Wand.Y)) / (1 + (double)(Wand.Y * Wand.Y));
double p = (-2 * c * (double)Wand.X) / (1 + (double)(Wand.Y * Wand.Y));


double wurzel = (p / 2.0d) * (p / 2.0d) - q;
if (wurzel <= 0.0d)
{
return new Vektor();
}
wurzel = Math.Sqrt(wurzel);
double x1 = (-p / 2.0d) - wurzel;
double x2 = (-p / 2.0d) + wurzel;

Vektor neueRichtung = new Vektor();

neueRichtung.X = (decimal)x1;
neueRichtung.Y = (-Wand.X * neueRichtung.X + (decimal)c) / Wand.Y;
// return neueRichtung;
neueRichtung.X = (decimal)x2;
neueRichtung.Y = (-Wand.X * neueRichtung.X + (decimal)c) / Wand.Y;

return neueRichtung;


Tausend Dank^2^


E: Grad gesehen: ich muss auch Prüfen ob der Winkel nicht zu Flach weg geht, hatte von oben nen Aufprall, Abprall war aber fast senkrecht nach rechts.

Daepilin
07.07.2013, 10:35
bewegungsgeschwindigkeit erreichst du, indem du deinen neueRichtung vektor mit dem betrag vom alteRichtung vektor multiplizierst.

wand.x = 0 ist grad ne gute frage...
müsste aber (habs nur eben skizziert, nich berechnet) einfach die spiegelung vom alteRichtung als neueRichtugn ergeben.
heißt in dem fall: x wert bleibt gleich, y wert ändert das vorzeichen.
musst du dann durch ne if-clause abfragen, meine gleichungen klappen mit wand.x oder wand.y gleich 0 halt nicht^^(bei wand.y ist es das gleiche, nur, dass der y wert bleibt und der x-wert das vorzeichen dreht)


nja der eine(richtige) vektor geht halt auf der vorderseite der wand weiter, der falsche auf der rückseite.
http://upload.worldofplayers.de/files9/Uzn9qJSDGbbXOSUnbenannt.png

Multithread
07.07.2013, 11:11
bewegungsgeschwindigkeit erreichst du, indem du deinen neueRichtung vektor mit dem betrag vom alteRichtung vektor multiplizierst.

wand.x = 0 ist grad ne gute frage...
müsste aber (habs nur eben skizziert, nich berechnet) einfach die spiegelung vom alteRichtung als neueRichtugn ergeben.
heißt in dem fall: x wert bleibt gleich, y wert ändert das vorzeichen.
musst du dann durch ne if-clause abfragen, meine gleichungen klappen mit wand.x oder wand.y gleich 0 halt nicht^^(bei wand.y ist es das gleiche, nur, dass der y wert bleibt und der x-wert das vorzeichen dreht)


nja der eine(richtige) vektor geht halt auf der vorderseite der wand weiter, der falsche auf der rückseite.
http://upload.worldofplayers.de/files9/Uzn9qJSDGbbXOSUnbenannt.png
hmmm.

Was im Falle Wand.X=0 mache:

Wand.Y = -Wand.Y;

das sollte klappen:D

Klappt so weit, jetzt muss ich nur noch die anderen Dinge Testen, sowie welcher der Beiden Vektoren richtig ist, bisher ist es aber immer der 2te.

jabu
07.07.2013, 17:34
1.) warum bin ich der einzige der dir hier hilft, hier können doch sicher mehr leute lineare algebra/analysis...
Das hat sicher etwas damit zu tun:

Nach elendig langem Gefrickel hatte ich irgendwann das mit den Pfaden rausbekommen. Zu den DLLs fehlt der Code, was schon mal bei dem einen oder anderen gar nicht gut ankommt. Dann gab es immer gewisse Diskrepanzen zwischen dem hier diskutierten Fortschritt und dem heruntergeladenen Code. Dann fehlt fast jegliche Dokumentation. Variablen sprechen falsch für sich selbst oder gar nicht, insbesondere in dem hier im Forum diskutierten Code.

Nun habt Ihr nicht einmal geklärt, was Ihr überhaupt wollt. Daepilin reißt sich ein Bein aus, um mit dem Chaos (nicht böse gemeint, sorry Lara ;)) fertigzuwerden. Und Lara packt Code mit Fallunterscheidungen für Spezialfälle da mit rein, welcher alles kaputtfiltert, was Daepilin sich überlegt hatte. So ist das kein Wunder.

Ich habe seit etwa einer Woche eine Herleitung für den allgemeinen Fall eines Abprallens auf einem Schmierzettel liegen, welcher komplett ohne Winkelfunktionen und damit auch ohne Fallunterscheidungen auskommt. Es ist nicht einmal eine Wurzel da drin. Das wollte ich auch alles schon einmal posten, hatte einen länglichen Beitrag verfasst und verworfen, weil es mir nicht gelang, auf alle Eventualitäten, was Lara mit seinem Code wohl meinen könnte, einzugehen.

Solange Daepilin allgemeine Fälle behandelt und Lara immer wieder nur senkrechte bzw. waagerechte Wände behandelt sehe ich nicht einmal eine Definition einer Problemstellung, sondern nur einen Wust aus Winkelfunktionen, der in Laras Code auch noch Fehler beinhaltet und dann eingepfropfte Spezialfallbehandlung für winklige Wände. Das tut sich niemand freiwillig an, außer dem unendlich geduldigen Daepilin.

Entweder, es geht um Spezialfälle, dann kann man sich sämtlichen Mathe-Foo sparen. Das praktiziert Lara die ganze Zeit. Trotzdem fragt er immer wieder, was wenn die x-Komponente Null ist. Die Frage ist schon unsinnig, weil sie es per Definition ist, einmal eben x=0 und einmal y=0. Für alle anderen Fälle ist Laras Ansatz funktional kaputt. Entweder es geht um winklige Wände oder um den allgemeinen Fall, nicht beides und dann mit einer Fallunterscheidung, höchstens wegen der Performance, aber dann muss er das sagen, das es ihm darum geht. Dann würde ich aber erst mal den allgemeinen Fall fertigmachen.

Und glaubt mir, dass die ganzen Winkelfunktionen für dieses triviale Problem unnötig sind, außerdem sind sie nicht eineindeutig. Sergej Petrow liegt ganz richtig mit seinen einwürfen.

So, das war jetzt etwas krass von mir, ist aber durchweg gut gemeint. Zuerst muss Lara mitteilen, was er will. Ich bin zwar auch kein Mathe-Freak, aber die Arbeitsweise scheint mir hier das größte Problem zu sein.

Und bevor Ihr irgendwas mit x und y macht, definiert bitte verbindlich Euer Koordinatensystem! Was ist x, was ist y? Damit fängt es schon an. Dann können wir weitersehen.


To do:

Allgemein:

Anforderungen klar definieren
Koordinatensystem projektweit definieren, x bleibt x, egal wo!


Im Quellcode:

Quellcode vervollständigen
Pfade korrigieren, ansonsten exaktes Schema vorgeben
Sprechende Namen für Bezeichner und Kommentare (dokumentieren)!


Im Forum:

Anforderungen an Codeschnipsel im Forum formulieren
Randbedingungen dazu angeben
Quellcode im Forum durch sprechende Namen und Kommentare dokumentieren ("resolveSkalar" ist grob irreführend und wäre eher etwas für einen obfuscated code contest als für Problemlösungen geeignet usw.)
...

Daepilin
07.07.2013, 18:01
beim koordinatensystem gehen wir denke ich beide standardmäßig schon vom gleichen aus, was halt von quasi jeder engine verwendet wird.

bei den anforderungen war meine ich mal irgendwas, dass lara meinte, er bräuchte da was allgemeineres als senkrechte/waagerechte wände, das hat sich ja irgendwie geformt, aus den problemen hier, hilfsansätzen im pc OT und aus dem gespräch hier.

Klar, wenn er nur senkrechte/waagerechte wände hat, kann man sich den ganzen mathe-murks sparen und spiegelt einfach den einfallsvektor.

glaub du bist da eher "professionelleres" arbeiten gewöhnt^^

jabu
07.07.2013, 18:03
Was im Falle Wand.X=0 mache:
Ist x wagerecht? Wie ist dein Koordinatensystem definiert (sonst wird dir hier niemand sagen können, ob du richtig liegst)?

In dem Bild ist Wand.X=0, wenn x waagerecht ist. Also tun wir mal so, als ob das stimmt:


Wand.Y = -Wand.Y;
Nein, die Y-Richtung wird beibehalten, und Wand ändert sich gar nicht.

meinNeuerVektor.X = -MeinAlterVektor.X;
meinNeuerVektor.Y = MeinAlterVektor.Y;


das sollte klappen:D
Nein.


Klappt so weit,
Nein, kann es nicht, außer durch Zufall bzw. Probieren, wenn sich mehrere Fehler gegenseitig aufheben.


jetzt muss ich nur noch die anderen Dinge Testen, sowie welcher der Beiden Vektoren richtig ist, bisher ist es aber immer der 2te.
Nein, du brauchst erst einmal ein Konzept.


E: Grad gesehen: ich muss auch Prüfen ob der Winkel nicht zu Flach weg geht, hatte von oben nen Aufprall, Abprall war aber fast senkrecht nach rechts.
Nein, Spezialwinkel gibt es nicht. Wenn die Berechnungen stimmen, passiert das nicht, also nicht wieder eine Spezialprüfung einbauen.

Multithread
07.07.2013, 18:41
Ist x wagerecht? Wie ist dein Koordinatensystem definiert (sonst wird dir hier niemand sagen können, ob du richtig liegst)?

Das Koordiantensystem entspricht dem womit Windows die Pixel auf dem Bildschirm Definitiert. X ist 0 wenn der Char gerade von Oben runter fällt, oder gerade von Unten nach oben, geht beides:D



In dem Bild ist Wand.X=0, wenn x waagerecht ist. Also tun wir mal so, als ob das stimmt:


Nein, die Y-Richtung wird beibehalten, und Wand ändert sich gar nicht.

meinNeuerVektor.X = -MeinAlterVektor.X;
meinNeuerVektor.Y = MeinAlterVektor.Y;

hmm, demnach so:

Wand.X = Wand.Y;
Wand.Y = 0;

?
hmm, ich muss aschauen, bisher funktioniert es auf jede Ar:C:





Nein, kann es nicht, außer durch Zufall bzw. Probieren, wenn sich mehrere Fehler gegenseitig aufheben.

Mir relativ egal, solange es geht;)
Ich weiss nicht woran du Programmierst, aber ich habe im Letzten Jahr praktisch nur Fehler gejagt und kaum was Selber Pogrammiert, sowas hinterlässt Spuren bei so nem jungen Coder;)




Nein, du brauchst erst einmal ein Konzept.


ein Konzept ist schon vorhanden, aber nirgendwo niedergeschrieben, eben so ein richtig beschissenes One Man Projekt.
Ich hätte auch nicht erwartet auf solch ein problem zu stossen.




Nein, Spezialwinkel gibt es nicht. Wenn die Berechnungen stimmen, passiert das nicht, also nicht wieder eine Spezialprüfung einbauen.
keine sorge, das liegt an den Trennwänden zwischen zwei blöcken, die fliessen aktuell auch noch in die Abprallwand mit ein, diese müssen aber noch raus, zb. nach dem laden aller Blöcke.
Daran arbeite ich gerade.



Das am Anfang vieles Unklar war, tut mir leid.
Dennoch habe ich versucht alles zu liefern nach dem ich Gefragt wurde, also zb: Kommentierung des Codes, und jetzt am ende noch ne neue Version wo das Debugging gehen sollte, hätte ich das eher gewusst, hätte ich das auch eher machen können.

PS: könntest du noch kurz erklären wie das Ohne Winkel und Vektoren gehen soll?

jabu
07.07.2013, 19:26
beim koordinatensystem gehen wir denke ich beide standardmäßig schon vom gleichen aus, was halt von quasi jeder engine verwendet wird.
Mit solchen Annahmen wird man irgendwann Schiffbruch erleiden ;), in einem Forum erst recht, wo es eher unwahrscheinlich ist, dass sich jeder durch inkonsistenten Wust hindurcharbeitet. Wenn der Code korrekt wäre, könnte man einfach Annahmen machen, wenn er das nicht ist, muss man beide undefinierte Varianten immer mittransportieren, genauso bei all den anderen Variablen, was quadrillionen Möglichkeiten ergibt, wenn man einen Fehler sucht. Das ganze krankt an der Arbeitsweise, nicht an dem bisschen Mathe. Und es fängt eben mit so trivialen Dingen an, wie man sein Koordinatensystem definiert, die Mathematik ist da flexibel. Also soll x jetzt waagerecht sein?

Das Problem wird nämlich umso größer, wenn im Code ein Vektor um 90° gedreht wird bzw. eine Senkrechte errichtet wird. Er macht aus einem Vektor "senkrechte" also einen Vektor "abprallwand" per einer ominösen Funktion "resolveSkalar", die weder einen Skalar behandelt, noch einen erzeugt, noch etwas aus einem ableitet. Da geht ein Vektor rein und einer raus, und nachher ist er irgendwie verdreht. Ob er aber richtig herum "verdreht" ist, weiß man erst, wenn es eine Dokumentation zu der Funktion gibt. Es handelt sich um eine Art Filterfunktion, die mal so und mal so den Vektor manipuliert, aber die Information ist am Ende verloren. Für so etwas muss es einen verdammt triftigen Grund geben, der dann dokumentiert werden muss. Die Winkelfunktionen, lässt er trotzdem noch darauf los. Aber diese Funktionen müssten schon falsch sein, wenn sie bei bestimmten Winkeln plötzlich nicht gültig wären und eines Verdrehens bedürften. Das ist etwa so, als ob man bei der Addition zweier Zahlen eine Fallunterscheidung treffen und manchmal eins hinzuzählen müsste, damit es stimmt. Das ist natürlich völlig unsinnig.

Soll "senkrechte" ein Normalenvektor auf der Wand sein, sodass "abprallwand" wieder genauso wie die echte Abprallwand orientiert ist? Man weiß es nicht. Es folgen ja keine durchweg korrekten Berechnungen, weswegen man das nicht mit Sicherheit von hinten her schließen kann. Er muss schon formulieren, was er will, dann macht er sich die Sache enorm leichter. Softwareentwicklung bedeutet erst mal Verstehen und Formulieren. Das Coden kommt zum Schluss, und eigentlich muss man das gar nicht können, um es mal auf die Spitze zu treiben.

IMO feht eine Analyse über die fehlende Eineindeutigkeit der Winkelfunktionen und den damit einhergehenden Informationsverlust.

Ebenso:

double wert = Math.Acos(skalarprodukt / absMultiplikation);
... Math.Cos(wert * 180 / Math.PI);

Benenne "wert" sowie "absMultiplikation" aussagekräftig. Das erspart das Lesen vieler Beiträge.

"wert" liegt lt. MSDN also im Bogenmaß im Interval von 0 ≤ θ ≤ π vor.
Außerdem sagt das MSDN, dass Math.Cos einen Winkel im Bogenmaß im Interval von 0 ≤ θ ≤ π nimmt.

Warum wird er dann vorher in Grad gewandelt?

Das nur als Beleg, dass sich der Code auch nicht rückwärts erschließt.


bei den anforderungen war meine ich mal irgendwas, dass lara meinte, er bräuchte da was allgemeineres als senkrechte/waagerechte wände, das hat sich ja irgendwie geformt, aus den problemen hier, hilfsansätzen im pc OT und aus dem gespräch hier.
Vielleicht kann er das nochmal verdeutlichen. Den Spezialfall kann er ja gerne behandeln, aber bevor der allgemeine Fall gelöst ist, macht es wenig Sinn, das zu vermischen. Irgendwann ist der Code so verdreht, dass sich alles andere danach richten muss.


Klar, wenn er nur senkrechte/waagerechte wände hat, kann man sich den ganzen mathe-murks sparen und spiegelt einfach den einfallsvektor.
Das ist ja genau das, was ich immer von ihm gelesen habe, dass er eben diese Lösung gefunden habe, wie das geht. Das war zwar meistens irgendwie verdreht, aber wenn er nochmal woanders etwas verdreht, mag das sogar hinkommen, will ihm da nicht Unrecht tun. Das Problem ist nur, dass die saubere Basis fehlt, um darauf aufzubauen. Wenn ich mehrmals bei den Spiegelungen etwas Falsches lese, muss ich doch davon ausgehen, dass er sein Koordinatensystem irgendwie anders definiert hat, wenn er dann sagt, es funktioniere bei ihm. Oder der Code ist irgendwo aus dem Kontext gerissen, in dem es dann wieder hinkommt, kann ja alles sein, aber den riechen wir nicht. ;) :)

Multithread
07.07.2013, 20:21
IMO feht eine Analyse über die fehlende Eineindeutigkeit der Winkelfunktionen und den damit einhergehenden Informationsverlust.

Ebenso:

double wert = Math.Acos(skalarprodukt / absMultiplikation);
... Math.Cos(wert * 180 / Math.PI);

Benenne "wert" sowie "absMultiplikation" aussagekräftig. Das erspart das Lesen vieler Beiträge.

"wert" liegt lt. MSDN also im Bogenmaß im Interval von 0 ≤ θ ≤ π vor.
Außerdem sagt das MSDN, dass Math.Cos einen Winkel im Bogenmaß im Interval von 0 ≤ θ ≤ π nimmt.

Warum wird er dann vorher in Grad gewandelt?

Das nur als Beleg, dass sich der Code auch nicht rückwärts erschließt.

Könntest du bitte auch mich Zitieren, wenn du mich meinst?

Das mit dem Bogenmass:
Das ganze klingt schlüssig, allerdings muss ich erst die Kollisionsrichtungsprüfung machen, ansonsten reagiert das Programm nicht nachvollziehbar genug.




Vielleicht kann er das nochmal verdeutlichen. Den Spezialfall kann er ja gerne behandeln, aber bevor der allgemeine Fall gelöst ist, macht es wenig Sinn, das zu vermischen. Irgendwann ist der Code so verdreht, dass sich alles andere danach richten muss.


Das ist ja genau das, was ich immer von ihm gelesen habe, dass er eben diese Lösung gefunden habe, wie das geht. Das war zwar meistens irgendwie verdreht, aber wenn er nochmal woanders etwas verdreht, mag das sogar hinkommen, will ihm da nicht Unrecht tun. Das Problem ist nur, dass die saubere Basis fehlt, um darauf aufzubauen. Wenn ich mehrmals bei den Spiegelungen etwas Falsches lese, muss ich doch davon ausgehen, dass er sein Koordinatensystem irgendwie anders definiert hat, wenn er dann sagt, es funktioniere bei ihm. Oder der Code ist irgendwo aus dem Kontext gerissen, in dem es dann wieder hinkommt, kann ja alles sein, aber den riechen wir nicht. ;) :)
Ich muss an einer Wand abprallen können, welche von 0,13 nach 24,11 geht. Sowie von jeder Wand die entsteht wenn man diese um beliebig viele Grad dreht.
Ich weiss nicht wie das als Anforderung ist, die mache ich normalerweise nicht.


Das ich den Spezialfall nicht vor dem Allgemeinen beachten soll, leuchtet mir ein.

Wo arbeitest du eigentlich, und als was genau? Du scheinst da ja durchaus vom Fach zu sein, was Anforderungen angeht.

Was das ganze Vektor und Kollisionszeugs angeht, habe ich bereits weiter vorne mal gepostet wie ich mich dabei Fühle:
http://24.media.tumblr.com/tumblr_m9e7rq9Xww1rel75xo1_1280.jpg
Mein Mathe Lehrer hielt Wahrscheindlichkeit für wichtiger als Vektoren und Trigonometrie:C:

jabu
07.07.2013, 20:37
Das Koordiantensystem entspricht dem womit Windows die Pixel auf dem Bildschirm Definitiert.
Du sprichst über eine uns unbekannte Library mit dem .NET-Framework und erwartest, dass wir alle Drehungen deines Codes sowie die Definitionen deines eigenen Ressourcenformates kennen... ;):D

Im Windows API ist die x-Richtung waagerecht. Alles andere obliegt den u. U. zwischengeschobenen Manipulationen^, die sich mit Sicherheit jeder erst mal gerne reinzieht. :rolleyes:


X ist 0 wenn der Char gerade von Oben runter fällt, oder gerade von Unten nach oben, geht beides:D
Gut, du meinst die Vektorkomponente, dann ist die x-Achse waagerecht. :)


hmm, demnach so:

Wand.X = Wand.Y;
Wand.Y = 0;

Warum willst du immer deinen Wand-Vektor manipulieren, ich denke, es ginge um den Vektor eines beweglichen Objektes, oder irre ich mich, kann ja sein. Außerdem hast du "Wand" nirgends definiert. Bevor du also nicht mitteilst, was genau der Vektor "Wand" beschreiben soll und welche Manipulation erwünscht ist, bleibt alles Schall und Rauch. Niemand kann etwas bestätigen oder falsifizieren.


Mir relativ egal, solange es geht;)
Du schriebst doch etwas von falschen Abprallwinkeln, oder irre ich mich?


Ich weiss nicht woran du Programmierst,
Im Momentan gar nichts, weil ich keine Zeit habe und schon vieles wieder vergessen habe. Früher habe ich mal einige Semester E-Technik genossen und auch eine kleine 3D-Engine mit DirectX in C++ entwickelt, aber nichts Besonderes, dafür aber zu Fuß, mit Transformationsmatrizen und so, ohne Fremdlibraries, alles zu Fuß. Auch einige Programmiersoftware für einen Datenbus über den Parallelport habe ich geschrieben, in C damals, aber auch nichts Wildes, schön mit grafischer Eingabemaske, ganz ohne .NET, sondern mit dem Windows-API, Message-Loop usw.

Aber das ist alles verdammt lange her. Wenn ich dürfte, würde ich ja gerne wieder. Aber der Alltag spannt mich in ein allzu enges Korsett. ;)


aber ich habe im Letzten Jahr praktisch nur Fehler gejagt und kaum was Selber Pogrammiert, sowas hinterlässt Spuren bei so nem jungen Coder;)
Das ist doch gut, es gibt kaum Besseres, als fremden Code zu studieren. Ich kann ja nicht so viel mit C# anfangen, ist aber eher ein ideologisches Problem. Das ist mir zu weit weg von der Maschine und zu proprietär.


ein Konzept ist schon vorhanden, aber nirgendwo niedergeschrieben, eben so ein richtig beschissenes One Man Projekt.
Ich hätte auch nicht erwartet auf solch ein problem zu stossen.
Wenich daran denke, wie oft ich damals etwas verworfen habe, kann ich das gut nachvollziehen...


keine sorge, das liegt an den Trennwänden zwischen zwei blöcken, die fliessen aktuell auch noch in die Abprallwand mit ein, diese müssen aber noch raus, zb. nach dem laden aller Blöcke.
Daran arbeite ich gerade.
Ach so.


Das am Anfang vieles Unklar war, tut mir leid.
Kein Problem, wollte dich nicht angehen, sondern nur helfen, wegen der Arbeitsweise, damit du mehr Resonanz erfährst. Darum geht es doch?


Dennoch habe ich versucht alles zu liefern nach dem ich Gefragt wurde, also zb: Kommentierung des Codes, und jetzt am ende noch ne neue Version wo das Debugging gehen sollte, hätte ich das eher gewusst, hätte ich das auch eher machen können.
Das sieht schon sehr viel besser aus, habe es gerade heruntergeladen und werde es mir noch ansehen, sobald ich Zeit habe, danke! :)
Allerdings diskutieren wir hier im Forum über Sachen, die so in deinem Code nicht drinstehen. Und wenn du dann sagst, dass es bei dir ginge, irritiert das schon gewaltig, musst du verstehen. ;)


PS: könntest du noch kurz erklären wie das Ohne Winkel und Vektoren gehen soll?
Schon mit Vektoren, aber ohne Winkelfunktionen, was die allgemeine Reflektion angeht und ohne Wurzeln, alles über die Vektorkomponenten mit den Grundrechenarten. Dabei verlierst du keine Information. Denn die fehlende Umkehrbarkeit mancher Winkelfunktionen bzw. -Operationen kann zu ganz schönen Schmerzen führen.

Gerne betätige ich mich als Moderator, bis du es dir selbst erarbeitet hast. Auf dem Silbertablett werde ich das allerdings nicht ausbreiten, dann lernst du ja nichts. :)

Wir definieren uns also ein rechtwinkliges, zweidimensionales Koordinatensystem, bei dem die x-Achse zunehmend von links nach rechts verläuft und die y-Achse senkrecht dazu mit zunehmenden Werten von unten nach oben. Das gilt für alle Vektoren. Wie du das auf den Bildschirm projezierst, kannst du zurechtbiegen, wie du es brauchst.

Dann stellen wir uns eine Wand vor, beliebig orientiert. Das ist ja Gegenstand von Daepilins überwiegenden Bemühungen hier. Das leistet dein Code hier im Forum noch nicht, musst du zugeben, und daher meine Kritik, weil es nicht sein kann.

Nun stellen wir uns einen Vektor vor, der in beliebiger Richtung zu dieser Wand orientiert ist.

Tipp 1: Der Ort ist egal, es geht nur um seine Reflektion an der Wand.
Tipp 2: Aufmalen hilft, aber bitte nicht so tun, als ob der Vektor die Wand berührt, das spielt keine Rolle!
Tipp 3: Wir brauchen eine Festlegung, um eine Spiegelachse zu definieren. Ich habe mit einer Senkrechten zu der Wand gearbeitet, dem sog. Einheitsnormalenvektor. Diesem kommt in der Computergrafik eine besondere Rolle zu, weil er ungemein praktisch ist. Bei statischen Objekten sollte er vorausberechnet und mit in der Resource gespeichert, ansonsten vorgeladen werden.

So, das waren die ersten Hinweise.

Daepilin
07.07.2013, 20:56
btw, die wand ist in meiner rechnung nur ein aspekt, weil ich halt die rechnung brauche.

Ich berechne da schon den finalen abprallvektor ;)

an den weg über einen normalenvektor hab ich allerdings auch nicht gedacht...

jabu
07.07.2013, 21:10
an den weg über einen normalenvektor hab ich allerdings auch nicht gedacht...
Mit kleinen Änderungen würde auch der Einheitsvektor genügen, welcher quasi in der Wandlinie drin liegt. Aber ich habe die Version als Einheits-Normalenvektor (senkrecht dazu) genommen, weil sich noch bei Kollisionsabfragen bzw. späteren Berechnungen seine enorme Nützlichkeit zeigen kann. Ausgewachsene 3D-Engines bauen enorm viel darauf auf und können diese Vektoren meistens im Debug-Modus anzeigen... Auch Sortieralgorithmen zum Rendern von Scenes bzw. zur Entscheidungsfindung, ob es sich um eine zu texturierende Vorder- oder eine auszulassende Rückseite (unsichtbar) handelt, verwenden diese. Auch Beleuchtungstechniken... :D

Multithread
07.07.2013, 21:20
Code aus Abprallen, der rest ist im letzten Codepacket sicher noch aktuell:

public Vektor abprallen(Gegenstand _g, List<Point> _wande, GravitationRichtung _richtung)
{
Point position = new Point(_g.X, _g.Y);
Vektor alteRichtung = _g.Bewegungsrichtung;
Vektor senkrechte = null;
Point kollisionPunkt = Point.Empty;

if (_wande.Count > 0)
{
long lx = 0;
long ly = 0;
foreach (Point _p in _wande)
{
lx += _p.X;
ly += _p.Y;
}
kollisionPunkt = (new Point((int)(lx / _wande.Count), (int)(ly / _wande.Count)));
senkrechte = new Vektor(position.X - kollisionPunkt.X, position.Y - kollisionPunkt.Y);
}

Vektor abprallwand = resolveSkalar(senkrechte);
double skalarprodukt = (double)(alteRichtung.X * abprallwand.X + alteRichtung.Y * abprallwand.Y);
double absMultiplikation = Math.Sqrt((double)(alteRichtung.X * alteRichtung.X + alteRichtung.Y * alteRichtung.Y));
absMultiplikation *= Math.Sqrt((double)(abprallwand.X * abprallwand.X + abprallwand.Y * abprallwand.Y));

Vektor Wand = new Vektor();
Wand.X = -senkrechte.Y;
Wand.Y = senkrechte.X;

if (Wand.X != 0)
{
Wand.Y = Wand.Y / Math.Abs(Wand.X);
Wand.X = Wand.X / Math.Abs(Wand.X);
}
else
{
//Wand.X = Wand.Y;
//Wand.Y = 0;
}

double wert = Math.Acos(skalarprodukt / absMultiplikation);
double c = Math.Sqrt((double)(Wand.X * Wand.X + Wand.Y * Wand.Y)) * Math.Cos(wert);
double q = (c * c - (double)(Wand.Y * Wand.Y)) / (1 + (double)(Wand.Y * Wand.Y));
double p = (-2 * c * (double)Wand.X) / (1 + (double)(Wand.Y * Wand.Y));


double wurzel = (p / 2.0d) * (p / 2.0d) - q;
if (wurzel <= 0.0d)
{
return new Vektor();
}
wurzel = Math.Sqrt(wurzel);
double x1 = (-p / 2.0d) - wurzel;
double x2 = (-p / 2.0d) + wurzel;

Vektor neueRichtung = new Vektor();

neueRichtung.X = (decimal)x1;
neueRichtung.Y = (-Wand.X * neueRichtung.X + (decimal)c) / Wand.Y;


// return neueRichtung;
neueRichtung.X = (decimal)x2;
neueRichtung.Y = (-Wand.X * neueRichtung.X + (decimal)c) / Wand.Y;

neueRichtung.Y = neueRichtung.Y * 10;
neueRichtung.X = neueRichtung.X * 10;

return neueRichtung;
}


Darauf nehme ich bezug, wenn ich etwas frage:)
_g kann alles sein, vom Ball, über einen NPC bis hin zum Spieler selber.



Du sprichst über eine uns unbekannte Library mit dem .NET-Framework und erwartest, dass wir alle Drehungen deines Codes sowie die Definitionen deines eigenen Ressourcenformates kennen... ;):D

Im Windows API ist die x-Richtung waagerecht. Alles andere obliegt den u. U. zwischengeschobenen Manipulationen^, die sich mit Sicherheit jeder erst mal gerne reinzieht. :rolleyes:


Gut, du meinst die Vektorkomponente, dann ist die x-Achse waagerecht. :)

Habs nach getestet, ja, X ist waagerecht.




Warum willst du immer deinen Wand-Vektor manipulieren, ich denke, es ginge um den Vektor eines beweglichen Objektes, oder irre ich mich, kann ja sein. Außerdem hast du "Wand" nirgends definiert. Bevor du also nicht mitteilst, was genau der Vektor "Wand" beschreiben soll und welche Manipulation erwünscht ist, bleibt alles Schall und Rauch. Niemand kann etwas bestätigen oder falsifizieren.


Du schriebst doch etwas von falschen Abprallwinkeln, oder irre ich mich?

Kann sein, ich weiss aber bis jetzt noch nicht wie man dem noch sagen kann. Abprallvektor?





Im Momentan gar nichts, weil ich keine Zeit habe und schon vieles wieder vergessen habe. Früher habe ich mal einige Semester E-Technik genossen und auch eine kleine 3D-Engine mit DirectX in C++ entwickelt, aber nichts Besonderes, dafür aber zu Fuß, mit Transformationsmatrizen und so, ohne Fremdlibraries, alles zu Fuß. Auch einige Programmiersoftware für einen Datenbus über den Parallelport habe ich geschrieben, in C damals, aber auch nichts Wildes, schön mit grafischer Eingabemaske, ganz ohne .NET, sondern mit dem Windows-API, Message-Loop usw.

Aber das ist alles verdammt lange her. Wenn ich dürfte, würde ich ja gerne wieder. Aber der Alltag spannt mich in ein allzu enges Korsett. ;)

Ok, das Gefühl kenne ich.
Aber sobald man weniger Programmiert, kommt das verlangen:D





Das ist doch gut, es gibt kaum Besseres, als fremden Code zu studieren. Ich kann ja nicht so viel mit C# anfangen, ist aber eher ein ideologisches Problem. Das ist mir zu weit weg von der Maschine und zu proprietär.

schon, aber ich durfte mir zuerst dir Probleme anschauen, an denen mein Chef, der schon gute 30 Jahre Programmiert, gescheitert ist§ugly




Wenich daran denke, wie oft ich damals etwas verworfen habe, kann ich das gut nachvollziehen...


Ach so.


Kein Problem, wollte dich nicht angehen, sondern nur helfen, wegen der Arbeitsweise, damit du mehr Resonanz erfährst. Darum geht es doch?

Absolut.
Wenn ich weiss, das ich was falsch mache, kann ich es versuchen beim nächsten mal von Anfang an Richtig zu machen.





Das sieht schon sehr viel besser aus, habe es gerade heruntergeladen und werde es mir noch ansehen, sobald ich Zeit habe, danke! :)
Allerdings diskutieren wir hier im Forum über Sachen, die so in deinem Code nicht drinstehen. Und wenn du dann sagst, dass es bei dir ginge, irritiert das schon gewaltig, musst du verstehen. ;)

Das es nicht drin stand, war definitiv mein Problem.
aber das aktuelle, entspricht fast meiner gesamten Code Bibliothek.
zb. die Thread Queue, habe ich vor gut 3 Jahren angefangen. Die hilft mir dabei, schnell mal was in nen anderen Thread auszulagern.
CoRG ist ebenfalls schon gute 2 Jahre alt, und doch werde ich beides wohl noch in 50 Jahren benutzen....




Schon mit Vektoren, aber ohne Winkelfunktionen, was die allgemeine Reflektion angeht und ohne Wurzeln, alles über die Vektorkomponenten mit den Grundrechenarten. Dabei verlierst du keine Information. Denn die fehlende Umkehrbarkeit mancher Winkelfunktionen bzw. -Operationen kann zu ganz schönen Schmerzen führen.

Gerne betätige ich mich als Moderator, bis du es dir selbst erarbeitet hast. Auf dem Silbertablett werde ich das allerdings nicht ausbreiten, dann lernst du ja nichts. :)

Ohne Winkelfunktionen§kratz
Einzige was mir da einfallen würde: Mann kann beide Vektoren verrechnen und daraus den abprallenden berechnen.

\\o//



Wir definieren uns also ein rechtwinkliges, zweidimensionales Koordinatensystem, bei dem die x-Achse zunehmend von links nach rechts verläuft und die y-Achse senkrecht dazu mit zunehmenden Werten von unten nach oben. Das gilt für alle Vektoren. Wie du das auf den Bildschirm projezierst, kannst du zurechtbiegen, wie du es brauchst.

Dann stellen wir uns eine Wand vor, beliebig orientiert. Das ist ja Gegenstand von Daepilins überwiegenden Bemühungen hier. Das leistet dein Code hier im Forum noch nicht, musst du zugeben, und daher meine Kritik, weil es nicht sein kann.


Deine Wand ist also im Grunde die aus dem Abprallpunkt berechnete Abprallwand?





Nun stellen wir uns einen Vektor vor, der in beliebiger Richtung zu dieser Wand orientiert ist.

Bewegugnsrichtung?!





Tipp 1: Der Ort ist egal, es geht nur um seine Reflektion an der Wand.
Tipp 2: Aufmalen hilft, aber bitte nicht so tun, als ob der Vektor die Wand berührt, das spielt keine Rolle!
Tipp 3: Wir brauchen eine Festlegung, um eine Spiegelachse zu definieren. Ich habe mit einer Senkrechten zu der Wand gearbeitet, dem sog. Einheitsnormalenvektor. Diesem kommt in der Computergrafik eine besondere Rolle zu, weil er ungemein praktisch ist. Bei statischen Objekten sollte er vorausberechnet und mit in der Resource gespeichert, ansonsten vorgeladen werden.

So, das waren die ersten Hinweise.
Wie oben erwähnt: Ich denke man könnte noch die beiden Vektoren irgendwie miteinander verrechnen, sofern man beide zuerst auf Gesamtlänge 1 streckt.


E: normalvvektor? Muss google fragen, ich habe nicht mal die hälfte verstanden was ihr da ausgetauscht habt....

jabu
08.07.2013, 00:13
Sorry, wenn ich momentan etwas schreibfaul beim Zitieren, insbesondere bei Schachtelungen bin, kommt vom Stress, ist sonst nicht meine Art, für heute bleibe ich mal faul. ;)

Darauf nehme ich bezug, wenn ich etwas frage:)
_g kann alles sein, vom Ball, über einen NPC bis hin zum Spieler selber.
[...]
Habs nach getestet, ja, X ist waagerecht.
Jau, danke. Mit dem restlichen Code werde ich noch etwas brauchen, ist ja bei dir gut gereift.


Kann sein, ich weiss aber bis jetzt noch nicht wie man dem noch sagen kann. Abprallvektor?
Och, ist mir eigentlich egal. Nur wenn er "Wand" heißt, müsste es sich um einen von einer Wand abgeleiteten handeln und eben nicht um den freien Richtungsvektor. Es ist ja viel leichter, bei Codeschnipseln im Forum das Problem vom Projekt isoliert darzustellen, sodass es von jedem leicht nachvollzogen werden kann. Ich stelle da leicht auf stur, wenn das Dargestellte offensichtlich aus einem Kontext gerissen wurde, weil ich erst eine Mords-Recherche in deinen Sources und in vergangenen Beiträgen sowie Parallelthreads machen müsste, um mir den Kontext zusammenzureimen. Für sich genommen sind die paar Zeilen bedeutungslos. Du musst immer davon ausgehen, dass es dein Projekt ist, nicht unseres. Wenn wir es zu unserem machen sollen, ist das etwas viel verlangt (nicht dass mancher keinen Spaß daran hätte, es fehlt allein die Zeit), aber man kann sich Einzelaspekte ansehen, wenn sie entsprechend vollständig dargestellt sind. Da kann dann vllt. auch wieder Sergej Petrow oder jemand anderes einhaken, wenn er nicht gleich deine Engine erlernen muss. ;)


Das es nicht drin stand, war definitiv mein Problem.
aber das aktuelle, entspricht fast meiner gesamten Code Bibliothek.
zb. die Thread Queue, habe ich vor gut 3 Jahren angefangen. Die hilft mir dabei, schnell mal was in nen anderen Thread auszulagern.
CoRG ist ebenfalls schon gute 2 Jahre alt, und doch werde ich beides wohl noch in 50 Jahren benutzen....
Nun verstehe ich sehr viel besser, worum es geht, und es macht mehr Spaß. :)


Ohne Winkelfunktionen§kratz
Einzige was mir da einfallen würde: Mann kann beide Vektoren verrechnen und daraus den abprallenden berechnen.

\\o//
Na selbstverfreilich.


Deine Wand ist also im Grunde die aus dem Abprallpunkt berechnete Abprallwand?
??? Nö. Der Abprallpunkt ist bei mir komplett unbekannt, den müsste man noch (vorher) berechnen. Er spielt auch bei der Spiegelung des Richtungs- bzw. Geschwindigkeitsvektors keine Rolle. Es ist piepegal, wo das stattfindet, wenn es um die reine Richtung geht. Aber Ort und Richtung sind zweierlei Paar Schuhe, die es unbedingt zu trennen gilt. Falls deine Engine dabei etwas vereinfacht oder zusammenfasst, muss ich es mir noch ansehen. Es sind ja auch simple Lösungen denkbar, die einfach einen Ortsvektor um kleine Deltas weitersetzen, ohne dass der Richtungsvektor bekannt wäre. Im Grunde steckt er dann in diesen kleinen Deltas drin, aber ohne analytische Vorausschau oder korrekte Kollisionspunkte, was man auch nicht immer unbedingt haben muss.

Zur Berechnung des neuen Richtungsvektors, der ja ebenfalls ein freier Vektor ist, benötigt man den "Abprallpunkt" nicht. Man kann ihn an eine beliebige Stelle im Raum einzeichnen und sein reflektiertes Pendant berechnen, wenn man nur die Orientierung der Wand oder stattdessen ihres Normalenvektors kennt. Ob es bereits zu einer Kollision gekommen ist bzw. wo sich die Wand wirklich befindet, ist dabei piepegal. "Einfallwinkel = Ausfallwinkel" gilt ja auch, wenn du den Spiegel bis nach Jericho schleppst. Allerdings ändern sich die Positionen bzw. Ortsvektoren und auch der Zeitpunkt der Kollision, was bei zusätzlicher (Erd)beschleunigung einkalkuliert werden müsste.

Ohne letztere genügt ein lineares Gleichungssystem zur Lösung des Schnittpunktes. Bei (Erd)beschleunigung wird die Sache schon komplizierter, allerdings sind auch Approximationslösungen denkbar, bei denen der winzige Fehler gar nicht auffällt. Überhaupt sollte man bei der Kollision darüber nachdenken, ob die Vorgänge während einer Kollision zwischen zwei Framedarstellungen unbedingt physikalisch korrekt sein müssen. Man kann verdammt viel einsparen, wenn das nicht der Fall sein muss. Es kann genügen, wenn es danach korrekt weitergeht, z.B. indem das Objekt einfach vor den Kollisionspunkt gesetzt wird, was einer kleinen Verzögerung entspricht oder wenn für diesen Frame während der Kollision die Erdbeschleunigung deaktiviert ist. Aber bei niedrigen FPS würde das auffallen.

Schwieriger wird das allerdings unter dem Einfluss von präzise simulierter Beschleunigung, insbesondere, weil die aktuelle Orientierung des Vektors am Ort seiner Reflektion eine andere als zum Zeitpunkt des Feststellens seiner Kollision ist. Dann genügt das lineare Gleichungssystem nicht mehr den Anforderungen. Wenn eine Erdbeschleunigung einwirkt, wird die nicht mitreflektiert, sehr wohl aber der aktuelle Richtungsvektor.

Ich würde versuchen, das Problem des nach Kollision (wenn das Objekt schon zu weit ist) nachzuberechnenden Kollisionspunktes samt des neuen Vektors zu generalisieren, als wenn es sich um eine zusätzliche Aktualisierung am Ort der Kollision handeln würde, ist aber nur so eine erste Idee. Das wäre so ein Rücksetzen auf den alten Wert plus Orts- und Zeitberechnung, um daraus einen unsichtbaren Zwischenzustand zu berechnen (der Frame fällt ja nicht synchron auf die Kollision), um von diesem aus den Restschritt auf den aktuellen zu kalkulieren.

Kommerzielle Engines tricksen eine Menge, da ist nicht immer alles korrekt simuliert. Ich muss mir das bei dir auch erst mal richtig ansehen, damit ich die Voraussetzungen und Anforderungen besser kenne.

Aber ich wollte nicht so weit gehen, wir diskutieren ja nur über ein Teilproblem, das der Reflektion eines Richtungsvektors. Mehr habe ich ja nicht gewollt oder behauptet. Der geht eben simpel ohne Winkelfunktionen zu berechnen.


Bewegugnsrichtung?!
Ja, dachte ich so. Bei der Reflektion beziehe ich mich auf freie Vektoren, wenn da nichts anderes steht.


Wie oben erwähnt: Ich denke man könnte noch die beiden Vektoren irgendwie miteinander verrechnen,
Es geht ja um das "Wie?". Das man es kann, habe ich ja vorausgeschickt.


sofern man beide zuerst auf Gesamtlänge 1 streckt.
Einer genügt, das ist definitionsgemäß bei dem Einheitsnormalenvektor der Fall. Das kannst du auch bei dem Richtungs- bzw. Geschwindigkeitsvektor tun, musst es aber nicht unbedingt. Denn sein Betrag tut bei der Reflektion nichts zur Sache, ist ja für die Winkel egal, mit wieviel Karacho der auf die Wand klatscht.


E: normalvvektor? Muss google fragen, ich habe nicht mal die hälfte verstanden was ihr da ausgetauscht habt....
Das ist ja der Sinn dahinter, einen Startpunkt zu liefern, damit du es dir selbst erschließen kannst. Also kannst du Dir schon einmal zwei Vektoren als gegeben vorstellen, einmal einen senkrechten zur Wand, auf den Betrag eins normiert, und unseren freien Richtungsvektor, ganz gleich, welchen Betrages.

Tipp 4: Das Skalarprodukt ersetzt den Kosinus.

Multithread
08.07.2013, 08:21
Sorry, wenn ich momentan etwas schreibfaul beim Zitieren, insbesondere bei Schachtelungen bin, kommt vom Stress, ist sonst nicht meine Art, für heute bleibe ich mal faul. ;)

Jau, danke. Mit dem restlichen Code werde ich noch etwas brauchen, ist ja bei dir gut gereift.

Bin da auch schon 2 Wochen an dieser einen Funktion dran...




Och, ist mir eigentlich egal. Nur wenn er "Wand" heißt, müsste es sich um einen von einer Wand abgeleiteten handeln und eben nicht um den freien Richtungsvektor. Es ist ja viel leichter, bei Codeschnipseln im Forum das Problem vom Projekt isoliert darzustellen, sodass es von jedem leicht nachvollzogen werden kann. Ich stelle da leicht auf stur, wenn das Dargestellte offensichtlich aus einem Kontext gerissen wurde, weil ich erst eine Mords-Recherche in deinen Sources und in vergangenen Beiträgen sowie Parallelthreads machen müsste, um mir den Kontext zusammenzureimen. Für sich genommen sind die paar Zeilen bedeutungslos. Du musst immer davon ausgehen, dass es dein Projekt ist, nicht unseres. Wenn wir es zu unserem machen sollen, ist das etwas viel verlangt (nicht dass mancher keinen Spaß daran hätte, es fehlt allein die Zeit), aber man kann sich Einzelaspekte ansehen, wenn sie entsprechend vollständig dargestellt sind. Da kann dann vllt. auch wieder Sergej Petrow oder jemand anderes einhaken, wenn er nicht gleich deine Engine erlernen muss. ;)

Da ich diese wand von Daepilin übernommen habe, verstehe ich selber noch nicht ganz wozu ich sie brauche.
Wenn ich das aber so sehe, dann könnte Wand gut auch die abprallwand sein, oder täuscht das. Also der Vektor welche um 90° zum Vektor von _g.Zentrum -> Kollisionspunkt steht.




Nun verstehe ich sehr viel besser, worum es geht, und es macht mehr Spaß. :)
Na selbstverfreilich.


Gut.



??? Nö. Der Abprallpunkt ist bei mir komplett unbekannt, den müsste man noch (vorher) berechnen. Er spielt auch bei der Spiegelung des Richtungs- bzw. Geschwindigkeitsvektors keine Rolle. Es ist piepegal, wo das stattfindet, wenn es um die reine Richtung geht. Aber Ort und Richtung sind zweierlei Paar Schuhe, die es unbedingt zu trennen gilt. Falls deine Engine dabei etwas vereinfacht oder zusammenfasst, muss ich es mir noch ansehen. Es sind ja auch simple Lösungen denkbar, die einfach einen Ortsvektor um kleine Deltas weitersetzen, ohne dass der Richtungsvektor bekannt wäre. Im Grunde steckt er dann in diesen kleinen Deltas drin, aber ohne analytische Vorausschau oder korrekte Kollisionspunkte, was man auch nicht immer unbedingt haben muss.

Ganz so egal ist er nicht, ohne abprallpunkt kannst du nicht sagen in welche Richtung der Vektor der Abprallwand geht, das ist seine einzige Aufgabe;)
Dieser Abprallwand Vektor hat dann zb sowas : 3,-24 als Richtung.





Zur Berechnung des neuen Richtungsvektors, der ja ebenfalls ein freier Vektor ist, benötigt man den "Abprallpunkt" nicht. Man kann ihn an eine beliebige Stelle im Raum einzeichnen und sein reflektiertes Pendant berechnen, wenn man nur die Orientierung der Wand oder stattdessen ihres Normalenvektors kennt. Ob es bereits zu einer Kollision gekommen ist bzw. wo sich die Wand wirklich befindet, ist dabei piepegal. "Einfallwinkel = Ausfallwinkel" gilt ja auch, wenn du den Spiegel bis nach Jericho schleppst. Allerdings ändern sich die Positionen bzw. Ortsvektoren und auch der Zeitpunkt der Kollision, was bei zusätzlicher (Erd)beschleunigung einkalkuliert werden müsste.

Ohne letztere genügt ein lineares Gleichungssystem zur Lösung des Schnittpunktes. Bei (Erd)beschleunigung wird die Sache schon komplizierter, allerdings sind auch Approximationslösungen denkbar, bei denen der winzige Fehler gar nicht auffällt. Überhaupt sollte man bei der Kollision darüber nachdenken, ob die Vorgänge während einer Kollision zwischen zwei Framedarstellungen unbedingt physikalisch korrekt sein müssen. Man kann verdammt viel einsparen, wenn das nicht der Fall sein muss. Es kann genügen, wenn es danach korrekt weitergeht, z.B. indem das Objekt einfach vor den Kollisionspunkt gesetzt wird, was einer kleinen Verzögerung entspricht oder wenn für diesen Frame während der Kollision die Erdbeschleunigung deaktiviert ist. Aber bei niedrigen FPS würde das auffallen.

Kein Problem, ich kann dem Objekt auch ne eigene Thread Resource für einige Milisekunden zuweisen die genau dies übernimmt, dann kann ich das Objekt auch exakt an die Wand fahren lassen, sofern nötig.
Damit sollte das auch bei niedrigen FPS nicht auffallen.





Schwieriger wird das allerdings unter dem Einfluss von präzise simulierter Beschleunigung, insbesondere, weil die aktuelle Orientierung des Vektors am Ort seiner Reflektion eine andere als zum Zeitpunkt des Feststellens seiner Kollision ist. Dann genügt das lineare Gleichungssystem nicht mehr den Anforderungen. Wenn eine Erdbeschleunigung einwirkt, wird die nicht mitreflektiert, sehr wohl aber der aktuelle Richtungsvektor.

Statistische Annäherung an den exakten Kollisionspunkt mit 5 Wiederholungen?
Es ist ja kein Wissenschaftliches Programm, und ich habe aufgrund des Gitternetztes auch nicht eine unendlich nahe Annäherung, sondern wenn ich mich ein atomarte Feld verschiebe, habe ich schon die Kleinste Einheit.




Ich würde versuchen, das Problem des nach Kollision (wenn das Objekt schon zu weit ist) nachzuberechnenden Kollisionspunktes samt des neuen Vektors zu generalisieren, als wenn es sich um eine zusätzliche Aktualisierung am Ort der Kollision handeln würde, ist aber nur so eine erste Idee. Das wäre so ein Rücksetzen auf den alten Wert plus Orts- und Zeitberechnung, um daraus einen unsichtbaren Zwischenzustand zu berechnen (der Frame fällt ja nicht synchron auf die Kollision), um von diesem aus den Restschritt auf den aktuellen zu kalkulieren.

Kommerzielle Engines tricksen eine Menge, da ist nicht immer alles korrekt simuliert. Ich muss mir das bei dir auch erst mal richtig ansehen, damit ich die Voraussetzungen und Anforderungen besser kenne.

Physikalisch korrekt muss es nicht sein, lediglich mit einer annehmbaren Genauigkeit richtig.





Einer genügt, das ist definitionsgemäß bei dem Einheitsnormalenvektor der Fall. Das kannst du auch bei dem Richtungs- bzw. Geschwindigkeitsvektor tun, musst es aber nicht unbedingt. Denn sein Betrag tut bei der Reflektion nichts zur Sache, ist ja für die Winkel egal, mit wieviel Karacho der auf die Wand klatscht.


Das ist ja der Sinn dahinter, einen Startpunkt zu liefern, damit du es dir selbst erschließen kannst. Also kannst du Dir schon einmal zwei Vektoren als gegeben vorstellen, einmal einen senkrechten zur Wand, auf den Betrag eins normiert, und unseren freien Richtungsvektor, ganz gleich, welchen Betrages.

Tipp 4: Das Skalarprodukt ersetzt den Kosinus.
der senkrechten zur Wand entspricht _g.Zentrum -> abprallPunkt
und _g.Bewegungsrichtung ist der andere

Jetzt haben diese Vektoren eine Differenz auf X und auf Y achse.

wenn ich jetzt:
Y= a.X-b.X
Und
X=a.Y-b.Y

mache, kriege ich nicht das richtige Resultat raus:C:
Und Irgendwo muss auch noch das Skalarprodukt mit sein....

aber sowas:

double c = Math.Sqrt((double)(Wand.X * Wand.X + Wand.Y * Wand.Y)) * skalaprodukt;

kann es auch nicht sein, was mache ich dann mit c§ugly

jabu
08.07.2013, 22:36
Auf deinen Beitrag werde ich später eingehen, falls es die Zeit erlaubt. Habe endlich verstanden, was deine

public Vektor abprallen(Gegenstand g, List<Wand> _wande, Point position, GravitationRichtung _richtung)
tut. Ich beziehe mich dabei immer noch auf deine VYPH2D_Game_Engine_Demo.zip dtQTkaxkGbbMvPLy2D_Game_Engine_Demo.zip, weil ich anhand dieser einigermaßen funktionierenden Version deine Engine besser verstehen lernen konnte. Es hat relativ lange gedauert, weil auch immer mal wieder Code ohne Effekt dazwischen ist. Desweiteren unterscheiden sich die Lösungsansätze in deiner Engine teils deutlich von meiner Art von Problemen zu abstrahieren, aber interessant sind sie allemal.


Hallo Zusammen

Ich arbeite Grad an eine Game Engine die sowas wie die 2D Mario spiele ermöglichen soll. Die gesamte Steuerung ist im Readme Spoiler weiter unten erklärt.

Mein Problem sind die Kollisionsabfragen und die Kollisionen, bzw dann später noch das 'Physikalisch korrekte' abprallen.
Dabei geht es nicht um den Fakt das man ab einer gewissen geschwindigkeit durch wände gehen kann, dafür gibt es ja eine maximale Geschwndigkeit der Figuren.
Das Problem lässt sich realtiv gut am rechten Rand darstellen, dort geht die Spielfigur(das Violette ding:D) öfters mal durch die Wand, und teilweise zurück ins Feld.
An der linken Wand und am Boden lässt sich das Problem jedoch nicht nachstellen.

Das Problem liegt in deiner Physik.cs, in oben aufgeführter Funktion, so eine Art unentdeckter Flüchtigkeitsfehler:



if (x < position.X)
{
umrechnung.X = -1;
if (alteRichtung.X < 0.0M)
{
alteRichtung.X += g.Widerstand;
}
else if (alteRichtung.X > 0.0M)
{
alteRichtung.X -= g.Widerstand;
}
}
else if (x > position.X)
{
// umrechnung.Y = -1; // -- (Upps, vertan)
umrechnung.X = -1; // ++ (So stimmt's)
if (alteRichtung.Y < 0.0M)
{
alteRichtung.Y += g.Widerstand;
}
else if (alteRichtung.Y > 0.0M)
{
alteRichtung.Y -= g.Widerstand;
}
}
else if (y < position.Y)
{
umrechnung.Y = -1; // ++ (übersichtlicher)
if (alteRichtung.Y < 0.0M)
{
alteRichtung.Y += g.Widerstand;
}
else if (alteRichtung.Y > 0.0M)
{
alteRichtung.Y -= g.Widerstand;
}
// umrechnung.Y = -1; // -- (unübersichtlich)
}
else if (y > position.Y)
{
umrechnung.Y = -1;
if (alteRichtung.Y < 0.0M)
{
alteRichtung.Y += g.Widerstand;
}
else if (alteRichtung.Y > 0.0M)
{
alteRichtung.Y -= g.Widerstand;
}
}

Was mich extrem irritierte, ist die Tatsache, dass in einer anderen Funktion auf Kollision geprüft wird und hier nochmal aus der Liste _wande gelesen wird, obwohl längst klar sein dürfte, womit und wie die Kollision stattgefunden hat. Erlaubt sind dann nur reine Senkrechten und Waagerechten, welche zu dem Listeneintrag führen. Es ist überflüssig bzw. ärgerlich, diese hier noch einmal zu detektieren.

Das ist alles kein guter Stil und eher etwas für einen Obfuscated Code Contest, da bleibe ich bei. :D ;)

Edit: Mittlerweile hast du wohl den Fehler mit den rechten Begrenzungen gefunden, ist ja in der neuen Version nicht mehr drin!

Multithread
09.07.2013, 05:54
Auf deinen Beitrag werde ich später eingehen, falls es die Zeit erlaubt. Habe endlich verstanden, was deine

public Vektor abprallen(Gegenstand g, List<Wand> _wande, Point position, GravitationRichtung _richtung)
tut. Ich beziehe mich dabei immer noch auf deine VYPH2D_Game_Engine_Demo.zip dtQTkaxkGbbMvPLy2D_Game_Engine_Demo.zip, weil ich anhand dieser einigermaßen funktionierenden Version deine Engine besser verstehen lernen konnte. Es hat relativ lange gedauert, weil auch immer mal wieder Code ohne Effekt dazwischen ist. Desweiteren unterscheiden sich die Lösungsansätze in deiner Engine teils deutlich von meiner Art von Problemen zu abstrahieren, aber interessant sind sie allemal.

Ich sehe nur schon an der Zeile code das du da eine Veraltete Funktion betrachtest die es so in der neusten Demo nicht mehr gibt.
Wenn du mir sagst was nicht geht, kann ich diesen Umstand beheben.
Ansonsten: Probiere mal den Ordner 2DGame Engine durch den aus der Aktuellen Demo zu ersetzten, das sollte ebenfalls gehen.




Das Problem liegt in deiner Physik.cs, in oben aufgeführter Funktion, so eine Art unentdeckter Flüchtigkeitsfehler:



if (x < position.X)
{
umrechnung.X = -1;
if (alteRichtung.X < 0.0M)
{
alteRichtung.X += g.Widerstand;
}
else if (alteRichtung.X > 0.0M)
{
alteRichtung.X -= g.Widerstand;
}
}
else if (x > position.X)
{
// umrechnung.Y = -1; // -- (Upps, vertan)
umrechnung.X = -1; // ++ (So stimmt's)
if (alteRichtung.Y < 0.0M)
{
alteRichtung.Y += g.Widerstand;
}
else if (alteRichtung.Y > 0.0M)
{
alteRichtung.Y -= g.Widerstand;
}
}
else if (y < position.Y)
{
umrechnung.Y = -1; // ++ (übersichtlicher)
if (alteRichtung.Y < 0.0M)
{
alteRichtung.Y += g.Widerstand;
}
else if (alteRichtung.Y > 0.0M)
{
alteRichtung.Y -= g.Widerstand;
}
// umrechnung.Y = -1; // -- (unübersichtlich)
}
else if (y > position.Y)
{
umrechnung.Y = -1;
if (alteRichtung.Y < 0.0M)
{
alteRichtung.Y += g.Widerstand;
}
else if (alteRichtung.Y > 0.0M)
{
alteRichtung.Y -= g.Widerstand;
}
}

Gar nicht weiter beachten, das ging nicht, sobald ich ne schräge kante habe. Und das haben zb. die 'Tödlichen' Zacken:D





Was mich extrem irritierte, ist die Tatsache, dass in einer anderen Funktion auf Kollision geprüft wird und hier nochmal aus der Liste _wande gelesen wird, obwohl längst klar sein dürfte, womit und wie die Kollision stattgefunden hat. Erlaubt sind dann nur reine Senkrechten und Waagerechten, welche zu dem Listeneintrag führen. Es ist überflüssig bzw. ärgerlich, diese hier noch einmal zu detektieren.

Das ist alles kein guter Stil und eher etwas für einen Obfuscated Code Contest, da bleibe ich bei. :D ;)

Edit: Mittlerweile hast du wohl den Fehler mit den rechten Begrenzungen gefunden, ist ja in der neuen Version nicht mehr drin!
Ja, den hatte ich mal gefunden. Aber half mir dann auch nichts mehr, da ich bei schrägen Kanten überhaupt keine Kollision mehr hinbekommen habe.:dnuhr:

jabu
10.07.2013, 17:57
Ich sehe nur schon an der Zeile code das du da eine Veraltete Funktion betrachtest die es so in der neusten Demo nicht mehr gibt.
Die Hintergrund.list wird bei mir nicht geladen, weshalb die Tests schwerfallen. Vielleicht kannst du kurz mitteilen, wie man das aktiviert bekommt?

Deine Listen sind mir suspekt, weil diese nicht erkennen lassen, ob sich per .Add da etwas unqualifiziert hinzuaddiert hat. Bei Übergabe einer Point-Liste an abprallen(.) ist mir das noch suspekter, weil es keine impliziten Sicherheiten gibt. Dieses Durchiterieren muss jedes mal kontrolliert und ggf. abgefangen werden, wenn man sich nicht 100-prozentig sicher ist, dass da ausschließlich drin ist, was hineingehört. Eine Punkt-Liste ist einfach die falsche Abstraktion für ein Punktpaar, ebenso ist eine Wand-Liste die falsche Abstraktion, wenn man eine einzelne Wand erwartet. Code wird so beinahe unlesbar und buganfällig, denn es fehlen die Garantien, die man bei korrekter Abstraktion hat. Nur wer deinen Code auswendig kennt, hat eine ausreichende Chance, die Annahmen zu kennen. Wenn man eine Funktion bzw. Methode sieht, sollte der Code für sich sprechen. Stilfragen sind kein Selbstzweck, sondern es geht um Wartbarkeit, Robustheit und Performance. Bestimmte Fehler und Notwendigkeiten zur Überprüfungen sowie Sackgassen im design entstehen bei gutem Stil erst gar nicht. Ich sage lieber nicht wie lange ich an deinem Code gesessen habe, um auch nur einigermaßen den Teilbereich deiner Engine zu verstehen, über den wir hier diskutieren. Gut, es ist absolut freiwillig, wenn sich jemand dafür interessiert, deshalb meine ich das auch nicht als Beschwerde. Ein gründliches Refactoring würde deiner Engine allerdings gut tun.


Gar nicht weiter beachten, das ging nicht, sobald ich ne schräge kante habe. Und das haben zb. die 'Tödlichen' Zacken:D
Muss mir das in deiner neuen Version noch richtig ansehen, aber zuerst brauche ich Hintergrundblöcke.


Ja, den hatte ich mal gefunden. Aber half mir dann auch nichts mehr, da ich bei schrägen Kanten überhaupt keine Kollision mehr hinbekommen habe.:dnuhr:
Noch in deiner alten dtQTkaxkGbbMvPLy2D_Game_Engine_Demo.zip, bitte sehr:


http://youtu.be/I_xrDGQWSYY

Dort ist noch ein zweites Video verlinkt, das den selben Sachverhalt zeigt, Links:
Video 01 (http://youtu.be/I_xrDGQWSYY)
Video 02 (http://youtu.be/O3SoJMklY8k)

Mangels Videobeschleunigung (kein DirectX, kein OpenGL) haben die gängigen Programme versagt, habe daher ein Tool genommen, welches nur alle 100 ms bzw. mit 10 Fps Screenshots macht.

Zur Simulation schräger Wande habe ich (in der alten Engine) einfach deine Block(s) schiefgerechnet (aber natürlich so, dass sie nach einem Schema wieder aneinanderpassen), außer denen von Taste "3". Dieses Kreisbildchen habe ich dann einfach kopiert und umbenannt, "quick and dirty", wie man so sagt.


Das Koordiantensystem entspricht dem womit Windows die Pixel auf dem Bildschirm Definitiert.
Warum hast du nicht einfach gesagt, dass die Y-Achse auf dem Kopf steht und daher das Koordinatensystem - anders als im Matheunterricht - im Uhrzeigersinn dreht? Ob das durchgängig so ist, weiß ich nicht, aber bei den Blöcken ist es so, denn die Kanten der Blöcke werden durch Punkte ebenfalls im Uhrzeigersinn definiert.


das liegt an den Trennwänden zwischen zwei blöcken, die fliessen aktuell auch noch in die Abprallwand mit ein, diese müssen aber noch raus, zb. nach dem laden aller Blöcke.
Daran arbeite ich gerade.
Habe ich mittlerweile gemerkt, wenn das Objekt in einer Mauer steckt, dann kollidiert es munter weiter und bleibt daher erst recht stecken.

In den Videos^ sind natürlich meine äußerst simplen und allgemeingültigen Vektoroperationen zur Reflektion an beliebig orientierten Wänden drin. Und die kommen, wie versprochen, ohne Winkelfunktionen aus. Außerdem wird in abprallen() noch einmal gefiltert, ob man sich tatsächlich auf eine Wand zubewegt, um ungültige Wand(e) in der Liste zu überspringen, falls vorhanden.

Es ist aber leider von der Architektur her leider grob unglücklich, dass die Ermittlung der neuen Richtung von der Kollisionserkennung separiert ist. Dieser Sachverhalt ist mir unverständlich, weil Informationsverluste damit einhergehen. "abprallen()" weiß eben nichts mehr von den vorausgegangenen Ereignissen sowie Ergebnissen in Kolidieren(Wand). Ich sage damit nicht, dass man nicht eine separate Funktion machen kann, sondern dass dieses Hintereinanderketten über Objektgrenzen hinweg und einmal quer durch die Physik-Loop mindestens unglücklich ist.

Es ist unglücklich, dass deine Engine ständig über diese Listen die Informationen aus ihrem angestammten Kontext reißt, obwohl diese bereits irgendwo anders (früher) gegeben waren. Dieser Informationsverlust muss schwer bezahlt werden, indem Nachberechnungen durchgeführt werden und nachträgliche Änderungen an den Implementierungen fast unmöglich sind. Anstatt eine Methode zu modifizieren, bricht der ganze Code, weil du die ganze Kette zum Fixen durchlaufen musst. Kein Mensch kann dir dabei noch sagen, ob die limitierenden Randbedingungen bzw. Annahmen, von denen du anfangs ausgingest, noch so anwendbar sind.

Manchmal sind Referenzen auf Objekte, die diese Informationen halten, glücklicher, manchmal sind es Objekte, die ihre Informationen autonom behandeln, je nach Ansatz. Aber eine teils lineare, teils verzweigte Verkettung von Funtionen ist so ziemlich das, was am brutalsten in die Sackgasse führt. Um dieses zu verhindern, kann es helfen, in sich selbst beschreibenden autonomen Objekten zu denken, sich klarzumachen, was sie sind, was ihnen gehört und was sie können. Und vor allem sollte man sich fragen, wer etwas besitzt oder kann.

Das Grundproblem ist ein eher philosophisches: Programme sollen ein Problem abbilden. Je detaillierter sie ausgearbeitet werden, desto mehr reiben sie sich an der Realität, weil die Abstraktionsmittel auf der Ebene dieser Details irgendwann einfach der Realität widersprechen.

Also ist es wichtig, sich bereits vorher über diese Grenzen im Klaren zu sein. Natürlich wächst ein Programm, man fängt bescheiden an und läuft dann aufgrund gestiegener Anforderungen in Sackgassen hinein. Aber es gibt einen Detektor dafür, ab wann ein Umkrempeln der internen Struktur erforderlich wird, und das ist eben genau dieses Gefühl, dass die Komplexität einem die Freiheitsgrade raubt, sobald man Änderungen vornimmt. Irgendwo verändert man einen Parameter, was einen nicht enden wollenden Rattenschwanz hinter sich herzieht, bis hin zu Widersprüchen und notdürftigen Fixes.

Das bedeutet nicht, dass der Programmierer die Komplexität nicht handhaben kann, sondern, dass der Code in seiner Struktur nicht korrekt genug von der Realität abstrahiert. Sobald er das aber tut, lösen sich zuvor scheinbar unlösbare Probleme einfach auf. Um dieses zu unterstützen, wurde die Objektorientierung eingeführt, wobei es sich um eine Abstraktionsweise handelt. Die Programmiersprache ist dabei mehr oder weniger egal. Ich kann auch eigentlich gar kein C#, muss man wissen, und je mehr ich es mir ansehe, desto weniger mag ich es. Der einzige Vorteil dieser Sprache sind wohl die vorgefertigten Elemente.

Ich hatte einen zähen Ringkampf mit deiner Klasse Vektor, die ich wie in C++ vernünftig generalisieren wollte. Am Ende scheiterte das u.a. wegen des defekten Initialisierungsverhaltens von Objekten in C#/CLI. Ich bin mir mittlerweile sicher, dass man ernsthafte Applikationen nicht sinnvoll in C# erstellen kann. Ich bin dir geradezu dankbar für diese Erkenntnis! :)

Multithread
10.07.2013, 19:40
Die Hintergrund.list wird bei mir nicht geladen, weshalb die Tests schwerfallen. Vielleicht kannst du kurz mitteilen, wie man das aktiviert bekommt?

Sollte eigentlich immer geladen werden. Befindet sich die hintergrund.list denn im Data Ordner der Spieledaten?




Deine Listen sind mir suspekt, weil diese nicht erkennen lassen, ob sich per .Add da etwas unqualifiziert hinzuaddiert hat. Bei Übergabe einer Point-Liste an abprallen(.) ist mir das noch suspekter, weil es keine impliziten Sicherheiten gibt. Dieses Durchiterieren muss jedes mal kontrolliert und ggf. abgefangen werden, wenn man sich nicht 100-prozentig sicher ist, dass da ausschließlich drin ist, was hineingehört. Eine Punkt-Liste ist einfach die falsche Abstraktion für ein Punktpaar, ebenso ist eine Wand-Liste die falsche Abstraktion, wenn man eine einzelne Wand erwartet. Code wird so beinahe unlesbar und buganfällig, denn es fehlen die Garantien, die man bei korrekter Abstraktion hat. Nur wer deinen Code auswendig kennt, hat eine ausreichende Chance, die Annahmen zu kennen. Wenn man eine Funktion bzw. Methode sieht, sollte der Code für sich sprechen. Stilfragen sind kein Selbstzweck, sondern es geht um Wartbarkeit, Robustheit und Performance. Bestimmte Fehler und Notwendigkeiten zur Überprüfungen sowie Sackgassen im design entstehen bei gutem Stil erst gar nicht. Ich sage lieber nicht wie lange ich an deinem Code gesessen habe, um auch nur einigermaßen den Teilbereich deiner Engine zu verstehen, über den wir hier diskutieren. Gut, es ist absolut freiwillig, wenn sich jemand dafür interessiert, deshalb meine ich das auch nicht als Beschwerde. Ein gründliches Refactoring würde deiner Engine allerdings gut tun.

Das mit der Punkteliste, hat nen ganz bestimmten grund: das sind all die Punkte wo eine Linie des Gegenstandes mit einer Linie am Rand kollidiert.
Solange die Algorithmen dahinter stimmen, kann ich mir aber 100% sicher sein das das drinn ist, was ich haben möchte.




Muss mir das in deiner neuen Version noch richtig ansehen, aber zuerst brauche ich Hintergrundblöcke.

Du kannst für jeden Beliebigen Block in der Datei Bilder.ini die Kollisionslinien festlegen. Ich denke doch das hast du auch so gemacht?




Noch in deiner alten dtQTkaxkGbbMvPLy2D_Game_Engine_Demo.zip, bitte sehr:


http://youtu.be/I_xrDGQWSYY

Dort ist noch ein zweites Video verlinkt, das den selben Sachverhalt zeigt, Links:
Video 01 (http://youtu.be/I_xrDGQWSYY)
Video 02 (http://youtu.be/O3SoJMklY8k)

Etwa so habe ich mir das vorgestellt^2^




Mangels Videobeschleunigung (kein DirectX, kein OpenGL) haben die gängigen Programme versagt, habe daher ein Tool genommen, welches nur alle 100 ms bzw. mit 10 Fps Screenshots macht.

hmm, hättest was gesagt, sowas einzubauen, ist kein Problem, jedes Bild ist ja im Grunde ein screenshot den man verwenden/Speichern kann. Am besten die Threadqueue mit der undankbaren aufgabe belasten:D




Zur Simulation schräger Wande habe ich (in der alten Engine) einfach deine Block(s) schiefgerechnet (aber natürlich so, dass sie nach einem Schema wieder aneinanderpassen), außer denen von Taste "3". Dieses Kreisbildchen habe ich dann einfach kopiert und umbenannt, "quick and dirty", wie man so sagt.

schiefgerechnet? Klingt nicht sehr allgemeingültig, geht das aber auch noch wenn ich zb nur 1 Pixel auf 100 schräg bin?





Warum hast du nicht einfach gesagt, dass die Y-Achse auf dem Kopf steht und daher das Koordinatensystem - anders als im Matheunterricht - im Uhrzeigersinn dreht? Ob das durchgängig so ist, weiß ich nicht, aber bei den Blöcken ist es so, denn die Kanten der Blöcke werden durch Punkte ebenfalls im Uhrzeigersinn definiert.

Das Koordinatensystem geht in 4 Richtungen, je für x und y gibt es eine + und eine - richtung.




Habe ich mittlerweile gemerkt, wenn das Objekt in einer Mauer steckt, dann kollidiert es munter weiter und bleibt daher erst recht stecken.

:D
Die erkentniss ist aber durchaus von bedeutung, daran erkennt man das der Kollisions und Abprall algorithmus funktioniert.




In den Videos^ sind natürlich meine äußerst simplen und allgemeingültigen Vektoroperationen zur Reflektion an beliebig orientierten Wänden drin. Und die kommen, wie versprochen, ohne Winkelfunktionen aus. Außerdem wird in abprallen() noch einmal gefiltert, ob man sich tatsächlich auf eine Wand zubewegt, um ungültige Wand(e) in der Liste zu überspringen, falls vorhanden.

über simpel lässt sich streiten.
ungültige Wände gibt es nicht. Und die, welche 2 übereinanderliegen, muss ich noch beim Start rauslöschen, sollte es auch nicht geben.




Es ist aber leider von der Architektur her leider grob unglücklich, dass die Ermittlung der neuen Richtung von der Kollisionserkennung separiert ist. Dieser Sachverhalt ist mir unverständlich, weil Informationsverluste damit einhergehen. "abprallen()" weiß eben nichts mehr von den vorausgegangenen Ereignissen sowie Ergebnissen in Kolidieren(Wand). Ich sage damit nicht, dass man nicht eine separate Funktion machen kann, sondern dass dieses Hintereinanderketten über Objektgrenzen hinweg und einmal quer durch die Physik-Loop mindestens unglücklich ist.

Ich habe mir dabei eigentlich was überlegt:
Im worst case hast du an nur einer statischen Wand ganze 6 Kollidierende Wände des Gegenstandes der sich bewegt.
Wenn du mit den Objektgrenzen mein Spielfeld meinst: ja, das ist unglücklich, aber da habe ich noch nichts besseres gefunden.





Es ist unglücklich, dass deine Engine ständig über diese Listen die Informationen aus ihrem angestammten Kontext reißt, obwohl diese bereits irgendwo anders (früher) gegeben waren. Dieser Informationsverlust muss schwer bezahlt werden, indem Nachberechnungen durchgeführt werden und nachträgliche Änderungen an den Implementierungen fast unmöglich sind. Anstatt eine Methode zu modifizieren, bricht der ganze Code, weil du die ganze Kette zum Fixen durchlaufen musst. Kein Mensch kann dir dabei noch sagen, ob die limitierenden Randbedingungen bzw. Annahmen, von denen du anfangs ausgingest, noch so anwendbar sind.

Wo reist die Engine zeugs aus dem Kontext?
Wenn du es mir einigermassen erlätern kannst, kann ich es beheben, ich kenne den code noch wie meine Westentasche, oder so ähnlich.




Manchmal sind Referenzen auf Objekte, die diese Informationen halten, glücklicher, manchmal sind es Objekte, die ihre Informationen autonom behandeln, je nach Ansatz. Aber eine teils lineare, teils verzweigte Verkettung von Funtionen ist so ziemlich das, was am brutalsten in die Sackgasse führt. Um dieses zu verhindern, kann es helfen, in sich selbst beschreibenden autonomen Objekten zu denken, sich klarzumachen, was sie sind, was ihnen gehört und was sie können. Und vor allem sollte man sich fragen, wer etwas besitzt oder kann.

:A
Meine Ausbildung ist noch nicht abgeschlossen:o




Das Grundproblem ist ein eher philosophisches: Programme sollen ein Problem abbilden. Je detaillierter sie ausgearbeitet werden, desto mehr reiben sie sich an der Realität, weil die Abstraktionsmittel auf der Ebene dieser Details irgendwann einfach der Realität widersprechen.

Also ist es wichtig, sich bereits vorher über diese Grenzen im Klaren zu sein. Natürlich wächst ein Programm, man fängt bescheiden an und läuft dann aufgrund gestiegener Anforderungen in Sackgassen hinein. Aber es gibt einen Detektor dafür, ab wann ein Umkrempeln der internen Struktur erforderlich wird, und das ist eben genau dieses Gefühl, dass die Komplexität einem die Freiheitsgrade raubt, sobald man Änderungen vornimmt. Irgendwo verändert man einen Parameter, was einen nicht enden wollenden Rattenschwanz hinter sich herzieht, bis hin zu Widersprüchen und notdürftigen Fixes.

Ah, diesen rattenschwanz kenne ich, den versuche ich eigentlich überall zu verhindern wo ich es kommen sehe.




Das bedeutet nicht, dass der Programmierer die Komplexität nicht handhaben kann, sondern, dass der Code in seiner Struktur nicht korrekt genug von der Realität abstrahiert. Sobald er das aber tut, lösen sich zuvor scheinbar unlösbare Probleme einfach auf. Um dieses zu unterstützen, wurde die Objektorientierung eingeführt, wobei es sich um eine Abstraktionsweise handelt. Die Programmiersprache ist dabei mehr oder weniger egal. Ich kann auch eigentlich gar kein C#, muss man wissen, und je mehr ich es mir ansehe, desto weniger mag ich es. Der einzige Vorteil dieser Sprache sind wohl die vorgefertigten Elemente.

C# hat eine grosse Bibliothek und ist im Grunde Plattformunabhängig wie Java.
Ausserdem gibt es mit XNA eine sehr einfach anwendbare DirectX9 schnittstelle.




Ich hatte einen zähen Ringkampf mit deiner Klasse Vektor, die ich wie in C++ vernünftig generalisieren wollte. Am Ende scheiterte das u.a. wegen des defekten Initialisierungsverhaltens von Objekten in C#/CLI. Ich bin mir mittlerweile sicher, dass man ernsthafte Applikationen nicht sinnvoll in C# erstellen kann. Ich bin dir geradezu dankbar für diese Erkenntnis! :)
was soll ein defektes Inizialisierungsverfahren bitte schön sein?


Willst du mir auch erklären wie du das mit den Vektoren gemacht hast?
Im grunde hast du wohl sowas (http://www.coding-board.de/showthread.php/31374-Korrektes-Abprallen-von-schräger-Wand) implementiert.
E: solltest du eine Seite kennen wo deine Vorgehensweise verständlich erklärt ist, würde ich das gerne mal ausprobieren.

Multithread
12.07.2013, 18:17
So. Das mit den Vektoren:ich habe im netzt wirklich was dazu gefunden, mit folgendem Code resultat:


Vektor abprallwand = resolveSkalar(senkrechte);

double value = Math.Sqrt((double)(abprallwand.X * abprallwand.X + abprallwand.Y * abprallwand.Y));
auf diagonale 1 Normalisierte Wand.
decimal[] N = new decimal[2];
N[0] = abprallwand.X / (decimal)value;
N[1] = abprallwand.Y / (decimal)value;

decimal[] V = new decimal[2] { alteRichtung.X, alteRichtung.Y};

//die zwei zeilen habe ich ausm Netz, kp was die genau machen.
V[0] = V[0] - 2 * ((V[0] * V[0] + V[1] * V[1]) / (N[0] * N[0] + N[1] * N[1])) * N[0] - V[0];
V[1] = V[1] - 2 * ((V[0] * V[0] + V[1] * V[1]) / (N[0] * N[0] + N[1] * N[1])) * N[1] - V[1];

decimal faktor = (decimal)(Math.Sqrt((double)(alteRichtung.X * alteRichtung.X + alteRichtung.Y * alteRichtung.Y)) / Math.Sqrt((double)(V[0] * V[0] + V[1] * V[1])));
//faktor *= 0.98M;


V[0] *= faktor;
V[1] *= faktor;
return new Vektor(V[0], V[1]);
Irgendwie kann ich dieses faktorisieren auf die geschwindigkeit am ende doch sicher umgehen, zwei Wurzeln berechnen sind doch relativ viel.
§wink

Danke an Daepilin und jabu für Ihre mehr oder minder grosse Geduld mit mir.

Lehona
12.07.2013, 18:38
Da sqrt(x)/sqrt(y) = sqrt(x/y) kannst du dir mind. einmal das Wurzel ziehen sparen. Zum Rest kann ich keinen Kommentar abgeben, weil ich keine Ahnung habe, was resolveSkalar() macht oder was senkrechte ist.

Multithread
13.07.2013, 18:59
Da sqrt(x)/sqrt(y) = sqrt(x/y) kannst du dir mind. einmal das Wurzel ziehen sparen. Zum Rest kann ich keinen Kommentar abgeben, weil ich keine Ahnung habe, was resolveSkalar() macht oder was senkrechte ist.hmm, das ist doch schon was.

Senkrechte, das ist die Strecke vom Mittelpunkt meines Abprallenden Gegenstands zum mathematischen Mittelpunkt aller Kollisionspunkte.
meine Abprallwand ist die wand, von welcher ich abpralle und N ist diese Wand normalisiert.
V ist meine Alte Bewegungsrichtung, bzw nach der Berechnung die neue.

Wieso dessen Geschwindigkeit aber so unterschiedlich von der Ursprünglichen ist, verstehe ich auch nicht.


Allerdings gibt es noch ein Problem:
Abgeprallt wird anscheinend immer nur in Y Richtung, X ist dabei so niedrig, das keine seitliche Bewegung mehr stadtfindet.


Vektor abprallwand = resolveSkalar(senkrechte);

double value = Math.Sqrt((double)(abprallwand.X * abprallwand.X + abprallwand.Y * abprallwand.Y));
decimal[] N = new decimal[2];
N[0] = abprallwand.X / (decimal)value;
N[1] = abprallwand.Y / (decimal)value;

decimal[] V = new decimal[2] { alteRichtung.X, alteRichtung.Y };

V[0] = V[0] - 2 * ((V[0] * V[0] + V[1] * V[1]) / (N[0] * N[0] + N[1] * N[1])) * N[0] - V[0];
V[1] = V[1] - 2 * ((V[0] * V[0] + V[1] * V[1]) / (N[0] * N[0] + N[1] * N[1])) * N[1] - V[1];

decimal faktor = (decimal)(Math.Sqrt((double)((alteRichtung.X * alteRichtung.X + alteRichtung.Y * alteRichtung.Y) / (V[0] * V[0] + V[1] * V[1]))));
//faktor *= 0.98M;


V[0] *= faktor;
V[1] *= faktor;
return new Vektor(V[0], V[1]);
Mein Problem ist nun, das er entweder nur in

jabu
14.07.2013, 03:24
V[0] = V[0] - 2 * ((V[0] * V[0] + V[1] * V[1]) / (N[0] * N[0] + N[1] * N[1])) * N[0] - V[0];

Schreiben wir das mal in Schönschrift, also als Strukturkomponenten und in Pseudocode und lösen es auf:

V.x = V.x - 2 * ( (V.x * V.x + V.y * V.y) / (N.x * N.x + N.y * N.y) ) * N.x - V.x ;

V.x = V.x - V.x - 2 * |V|^2 / |N|^2 * N.x ; // Der Betrag von N ist definitionsgemäß 1, falls der Vektor wie bei dir normiert wurde.

V.x = 0 - 2 * |V|^2 / 1 * N.x ;

V.x = - 2 * |V|^2 * N.x ;

Heraus kommt also die doppelte quadrierte Geschwindigkeit, entgegengesetzt zur Richtung der Normalenkomponente N.x. Da für N.y gemäß deiner zweiten Zeile der selbe Stuss herauskommt, ist die alte Richtung ohne jeden Einfluss. Einen Sinn kann ich dahinter nicht erkennen, sehr wohl aber, dass einer vom anderen abgeschrieben hat. Denn die Berechnung wurde nicht verstanden und trotzdem steht dort die "-2", auf die man aber nicht so ohne weiteres kommt, wenn man nicht die ganze Sache durchdrungen hätte, dann aber wäre der Unsinn nicht drin. Das ist fast ein Beweis, dass unreflektiert falsch kopiert worden ist.

Den Rest kommentiere ich lieber nicht. Denn mit ein wenig Überlegung wäre klar gewesen, dass ein Quotient zweier Beträge keine Richtungsinformation beinhalten kann. Spätestens daran, dass sowohl die x- als auch die y-Komponente mit dem selben Faktor multipliziert wird, sieht man, dass etwas nicht stimmen kann.

Nochmal zu der Seite, von der du das hast:

V' = V - 2 (( V*N ) / N*N ) ) l - V

Das hinter dem Strich kennst du doch von den Äquivalenzumformungen aus der Schule, das heißt so viel wie "auf beiden Seiten V abziehen", hatte derjenige aber wohl nicht gemerkt und es als Subtraktion aufgefasst.


Du bist ja vielleicht drollig:


Wieso dessen Geschwindigkeit aber so unterschiedlich von der Ursprünglichen ist, verstehe ich auch nicht.
"Wieso mir ein Holzscheit entgegenfliegt, wenn ich feste draufhaue und kein Gartenhaus daraus wird, verstehe ich auch nicht." :rolleyes:


Allerdings gibt es noch ein Problem:
"Trotzdem bin ich fest davon überzeugt, dass es doch ein Gartenhaus ist, es gibt da nur ein winziges Problem..." :rolleyes:


Abgeprallt wird anscheinend immer nur in Y Richtung, X ist dabei so niedrig, das keine seitliche Bewegung mehr stadtfindet.
"...nämlich dass das imaginäre Dach, wovon Ihr mir jetzt einfach glauben müsst, dass es existiert, irgendwie eine Abweichung vom geplanten Neigungswinkel aufweist." :rolleyes:

LG, jabu


PS

|V|^2 = (V.x * V.x + V.y * V.y)

ist doch nichts anderes als

c^2 = a^2 + b^2

Multithread
14.07.2013, 08:06
Schreiben wir das mal in Schönschrift, also als Strukturkomponenten und in Pseudocode und lösen es auf:

V.x = V.x - 2 * ( (V.x * V.x + V.y * V.y) / (N.x * N.x + N.y * N.y) ) * N.x - V.x ;

V.x = V.x - V.x - 2 * |V|^2 / |N|^2 * N.x ; // Der Betrag von N ist definitionsgemäß 1, falls der Vektor wie bei dir normiert wurde.

V.x = 0 - 2 * |V|^2 / 1 * N.x ;

V.x = - 2 * |V|^2 * N.x ;

Heraus kommt also die doppelte quadrierte Geschwindigkeit, entgegengesetzt zur Richtung der Normalenkomponente N.x. Da für N.y gemäß deiner zweiten Zeile der selbe Stuss herauskommt, ist die alte Richtung ohne jeden Einfluss. Einen Sinn kann ich dahinter nicht erkennen, sehr wohl aber, dass einer vom anderen abgeschrieben hat. Denn die Berechnung wurde nicht verstanden und trotzdem steht dort die "-2", auf die man aber nicht so ohne weiteres kommt, wenn man nicht die ganze Sache durchdrungen hätte, dann aber wäre der Unsinn nicht drin. Das ist fast ein Beweis, dass unreflektiert falsch kopiert worden ist.

Ach shit, das kann dann nicht klappen.

Nicht unreflektiert, aber unverstanden. Wenn ich wüsste wie genau ich es rechnen muss, hätte ich es schon lange hinbekommen. Auch wenn es gerade überhaupt nicht denn Anschein hat, Mathematisch bin ich nicht ganz unbegabt.
Und was er da gerechnet hat, habe ich mir nicht angesehen, das gebe ich zu, was mich interessiert hat, was das Ergebnis. Ich gehöre nicht zu den Menschen die es riechen wenn ne Mathematischer Formel falsch ist und vertraue entsprechend mehr darauf das der Typ, von dem ich das habe, wusste was er macht.





Den Rest kommentiere ich lieber nicht. Denn mit ein wenig Überlegung wäre klar gewesen, dass ein Quotient zweier Beträge keine Richtungsinformation beinhalten kann. Spätestens daran, dass sowohl die x- als auch die y-Komponente mit dem selben Faktor multipliziert wird, sieht man, dass etwas nicht stimmen kann.

Zumindest das etwas nicht stimmen kann, habe ich gemerkt.




Nochmal zu der Seite, von der du das hast:

V' = V - 2 (( V*N ) / N*N ) ) l - V

Das hinter dem Strich kennst du doch von den Äquivalenzumformungen aus der Schule, das heißt so viel wie "auf beiden Seiten V abziehen", hatte derjenige aber wohl nicht gemerkt und es als Subtraktion aufgefasst.

Das würde heissen bis zu dem Punkt war die Formel korrekt?





Du bist ja vielleicht drollig:


"Wieso mir ein Holzscheit entgegenfliegt, wenn ich feste draufhaue und kein Gartenhaus daraus wird, verstehe ich auch nicht." :rolleyes:


"Trotzdem bin ich fest davon überzeugt, dass es doch ein Gartenhaus ist, es gibt da nur ein winziges Problem..." :rolleyes:

Das triffts ziemlich genau, mal davon agbgesehen das ich Blind auf das Stück Holz geschlagen habe, mit einem mir nicht bekannten Werkzeug.

Nach bald 3 Wochen glaube ich langsam aber nicht mehr daran, dass es jemals fertig wird, da ist das bauen eines echten Gartenhauses aus einem Baumstamm deutlich einfacher.





"...nämlich dass das imaginäre Dach, wovon Ihr mir jetzt einfach glauben müsst, dass es existiert, irgendwie eine Abweichung vom geplanten Neigungswinkel aufweist." :rolleyes:

LG, jabu

Nicht das Dach hat eine Abweichung vom Winkel, der Regen fliesst nicht in die Imaginäre Regenrinne, sondern zur Seite.





PS

|V|^2 = (V.x * V.x + V.y * V.y)

ist doch nichts anderes als

c^2 = a^2 + b^2
Ah, was ist dann c? V.x+V.y?
Ich dachte eigentlich das |V|^2 das gleiche bedeutet wie (V.x * V.x + V.y * V.y).

jabu
14.07.2013, 17:08
Ich gehöre nicht zu den Menschen die es riechen wenn ne Mathematischer Formel falsch ist und vertraue entsprechend mehr darauf das der Typ, von dem ich das habe, wusste was er macht.
Niemand weiß das wirklich, ich auch nicht.

Es hatte sich in dem Forum, wo du es her hast, keine fruchtbare Diskussion ergeben, also ist blindes Vertrauen auf Zeugs von einen Fragesteller, der gerade selbst die richtige Fährte sucht und sie offensichtlich nicht gefunden hat und auch keine treffende Antwort bekommen hat, doch mindestens fragwürdig. Wenn man eine Herleitung nicht nachvollziehen kann, sollte man nicht von ihrer Richtigkeit ausgehen. Manchmal ist auch alles richtig (hier nicht), aber die Formel bildet etwas anderes als das Gesuchte ab. Ob sie das Gesuchte abbildet, sagt dir die Formel solange nicht, bis du sie verstanden hast. Es gibt viele richtige Formeln, in die du deine Vektoren hineinschmeißen kannst, nützt nur wenig, solange du nicht nachvollziehen kannst, ob sie tun, was sie sollen.


Zumindest das etwas nicht stimmen kann, habe ich gemerkt.
Im Ergebnis, aber man sollte sich vorher damit auseinandersetzen?


Das würde heissen bis zu dem Punkt war die Formel korrekt?
Sie beruht offensichtlich auf falschem Abschreiben einer Formel, deren Autor vermutlich einiges richtig erkannt hatte. Ob die kleinen Ungereimtheiten im Original richtig waren, ist nicht mehr zu erkennen.


Nach bald 3 Wochen glaube ich langsam aber nicht mehr daran, dass es jemals fertig wird, da ist das bauen eines echten Gartenhauses aus einem Baumstamm deutlich einfacher.
Na, du hast doch keine drei Wochen damit verbracht, sondern nur deine Freizeit, oder?


Nicht das Dach hat eine Abweichung vom Winkel, der Regen fliesst nicht in die Imaginäre Regenrinne, sondern zur Seite.
Jupp, das trifft es gleich viel besser. :D

Ah, was ist dann c? V.x+V.y?
Nein Sqrt(a^2 + b^2).


Du meinst wohl das(?):

c^2 = a^2 + b^2

Da a und b zueinander senkrecht sind (sonst gilt das ja nicht), kannst du es auch als einen Vektor c(a;b) auffassen:

|c|^2 = c.a * c.a + c.b * c.b

c muss nun in Betragsstriche, weil er selbst nun ein Vektor und nicht mehr die Länge einer Hypotenuse darstellt, also müssen wir kennzeichnen, dass eben dieser Betrag gemeint ist, welcher genau der Länge der Hypotenuse des Dreiecks entspricht.

Da wir mit a,b x,y meinen, können wir das auch so schreiben:

|c|^2 = c.x * c.x + c.y * c.y

Und ob der Geschwindigkeitsvektor nun V oder c heißt, ist auch piepegal:

|V|^2 = V.x * V.x + V.y * V.y


Ich dachte eigentlich das |V|^2 das gleiche bedeutet wie (V.x * V.x + V.y * V.y).
Nun ja, da hast du es. Wenn du diese Sachen (mit etwas Übung) siehst, wird plötzlich alles ganz einfach, ist ja kein Hexenwerk.

LG, jabu

jabu
14.07.2013, 18:08
Oh, da muss ich doch noch mal einhaken:



Ah, was ist dann c? V.x+V.y?
Ich dachte eigentlich das |V|^2 das gleiche bedeutet wie (V.x * V.x + V.y * V.y).
Nein, man kann leider aus einer Summe, wie sie dort^ in der Klammer steht, nicht so einfach eine Wurzel ziehen (von einigen schrägen Kniffen mal abgesehen, wobei etwas Komplizierteres herauskommen würde).

Edit/Anmerkung: Es geht darum, dass man aus |V|^2 = (V.x * V.x + V.y * V.y) nicht folgern kann, dass V.x+V.y die Wurzel von (V.x * V.x + V.y * V.y) wäre. Trotzdem ist |V|^2 = (V.x * V.x + V.y * V.y) richtig, für Außenstehende hatte ich das nicht genügend klar ausgedrückt.

Dass es so einfach nicht gehen kann, sieht man an dieser (falschen) Behauptung:

|V| = V.x + V.y
(Dass sie unzutreffend ist, erkennt man auch sofort am Dreieck)

Na ja, das kannst du meinetwegen trotzdem noch ausmultiplizieren:
(Stichwort: "binomische Formeln")

|V|^2 = (V.x + V.y) * (V.x + V.y)
|V|^2 = V.x^2 + V.x*V.y + V.y*V.x + V.y^2
|V|^2 = V.x^2 + 2*V.x*V.y + V.y^2


V.x^2 + 2*V.x*V.y + V.y^2 = V.x*V.x + V.y*V.y
V.x^2 + 2*V.x*V.y + V.y^2 = V.x^2 + V.y^2 | - (V.x^2 + V.y^2)
2*V.x*V.y = 0 | :2
V.x*V.y = 0

Lösungen: V.x = 0 ; V.y = 0

Man sieht, dass außer in Spezialfällen, für die sich der ganze Aufwand bekanntlich nicht lohnt (wir haben gar kein Dreieck), Falsches herauskommt. Also ist die gesamte Aussage falsch.

Der Umstand, dass eine Maschine, ein Programm oder sonstwas sich erwartungsgemäß verhält, bedeutet also noch lange nicht, dass dieses immer der Fall (allgemeingültig) wäre. Sieht man sich lediglich die Fälle an, bei denen V.x oder V.y Null ist, fällt nichts auf. Aus einer falschen Berechnung kann im Einzelfall etwas Richtiges resultieren.

Und dann wundert man sich womöglich, welche Kleinigkeit noch falsch wäre, weil ja schon irgendwas geht. In Wahrheit ist der ganze Ansatz falsch, sodass man wertvolle Stunden vergeudet, indem man daran festhält.

Damit will ich nicht sagen, dass dieser falsche Ansatz bei dir drin wäre, sondern anhand einer Parallele aufzeigen, wie blöd und irreführend das sein kann, wenn irgendwie etwas fast Plausibles herauskommt.

Also am besten schnell vergessen, was da oben steht. ;)

Multithread
14.07.2013, 18:36
hmmm, also wieder ne sackgasse.


Bleibt noch die idee ausm anderen Thread, hab sie mal hier gepostet, der Vollständigkeit halber.



Der Kniff besteht jetzt darin, den Betrag, den der Vektor längs entgegengesetzt zur Normalen zurücklegt, wieder "zurückzugehen", sodass er in Gegenrichtung zur Normalen nicht mehr wirkt. Und wenn wir diesen Betrag erst einmal wissen, dann können wir eben nochmal genau so ein Stück in Richtung der Normalen zurückgehen, was exakt der neuen Richtung entspricht. Das solltest du erstmal skizzieren und verstehen, denn es ist die Lösung!

Also indem ich das Skalarprodugt aus alte Bewegungsrichtung und senkrechte nochmals weg von der Bewegungsrichtung mache?

Bliebe wieder mal die Mathe dahinter über, sofern diese Überlegung überhaupt richtig ist.

Kannst du mir sagen ob Folgendes richtig ist?


decimal skalarSenkrechteBewegungsrichtung = (alteRichtung.X * N[0] + alteRichtung.Y * N[1]);
Wobei
1. alteRichtung die bisherigen Bewegungsrichtung ist.
2. N ist die normalisierte (Länge 1) senkrechte zur Abprallwand.
EDIT: wenn ich das ausm anderen Thread richtig sehe, muss ich danach noch die wurzel aus skalarSenkrechteBewegungsrichtung ziehen damit ich effektiv den Skalar habe.

jabu
26.07.2013, 21:28
Dann mache ich hier nach langer Zeit mal wieder einen Anfang:


[...]
Es hat Froschschenkel \\o//
passt zum Thema, wenn man diese^ als Vektoren interpretiert, also links zwei zueinander parallele Vektoren, welche jeweils an einer gedachten Mittelachse gespiegelt sind, welche durch ein Osterei skizziert ist. :D


Nach mehr suche ich noch§ugly
§kratz Das ist doch überdeutlich:



|
|
|
|
| Kante
|
/|\ |
/ | \ → |
/ | \ a |
/ | \ |
/ (*|*) \,
<--------------------- Normalenvektor
<- Normaleneinheitsvektor

Vektor a(x;y) weist schräg nach unten.
Die gesamte Skizze ist gegenüber dem
Koordinatensystem als beliebig verdreht
anzusehen.
Die Wand/Kante kann beliebig weit
entfernt sein.

Multithread
26.07.2013, 22:02
Da es für mich reichlich konfus klingt, äußere ich mich erst jetzt zu deinen durchgestrichenen Sachen:

Super, das richtige habe ich demnach wohl schon geschrieben:C:




Da stecken gute Grundgedanken drin, wenn auch nicht alles hundertprozentig richtig ist. Aber bevor du dich in einem Geflecht von Punkten, Strecken usw. verhedderst, ginge es doch erstmal um die Beantwortung einer einfachen Frage:

was haben wir vorher über punkte gesagt?§nana




Was siehst du, bzw. welche Erkenntnis liefert das Umklappen des Dreiecks?
Sofern das Uhrsprungsreiech einen Rechten Winkel hatte, und wir nicht über die Hypothenuse kippen, erhalten wir ein Gleichschenkliges Dreieck$§p4



passt zum Thema, wenn man diese^ als Vektoren interpretiert, also links zwei zueinander parallele Vektoren, welche jeweils an einer gedachten Mittelachse gespiegelt sind, welche durch ein Osterei skizziert ist. :D


§kratz Das ist doch überdeutlich:



|
|
|
|
| Kante
|
/|\ |
/ | \ → |
/ | \ a |
/ | \ |
/ (*|*) \,
<--------------------- Normalenvektor
<- Normaleneinheitsvektor

Vektor a(x;y) weist schräg nach unten.
Die gesamte Skizze ist gegenüber dem
Koordinatensystem als beliebig verdreht
anzusehen.
Die Wand/Kante kann beliebig weit
entfernt sein.

überdeutlich ist da leider für mich nichts:dnuhr:
ich habe a→ und n→

Jetzt könnte ich natürlich so lange an n→ entlanggehen, bis ich einen Vektor finde der gleich lang ist wie a→, das ist aber sicher nicht sinn der Übung.

Für ein rechtwinkliges Dreieck reicht es auch nicht, da ich nicht weiss wie lang n→ ist.

zumindest die richtung von n→ sollte man berechnen können aufgrund von a→ und deinem Osterei:p

Und sobald ich den winkel zwischen a→ und n→ berechne, arbeite ich wieder mit Winkeln, aber dann könnte ich das rechtwinklige Dreieck berechnen.


n→ verläuft übrigens immer parallel zur kante und nicht senkrecht dazu.

jabu
26.07.2013, 23:13
was haben wir vorher über punkte gesagt?§nana
Das^ ist unlogisch. Denn wenn ich dich vor einem Verheddern darin bewahren möchte, bedeutet das doch, dass ich davon abrate. Du warnst also den Falschen.


Sofern das Uhrsprungsreiech einen Rechten Winkel hatte, und wir nicht über die Hypothenuse kippen, erhalten wir ein Gleichschenkliges Dreieck$§p4
Von dieser Senkrechte sprichst du doch die ganze Zeit. Es ist also dein Postulat. Und weil deine Idee anschlussfähig ist, habe ich mich in deine Perspektive versetzt, diese (deine) Idee aufgegriffen und sie zur Grundlage einer geometrischen Interpretation gemacht. Jede geometrische Interpretation läuft auf das selbe hinaus, daher können wir gerne daran drehen und wenden, solange der Aufwand nicht spürbar größer wird.


überdeutlich ist da leider für mich nichts:dnuhr:
ich habe a→ und n→
... was völlig genügt. Im Grunde genügen a→ und n0→ (Normaleneinheitsvektor).


Jetzt könnte ich natürlich so lange an n→ entlanggehen, bis ich einen Vektor finde der gleich lang ist wie a→, das ist aber sicher nicht sinn der Übung.
interessant...


Für ein rechtwinkliges Dreieck reicht es auch nicht, da ich nicht weiss wie lang n→ ist.
...muss niemand wissen. Die Skizze ist rein schematisch zu verstehen, Größen sind also egal. Meinetwegen kannst du n→ einen hunderttausendstel mm kurz machen. Das ändert nichts an der Sache, allein die Richtungsinformation genügt.


Und sobald ich den winkel zwischen a→ und n→ berechne, arbeite ich wieder mit Winkeln, aber dann könnte ich das rechtwinklige Dreieck berechnen.
Wenn du wüsstest, was ein Skalarprodukt ist, würde dir jetzt allein anhand der Skizze wie Schuppen von den Augen fallen, dass man den Winkel nicht zu wissen braucht.


n→ verläuft übrigens immer parallel zur kante und nicht senkrecht dazu.
Da muss ich dich leider korrigieren, der Normalenvektor ist so definiert, dass er senkrecht zu einer Geraden verläuft. Und wenn die bei mir in der Wand verläuft, ist das völlig in Ordnung. Kommerzielle 3D-Engines machen das übrigens genau so mit den Kanten bzw. Flächen ihrer Dreiecke (Triangles), welche aus den Dreieckspunkten (Vertices) definiert sind. Dreidimensional ist die Berechnung der Normalen deutlich aufwändiger. Aber man macht es eben nur einmal. Dafür spart man sich später etliche Kreuzprodukte.

Selbstverständlich kannst du anders vorgehen. Aber solange du kein Konzept hast, bist du nicht schlecht bedient, mit Bekanntem vorliebzunehmen. Trotzdem ist der Normalenvektor immer eine Senkrechte. Meinetwegen kannst du machen was du willst und den Normalenvektor zum Normalenvektor berechnen, sodass er wieder in der Wand liegt, ist mir alles egal, solange du davon profitierst.

jabu
26.07.2013, 23:37
Und sobald ich den winkel zwischen a→ und n→ berechne, arbeite ich wieder mit Winkeln, aber dann könnte ich das rechtwinklige Dreieck berechnen.
Bevor du wieder alles so ganz easy findest: Natürlich bekommst du dann die Längen (Beträge der Vektoren) heraus. Aber weißt du dann auch, wie diese zum Koordinatensystem orientiert sind? Nein, nicht automatisch. Wir haben es ja mit schrägen Kanten zu tun, weshalb es der bloße Winkel zur Senkrechte nicht mehr tut. Also bräuchtest du wenigstens einen Hilfswinkel und hier und dort noch einen, um daraus wieder deine Vektorkomponenten zu berechnen. Und du vergisst, dass die Winkelfunktionen nicht eineindeutig sind. Also hast du die ganzen Fallunterscheidungen drin, was im Einzelfall bedeuten kann, dass du aufgrund des Informationsverlustes nicht mehr weißt, in welche Richtung der Vektor nun zeigt. Viel Spaß mit Hilfswinkeln, Zusatzparametern für die Quadranten, in denen sich das abspielt sowie redundanten Vor- und Zurückberechnungen zwischen Polarform und kartesischen Koordinaten.

Warum einfach, wenn's auch kompliziert geht? Aber anscheinend musst du da durch, sonst würdest du nicht immer wieder damit um die Ecke kommen. :rolleyes:

Edit:

Falls du mit der Warnung meinst, dass du bereits bestens über die freien Vektoren im Bilde bist und ich dich deswegen nicht immer so blöde ansprechen soll, dann ist das natürlich akzeptiert. So hatte ich das nicht gemeint. :gratz

Die Sache, dass ich so auf dem Normalenvektor beharre, hat tiefer liegende Gründe, die du erst verstehen kannst, wenn du das Ganze einige Male aus verschiedenen Perspektiven durchmessen hast. Ganz stark vereinfacht gesagt, läuft es darauf hinaus, dass
in 2D eine plausible Lösung ohne Normalenvektor, dafür aber mit dem "Wandvektor" möglich ist, welche sich erst mit einigem analytischen Aufwand als Spezialfall für zweidimensionale Systeme entpuppt. Wenn man das in Vektorschreibweise hier hinpostet, muss man automatisch davon ausgehen, das die Randbedingung nicht verstanden wird, sich der Käse im Schweinsgalopp durchs Netz verbreitet und wir schließlich mit verbugten Amateurprojekten leben müssen. Einfachheit kann so verführerisch sein, auch wenn sie falsch ist. Besonders ärgerlich ist dabei, dass die Ersparnis an Berechnungen nahe Null ist. Korrigiert man den Fehler, hat man es wieder mit dem Normalenvektor zu tun und erhält wieder das selbe wie bei meiner Betrachtung sowie der aus dem Spieleprogrammiererforum. Irgendwann kommt der Punkt, an dem der minimale Zusatzaufwand zur Berechnung des Normalenvektors (der in 2D eigentlich kein nennenswerter ist) an anderer Stelle durch Eleganz, Einfachheit und Performance nicht nur wieder ausgeglichen wird, sondern seinen Aufwand gleich mehrfach wieder einspielt. Aus einer globalen Sicht, die du noch nicht haben kannst, erweist sich das Vorgehen als äußerst effizient, weshalb du kaum eine professionelle Grafikengine finden wirst, die das nicht implementiert.

jabu
27.07.2013, 13:50
Hier noch ein Wink:


|
|
|
|
| Kante
|
/|\ |
/ | \ → |
/ | \ a |
/ | \ |
/ (*|*) \, →
<--------------------- Normalenvektor n →
\ (*|*) / <- Normaleneinheitsvektor n0
\ | /
\ | / →
\ | / a'
\|/
´

Wenn sich der Vektor a→ verändert,
skaliert einfach alles andere mit,
sodass sich kein Problem ergibt.

Eigentlich wollte ich dir das^ nicht vorwegnehmen, um deine Freude am Lösungsweg nicht zu schmälern, aber nun gut. Vektor a' ist doch der gesuchte, reflektierte Vektor. Nun dürfte ein Lösungsansatz aufgrund einfacher Vektoraddition unter Verwendung des Skalarproduktes auf der Basis von a→ und n0→ ersichtlich sein.

Multithread
27.07.2013, 15:27
Bevor du wieder alles so ganz easy findest: Natürlich bekommst du dann die Längen (Beträge der Vektoren) heraus. Aber weißt du dann auch, wie diese zum Koordinatensystem orientiert sind? Nein, nicht automatisch. Wir haben es ja mit schrägen Kanten zu tun, weshalb es der bloße Winkel zur Senkrechte nicht mehr tut. Also bräuchtest du wenigstens einen Hilfswinkel und hier und dort noch einen, um daraus wieder deine Vektorkomponenten zu berechnen. Und du vergisst, dass die Winkelfunktionen nicht eineindeutig sind. Also hast du die ganzen Fallunterscheidungen drin, was im Einzelfall bedeuten kann, dass du aufgrund des Informationsverlustes nicht mehr weißt, in welche Richtung der Vektor nun zeigt. Viel Spaß mit Hilfswinkeln, Zusatzparametern für die Quadranten, in denen sich das abspielt sowie redundanten Vor- und Zurückberechnungen zwischen Polarform und kartesischen Koordinaten.

Warum einfach, wenn's auch kompliziert geht? Aber anscheinend musst du da durch, sonst würdest du nicht immer wieder damit um die Ecke kommen. :rolleyes:
leider.



Hier noch ein Wink:


|
|
|
|
| Kante
|
/|\ |
/ | \ → |
/ | \ a |
/ | \ |
/ (*|*) \, →
<--------------------- Normalenvektor n →
\ (*|*) / <- Normaleneinheitsvektor n0
\ | /
\ | / →
\ | / a'
\|/
´

Wenn sich der Vektor a→ verändert,
skaliert einfach alles andere mit,
sodass sich kein Problem ergibt.

Eigentlich wollte ich dir das^ nicht vorwegnehmen, um deine Freude am Lösungsweg nicht zu schmälern, aber nun gut. Vektor a' ist doch der gesuchte, reflektierte Vektor. Nun dürfte ein Lösungsansatz aufgrund einfacher Vektoraddition unter Verwendung des Skalarproduktes auf der Basis von a→ und n0→ ersichtlich sein.
Du hast nur die Vektoraddition erwähnt, ergo keine Multiplikationen (ausser dem Skalarprodukt)

Ich nehme mal an, ich sollte nicht einfach

Are you fucking kidding me?


Vektor abprallwand = resolveSkalar(senkrechte);

double value = Math.Sqrt((double)(senkrechte.X * senkrechte.X + senkrechte.Y * senkrechte.Y));
decimal[] N = new decimal[2];
N[0] = senkrechte.X / (decimal)value;
N[1] = senkrechte.Y / (decimal)value;

decimal skalarSenkrechteBewegungsrichtung = (alteRichtung.X * N[0] + alteRichtung.Y * N[1]);

return new Vektor(N[0] * alteRichtung.X, N[1] * alteRichtung.Y);?

Was jetzt noch nicht geht: kollisionen wo ein teil der Bewegungsrichtung mal negativ war, ich gehe jetzt vorerst mal davon aus das die return Zeile immer noch nicht korrekt ist.

jabu
27.07.2013, 20:11
Du hast nur die Vektoraddition erwähnt, ergo keine Multiplikationen (ausser dem Skalarprodukt)
Ich habe lediglich die dir längst bekannten Grundoperationen erwähnt, auf denen du aufbauen kannst. Mit wenigen Worten mehr hätte ich die gesamte Berechnung verraten (worauf du hinaus willst, was ich aber gar nicht einsehe, weil es nicht gut für dich wäre).


Ich nehme mal an, ich sollte nicht einfach
Ja, was denn nicht?


Are you fucking kidding me?
Ironiefreies "Nein", habe ich auch seit Beginn unserer Konversation nicht getan.




// Code ohne Effekt, hatte im Original leider, je nach Kontext,
// mehr oder minder konfuse Dinge getan
Vektor abprallwand = resolveSkalar(senkrechte);

// Betragsbildung von senkrechte
double value = Math.Sqrt((double)(senkrechte.X * senkrechte.X + senkrechte.Y * senkrechte.Y));

decimal[] N = new decimal[2];

// Normierung von senkrechte auf den Betrag eins (Einheitsvektor zu senkrechte)
N[0] = senkrechte.X / (decimal)value;
N[1] = senkrechte.Y / (decimal)value;

// Code ohne Effekt,
// ansonsten Berechnung des Skalarproduktes aus N und alteRichtung
// Was das Skalarprodukt geometrisch bedeutet, hast du mir immer noch nicht gesagt,
// aber genau darauf kommt es an.
decimal skalarSenkrechteBewegungsrichtung = (alteRichtung.X * N[0] + alteRichtung.Y * N[1]);

// Eine interessante Operation, leider ohne Nutzen
// Ein Beispiel, gegeben sei:
// N[0] = 0.7071; N[1] = 0.7071;
// Der gewählte Normaleneinheitsvektor N ändert
// dort unten niemals etwas an der Richtung,
// ganz egal, wie alteRichtung orientiert ist.
// Also kann das nicht stimmen.
return new Vektor(N[0] * alteRichtung.X, N[1] * alteRichtung.Y);?


Was jetzt noch nicht geht: kollisionen wo ein teil der Bewegungsrichtung mal negativ war,
Du sprichst so wie jemand, der ein fast perfektes Werk vollendet hat, bei dem nur eine winzige Kleinigkeit nicht funktioniert. Das entspricht aber nicht den Tatsachen. Und das weißt du. Das Thema hatten wir schon zur Genüge durch, aber es ändert sich nichts, also nochmal: Du kannst nicht, nachdem du bloß mit der Axt auf Holzscheiten herumgekloppt hast, davon ausgehen, dass an deiner (imaginären) Hütte die Dachneigung nur ein winziges bisschen aus der Kehre ist. Du hast keine Hütte geplant und keine gebaut. Natürlich kannst du dir deine imaginäre Hütte vorstellen und dich freuen, kein Problem. ;)


ich gehe jetzt vorerst mal davon aus das die return Zeile immer noch nicht korrekt ist.
Ist ebenso witzig. Und ich muss jedes Mal überlegen, ob du nicht einen Zufallstreffer gelandet hast und dediziert darlegen, dass dem nicht so sein kann. Also tue mir bitte einen Gefallen und höre mit dem Raten auf bzw. behalte sowas für dich!

Es liegt nicht an mir, wann du dich erstmals mit den Skizzen beschäftigst, meine Tipps beherzigst und dir erstmals überlegst, was ein Skalarprodukt denn wirklich ist (nicht was auf dem Papier steht). Dann fehlt dir nichts mehr. Solange du das nicht tust, werde ich vorerst keinen Code mehr ansehen, weil es nur unnötig wertvolle Energie und Zeit bindet.

So, dann guten Erfolg! :)

Multithread
28.07.2013, 08:08
Ich habe lediglich die dir längst bekannten Grundoperationen erwähnt, auf denen du aufbauen kannst. Mit wenigen Worten mehr hätte ich die gesamte Berechnung verraten (worauf du hinaus willst, was ich aber gar nicht einsehe, weil es nicht gut für dich wäre).

Die Lösung scheint echt vor meiner Nase zu liegen...





Du sprichst so wie jemand, der ein fast perfektes Werk vollendet hat, bei dem nur eine winzige Kleinigkeit nicht funktioniert. Das entspricht aber nicht den Tatsachen. Und das weißt du. Das Thema hatten wir schon zur Genüge durch, aber es ändert sich nichts, also nochmal: Du kannst nicht, nachdem du bloß mit der Axt auf Holzscheiten herumgekloppt hast, davon ausgehen, dass an deiner (imaginären) Hütte die Dachneigung nur ein winziges bisschen aus der Kehre ist. Du hast keine Hütte geplant und keine gebaut. Natürlich kannst du dir deine imaginäre Hütte vorstellen und dich freuen, kein Problem. ;)

Interessant das ich anscheinend des öfteren diesen Eindruck vermittle, ich sollte ins Marketing wechseln:o
It's a feauture, not a bug:D




Ist ebenso witzig. Und ich muss jedes Mal überlegen, ob du nicht einen Zufallstreffer gelandet hast und dediziert darlegen, dass dem nicht so sein kann. Also tue mir bitte einen Gefallen und höre mit dem Raten auf bzw. behalte sowas für dich!

Ich glaube nicht das ich die letzten wochen mal keinen Zufallstreffer gelandet habe, aber du weisst ja was man über blinde Hühner sagt§ugly




Es liegt nicht an mir, wann du dich erstmals mit den Skizzen beschäftigst, meine Tipps beherzigst und dir erstmals überlegst, was ein Skalarprodukt denn wirklich ist (nicht was auf dem Papier steht). Dann fehlt dir nichts mehr. Solange du das nicht tust, werde ich vorerst keinen Code mehr ansehen, weil es nur unnötig wertvolle Energie und Zeit bindet.

So, dann guten Erfolg! :)
Das Skalarprodukt beinhaltet unter anderem de Winkel, der ist da also drin.:dnuhr:
Der Cosinussatz ist laut wiki die veralgemeinerung des Satzes von Pythagoras. ->
Anbgenommen 90° entsprechen einem pass by(keine kollision, oder nur eine streifende ohne abprallen), und 0° dem Quadrat seiner Länge ->
x = n→ * a→ - 2 * (n→-a→), damit zeigt der resultierende Pfeil von a→ nach n→ ->
wenn ich jetzt x durch die strecke von a→ teile (n→ ist ein normalvektor, also 1, div durch 1 kann man sich sparen), bekomme ich denn winkel zwischen a→ und n→ mithilfe der Cosinusfunktion, das war wohl das was Daeliphin mir versucht hat zu erklären. ->
In dem Fall bliebe genau ein 2tes Resultat, da es immer 2 Cosinus mit dem gleichen Winkel gibt (30 und 150, 15 und 165,...). Aber da wir gesagt haben das wir es ohne winkel könne, oder besser du, ist das wieder der falscher richtige ansatz.

E: ich hab was: da ich zweimal durch den Cosinus müsste, kann ich den doch eigentlich rausstreichen, so wie man das mit -1+1 macht. dann kann ich mit dem Skalarprodukt den 2ten Winkel rausbekommen mit 'simpler' algebra?

jabu
28.07.2013, 16:57
Die Lösung scheint echt vor meiner Nase zu liegen...
Nun ja, so ist es.


Interessant das ich anscheinend des öfteren diesen Eindruck vermittle, ich sollte ins Marketing wechseln:o
It's a feauture, not a bug:D
Nicht doch... :D


Ich glaube nicht, dass ich die letzten wochen mal keinen Zufallstreffer gelandet habe, aber du weisst ja was man über blinde Hühner sagt§ugly
Wenn man die miteinander kombiniert, ist die Wahrscheinlichkeit, dass das auch wieder stimmt, noch viel geringer (soweit es sich um voneinander unabhängige Zufallstreffer handelt)...

Ah, jetzt fängt die Maschine an zu rattern, das ist gut! Allerdings tut es mir gerade wirklich weh, deine ansonsten recht interessanten Überlegungen zum Kosinus einfach so zur Seite zu wischen. Wenn ich darauf eingehen würde, müsste ich alles auseinandernehmen, kommentieren, korrigieren usw., sodass sich hier wieder eine seitenlange Diskussion über Wege ergeben würde, welche nicht zu Ziel führen. Deine Gleichung enthält leider mindestens einen Fehler (Subtraktion eines Vektors von einem Skalar), sorry, wenn ich jetzt nicht darauf eingehen möchte, es wäre einfach weder effektiv noch efizient, damit weiterzumachen. Lassen wir den Kosinussatz mal außen vor, obwohl er interessant ist und man ihn hier auch mit einbeziehen könnte, aber es ist gar nicht nötig, das ist ja der Witz an der Sache.

Was ich nicht verstehe, ist dein Beharren an den Winkelfunktionen, das geht einfach nicht in meinen Kopf.


Als erstes empfiehlt es sich doch, herauszufinden, womit man es überhaupt zu tun hat, bei so einer Reflektion. Was passiert da eigentlich?

Am besten befasst du dich erstmal mit der ungestörten Überlagerung. Auf Wikipedia ist das aber, wie so oft, viel zu kompliziert dargestellt und nichts erklärt, ich hasse diese Müllhalde, wo irgendwelche frustrierten Möchtegerndozenten aus Mathebüchern abschreiben. Was nützen einem reine Formalismen, die ein Ergebnis beschreiben, ohne den Sachverhalt in seinem Wesen darzustellen.
Und so ist es wieder einmal, das Wikipedia (https://de.wikipedia.org/wiki/Superposition_%28Physik%29) eher zur Verwirrung als zur Aufklärung beiträgt. Ungestörte Überlagerung kann man auch ohne Mathe-Leistungskurs verstehen, z.B. so (das berühmte Beispiel mit dem Fluss):




--->
____________________________________________Ufer/Abprallwand
↑ /`
| /
| /
|/
Fließrichtung -> (Boot)

____________________________________________Ufer




Das Boot strebt auf kürzestem Weg, also orthogonal zum Ufer. Dazu kommt die Fließrichtung des Flusses, mit der es abgetrieben wird, sodass das Boot nicht mehr am beabsichtigten Punkt aufkommt, sondern etwas weiter flussabwärts (hier rechts davon). Die resultierende Bewegung verläuft also schräg.

Es spielt jetzt für die Ankunftszeit des Bootes am anderen Ufer keine Rolle, ob es abgetrieben wird. Man spricht hier von einer ungestörten Überlagerung. Auch der Weg in der angepeilten Richtung ändert sich nicht. Zwar wird das Boot jetzt vom Betrag her schneller, ist aber senkrecht zum Ufer immer noch genauso schnell/langsam, als würde es nicht abgetrieben.

Wenn wir jetzt den resultierenden ("schrägen") Vektor ansehen, können wir ihn immer wieder in seine Komponenten zerlegen, einmal den Vektor in Fahrtrichtung, senkrecht zum Ufer und einmal in Fließrichtung des Flusses, also parallel zum Ufer.

Dabei spielt es keine Rolle, ob die Bewegung überhaupt so zustande gekommen ist! Man kann den Vektor immer in diese Anteile zerlegen! Einzige Bedingung ist, dass zu diesem Vektor selbst auch mindestens einer der beiden anderen zueinander senkrechten Vektoren gegeben ist, also beispielsweise der in Richtung zum Ufer, wobei man sagen muss, dass die reine Richtungsinformation genügt. Es ist also nicht einmal nötig, den Betrag des Vektors in Fahrtrichtung zu wissen, man kann ihn getrost auf den Betrag 1 normieren oder einen beliebigen anderen Vektor verwenden, der parallel zu ihm verläuft. Aber vorerst belasten wir uns nicht damit.

ResultierendeGeschwindigkeit(x;y) = Fließgeschwindigkeit(x;y) + Fahrtgeschwindigkeit(x;y)

Es ist eine einfache Addition beider Vektoren. Man benötigt keinerlei Winkelfunktionen. Das ist doch der Vorteil der Komponentenschreibweise.

Jetzt stellen wir uns vor, dass das Boot, wenn es am anderen Ufer angekommen ist, gleich eine Kehrtwende macht:




___________________________________________Ufer/Abprallwand
--->Umkehrpunkt
↑ / \
| / | \
| / | \
|/ ↓ \,
--->
___________________________________________Ufer



Also begibt es sich wieder direkt in Richtung des Ufers, nur in diesem Fall zum entgegengesetzten. Dir wird sicher schon aufgefallen sein, dass die Richtung zum Ufer hin immer exakt entgegengesetzt zu seinem Normalenvektor ist und vom Ufer weg immer exakt der Richtung des Normalenvektors entspricht.

An der Fließrichtung sowie Fließgeschwindigkeit hat sich aber niemals etwas geändert, das Boot wird auch beim Ablegen von der anderen Seite in die selbe Richtung abgetrieben!

Nur die Richtung bzw. Geschwindigkeit zum Ufer hin hat sich um 180° gedreht, was dem Gegenvektor der Fahrtgeschwindigkeit entspricht, also Multiplikation mit dem Skalar -1 bzw. komponentenweise Multiplikation mit -1, was seiner Subtraktion entspricht:


ResultierendeGeschwindigkeit(x;y) = Fließgeschwindigkeit(x;y) + Fahrtgeschwindigkeit(x;y)

ResultierendeGeschwindigkeit(x;y)' = Fließgeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y) <--- hier einsetzen!

Die beiden Zeilen^ sind wohl einleuchtend (ResultierendeGeschwindigkeit(x;y)' ist die nach dem Ablegen).


Jetzt sagen wir, wir wüssten die Fließgeschwindigkeit überhaupt nicht, dafür aber die (alte)
ResultierendeGeschwindigkeit(x;y)

ResultierendeGeschwindigkeit(x;y) = Fließgeschwindigkeit(x;y) + Fahrtgeschwindigkeit(x;y)
<=>
Fließgeschwindigkeit(x;y) = ResultierendeGeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y) ---^ da oben einsetzen


und setzen ein, s.o.:

ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y)
<=>
ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - 2 * Fahrtgeschwindigkeit(x;y)


Geometrisch sieht das dann so aus:



___________________________________________Ufer/Abprallwand
--->
↑ /↑
| / |
| / |
|/ |
\ ↑
\ |
\ |
\|
___________________________________________Ufer




Na, klingelts? §xmas


Das alles liegt nun auf einem silbernen Tablett vor dir. Jetzt kommt es darauf an, dass du das Gelernte auch übertragen kannst (nicht raten, sondern logisch schließen!!!), also zu unserem konkreten Problem:



|
|
|
|
| Kante
|
/|\ |
/ | \ → |
/ | \ a |
/ | \ |
/ (*|*) \, →
<--------------------- Normalenvektor n →
\ (*|*) / <- Normaleneinheitsvektor n0
\ | /
\ | / →
\ | / a'
\|/
´



Fragen:


Welcher Anteil von a→ ändert sich (bitte farblich markieren und begründen)?
Welcher Anteil von a→ bleibt erhalten (bitte farblich markieren und begründen)?
(Der bleibende Anteil wäre in 3D eine Fläche, hier in 2D ist es ein Vektor, also kein Problem das einzuzeichnen)
Die restlichen Fragen stellst du dir selbst, ich lese sie mir gerne durch.


Selbstverständlich gibt es noch einen kleinen Teil, den du selbstständig herleiten musst. Natürlich hat der etwas mit dem Skalarprodukt zu tun, aber bitte nicht wieder raten, und bitte nicht wieder das Dach vor dem Keller bauen! Nein, ich habe dir nicht extra das Beispiel mit dem Boot so herum gedreht, wie du es brauchst, genauso wenig, wie ich die Wand/Kante mitten in die Raute gezeichnet habe, obwohl man das tun könnte. Ich rate dringend davor ab, weil sowas die Entstehung von Fehlannahmen, Spezialfällen sowie überflüssigen Punkten befördern kann. Vermutlich wirst du im Netz so schnell keine andere Erklärung finden, die so im Detail auf deine Problemstellung eingeht wie diese. Auch Mathebücher behandeln selten so spezielle Problemstellungen, eher Bücher zur Physik sowie zur Spieleprogrammierung. Die gehen dann weniger auf deine Belange ein, sind dafür aber noch gründlicher. Falls du also nichts Besseres hast, empfehle ich wärmstens, dieses kleine Tutorial anzunehmen. Fehlermeldungen und Korrekturen werden natürlich gerne angenommen.

Weiterhin viel Spaß!
LG, jabu

Multithread
29.07.2013, 20:33
Ich habe stark das gefühl, am ende habe ich sowas:


V[0] = V[0] - 2 * ((V[0] * V[0] + V[1] * V[1]) / (N[0] * N[0] + N[1] * N[1])) * N[0] - V[0];
V[1] = V[1] - 2 * ((V[0] * V[0] + V[1] * V[1]) / (N[0] * N[0] + N[1] * N[1])) * N[1] - V[1];
hoffentlich aber ohne Rechenfehler:o



Nicht doch... :D

Stimmt, das überlasse ich den Profis, unser Firmeninhaber könnte Öfen in der Sahara verkaufen$§p4




Wenn man die miteinander kombiniert, ist die Wahrscheinlichkeit, dass das auch wieder stimmt, noch viel geringer (soweit es sich um voneinander unabhängige Zufallstreffer handelt)...

Wie war das noch mit den Affen die Shakespear tippen?:D




Ah, jetzt fängt die Maschine an zu rattern, das ist gut! Allerdings tut es mir gerade wirklich weh, deine ansonsten recht interessanten Überlegungen zum Kosinus einfach so zur Seite zu wischen. Wenn ich darauf eingehen würde, müsste ich alles auseinandernehmen, kommentieren, korrigieren usw., sodass sich hier wieder eine seitenlange Diskussion über Wege ergeben würde, welche nicht zu Ziel führen. Deine Gleichung enthält leider mindestens einen Fehler (Subtraktion eines Vektors von einem Skalar), sorry, wenn ich jetzt nicht darauf eingehen möchte, es wäre einfach weder effektiv noch efizient, damit weiterzumachen. Lassen wir den Kosinussatz mal außen vor, obwohl er interessant ist und man ihn hier auch mit einbeziehen könnte, aber es ist gar nicht nötig, das ist ja der Witz an der Sache.

Da hat man einmal ne gute idee,.... :D




Was ich nicht verstehe, ist dein Beharren an den Winkelfunktionen, das geht einfach nicht in meinen Kopf.


ka, ich komme jedesmal vom Skalarprodukt wieder auf den Winkel:(




Als erstes empfiehlt es sich doch, herauszufinden, womit man es überhaupt zu tun hat, bei so einer Reflektion. Was passiert da eigentlich?

Am besten befasst du dich erstmal mit der ungestörten Überlagerung. Auf Wikipedia ist das aber, wie so oft, viel zu kompliziert dargestellt und nichts erklärt, ich hasse diese Müllhalde, wo irgendwelche frustrierten Möchtegerndozenten aus Mathebüchern abschreiben. Was nützen einem reine Formalismen, die ein Ergebnis beschreiben, ohne den Sachverhalt in seinem Wesen darzustellen.
Und so ist es wieder einmal, das Wikipedia (https://de.wikipedia.org/wiki/Superposition_%28Physik%29) eher zur Verwirrung als zur Aufklärung beiträgt. Ungestörte Überlagerung kann man auch ohne Mathe-Leistungskurs verstehen, z.B. so (das berühmte Beispiel mit dem Fluss):

Wie war das noch mit den Affen die Shakespear tippen?:D







--->
____________________________________________Ufer/Abprallwand
↑ /`
| /
| /
|/
Fließrichtung -> (Boot)

____________________________________________Ufer



*-*





Das Boot strebt auf kürzestem Weg, also orthogonal zum Ufer. Dazu kommt die Fließrichtung des Flusses, mit der es abgetrieben wird, sodass das Boot nicht mehr am beabsichtigten Punkt aufkommt, sondern etwas weiter flussabwärts (hier rechts davon). Die resultierende Bewegung verläuft also schräg.

Es spielt jetzt für die Ankunftszeit des Bootes am anderen Ufer keine Rolle, ob es abgetrieben wird. Man spricht hier von einer ungestörten Überlagerung. Auch der Weg in der angepeilten Richtung ändert sich nicht. Zwar wird das Boot jetzt vom Betrag her schneller, ist aber senkrecht zum Ufer immer noch genauso schnell/langsam, als würde es nicht abgetrieben.

Wenn wir jetzt den resultierenden ("schrägen") Vektor ansehen, können wir ihn immer wieder in seine Komponenten zerlegen, einmal den Vektor in Fahrtrichtung, senkrecht zum Ufer und einmal in Fließrichtung des Flusses, also parallel zum Ufer.

Dabei spielt es keine Rolle, ob die Bewegung überhaupt so zustande gekommen ist! Man kann den Vektor immer in diese Anteile zerlegen! Einzige Bedingung ist, dass zu diesem Vektor selbst auch mindestens einer der beiden anderen zueinander senkrechten Vektoren gegeben ist, also beispielsweise der in Richtung zum Ufer, wobei man sagen muss, dass die reine Richtungsinformation genügt. Es ist also nicht einmal nötig, den Betrag des Vektors in Fahrtrichtung zu wissen, man kann ihn getrost auf den Betrag 1 normieren oder einen beliebigen anderen Vektor verwenden, der parallel zu ihm verläuft. Aber vorerst belasten wir uns nicht damit.

Soweit erstmal logisch. ich akzeptiere erstmal einfach das man den Fahrtrichtungsvecktor auf 1 Nomieren kann, ich habe das Gefühl da später ev noch schlau draus zu werden. Gedankengänge mal logisch in einer Reihenfolge aufstellen:




ResultierendeGeschwindigkeit(x;y) = Fließgeschwindigkeit(x;y) + Fahrtgeschwindigkeit(x;y)

Es ist eine einfache Addition beider Vektoren. Man benötigt keinerlei Winkelfunktionen. Das ist doch der Vorteil der Komponentenschreibweise.

Macht sinn.




Jetzt stellen wir uns vor, dass das Boot, wenn es am anderen Ufer angekommen ist, gleich eine Kehrtwende macht:




___________________________________________Ufer/Abprallwand
--->Umkehrpunkt
↑ / \
| / | \
| / | \
|/ ↓ \,
--->
___________________________________________Ufer



Also begibt es sich wieder direkt in Richtung des Ufers, nur in diesem Fall zum entgegengesetzten. Dir wird sicher schon aufgefallen sein, dass die Richtung zum Ufer hin immer exakt entgegengesetzt zu seinem Normalenvektor ist und vom Ufer weg immer exakt der Richtung des Normalenvektors entspricht.

Die Mal Zwei der ich immer und immer wieder begegnet bin, ich glaube so weit waren wir schon mal.




An der Fließrichtung sowie Fließgeschwindigkeit hat sich aber niemals etwas geändert, das Boot wird auch beim Ablegen von der anderen Seite in die selbe Richtung abgetrieben!

Nur die Richtung bzw. Geschwindigkeit zum Ufer hin hat sich um 180° gedreht, was dem Gegenvektor der Fahrtgeschwindigkeit entspricht, also Multiplikation mit dem Skalar -1 bzw. komponentenweise Multiplikation mit -1, was seiner Subtraktion entspricht:

so:





ResultierendeGeschwindigkeit(x;y) = Fließgeschwindigkeit(x;y) + Fahrtgeschwindigkeit(x;y)

ResultierendeGeschwindigkeit(x;y)' = Fließgeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y) <--- hier einsetzen!

Die beiden Zeilen^ sind wohl einleuchtend (ResultierendeGeschwindigkeit(x;y)' ist die nach dem Ablegen).


Jetzt sagen wir, wir wüssten die Fließgeschwindigkeit überhaupt nicht, dafür aber die (alte)
ResultierendeGeschwindigkeit(x;y)

ResultierendeGeschwindigkeit(x;y) = Fließgeschwindigkeit(x;y) + Fahrtgeschwindigkeit(x;y)
<=>
Fließgeschwindigkeit(x;y) = ResultierendeGeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y) ---^ da oben einsetzen


und setzen ein, s.o.:

ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y)
<=>
ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - 2 * Fahrtgeschwindigkeit(x;y)

:)
ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - 2 * Fahrtgeschwindigkeit(x;y)
entspricht als einzelkomponenten folgendem?
V[0] = V[0] - 2 * (X[0]);
X ist auf 1 Normiert, so das sich die Fahrtgeschwindigkeit nicht ändert:)

Soweit richtig?




Geometrisch sieht das dann so aus:



___________________________________________Ufer/Abprallwand
--->
↑ /↑
| / |
| / |
|/ |
\ ↑
\ |
\ |
\|
___________________________________________Ufer




Na, klingelts? §xmas

ja:)
Ach shit, war nur die Haustüre:(




Das alles liegt nun auf einem silbernen Tablett vor dir. Jetzt kommt es darauf an, dass du das Gelernte auch übertragen kannst (nicht raten, sondern logisch schließen!!!), also zu unserem konkreten Problem:



|
|
|
|
| Kante
|
/|\ |
/ | \ → |
/ | \ a |
/ | \ |
/ (*|*) \, →
<--------------------- Normalenvektor n →
\ (*|*) / <- Normaleneinheitsvektor n0
\ | /
\ | / →
\ | / a'
\|/
´



Fragen:


Welcher Anteil von a→ ändert sich (bitte farblich markieren und begründen)?
Welcher Anteil von a→ bleibt erhalten (bitte farblich markieren und begründen)?
(Der bleibende Anteil wäre in 3D eine Fläche, hier in 2D ist es ein Vektor, also kein Problem das einzuzeichnen)
Die restlichen Fragen stellst du dir selbst, ich lese sie mir gerne durch.




|
|
|
|
| Kante
|
/|\ |
/ | \ → |
/ | \ a |
/ | \ |
/ (*|*) \, →
<--------------------- Normalenvektor n →
\ (*|*) / <- Normaleneinheitsvektor n0
\ | /
\ | / →
\ | / a'
\|/
´


Der Blaue Anteil bleibt erhalten, der Grüne ändert sich.
Wenn ich jetzt 2 mal N abziehe, was erstmal logisch erscheinen würde, komme ich auf keinen Grünen Zweig, Programm bestätigt meine Vermutung. -> wieder vergessen.

Wir haben aber noch was von oben:
ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - 2 * Fahrtgeschwindigkeit(x;y)
was habe ich nicht direkt zur hand? Fahrtgeschwindigkeit, also muss ich das weiter zerlegen.

So, und ich kann jetzt ganz frech behaupten, wüsste ich genau wieso man den einen Vektor nomieren kann, könte ich das jetzthttp://www.worldofugly.de/ugly/003.gif




Selbstverständlich gibt es noch einen kleinen Teil, den du selbstständig herleiten musst. Natürlich hat der etwas mit dem Skalarprodukt zu tun, aber bitte nicht wieder raten, und bitte nicht wieder das Dach vor dem Keller bauen! Nein, ich habe dir nicht extra das Beispiel mit dem Boot so herum gedreht, wie du es brauchst, genauso wenig, wie ich die Wand/Kante mitten in die Raute gezeichnet habe, obwohl man das tun könnte. Ich rate dringend davor ab, weil sowas die Entstehung von Fehlannahmen, Spezialfällen sowie überflüssigen Punkten befördern kann. Vermutlich wirst du im Netz so schnell keine andere Erklärung finden, die so im Detail auf deine Problemstellung eingeht wie diese. Auch Mathebücher behandeln selten so spezielle Problemstellungen, eher Bücher zur Physik sowie zur Spieleprogrammierung. Die gehen dann weniger auf deine Belange ein, sind dafür aber noch gründlicher. Falls du also nichts Besseres hast, empfehle ich wärmstens, dieses kleine Tutorial anzunehmen. Fehlermeldungen und Korrekturen werden natürlich gerne angenommen.

Weiterhin viel Spaß!
LG, jabu
Spass? Spass sieht anders aus, nicht viel aber anders:o

So, ich glaube muss morgen Weiterprobieren, irgendwie kriege ich die absolute Lösung grad nicht hin, einige überlegungen sind schon drin.

jabu
30.07.2013, 00:31
Ich habe stark das gefühl, am ende habe ich sowas:
Ich sagte ja, dass ich Geratenes nicht mehr kommentieren werde, was sinngemäß auch für Gefühltes gilt. Außerdem sagte ich, dass ich Code nicht mehr kommentieren werde, solange das Problem nicht gelöst ist. Zuweisungsoperatoren treffen keine mathematische Aussage, weshalb das im weiteren Verlauf übel nach hinten losgehen kann. Wir brauchen aber mathematische Aussagen, z. B. dass links das Gleiche wie rechts steht. Eine Zuweisung ist jedoch nur eine Manipulation. In meinem Tutorial sind aber immer mathematische Ausdrücke gemeint, solange da kein C, C++, C# -Code bzw. Pseudocode steht. Also ist es verdammt wichtig, dass du siehst, dass ich keine Geradeausberechnungen liefere, also nichts von rechts an links zuweise, sondern mathematische Aussagen treffe, deren simplen Gehalt du unbedingt verstehen musst, insbesondere die Summe zweier Vektoren, dass diese einem resultierenden Vektor entspricht. Das ist keine Zuweisung, sondern die Aussage, dass es sich um das selbe handelt. Zudem ist es von elementarer Bedeutung, dass dir klar ist, was eine Äquivalenzumformung ist (lernt man in der Hauptschule in der achten bis neunten Klasse, um hier mal den kleinsten Nenner aufzuführen). Also gehe ich davon als selbstverständlich aus. Falls nicht, reden wir aneinander vorbei.


ka, ich komme jedesmal vom Skalarprodukt wieder auf den Winkel:(
Der Kosinus eines Winkels ist nicht der Winkel, aber was drückt der Kosinus eines Winkels aus?
(Bitte nicht mit Ahnungslosigkeit kommentieren, sondern damit beschäftigen. Wenn das noch nicht verstanden ist, können wir hier erstmal aufhören.)


Soweit erstmal logisch. ich akzeptiere erstmal einfach das man den Fahrtrichtungsvecktor auf 1 Nomieren kann, ich habe das Gefühl da später ev noch schlau draus zu werden.
Das müsstest du sogar, um auch den Rest zu verstehen. Bei dem Boot kommt es nicht zur Anwendung, weil alles, was wir brauchen, gegeben ist. Jetzt kannst du schon erahnen, dass ich es nicht einfach nur so erwähnt habe. Die Sache mit dem Boot kann dir mehr vermitteln als du glaubst, wenn du aufmerksam hinsiehst. Dafür ist sie absichtlich simpler, um das grundlegende Verständnis aufzubauen. Ich habe allerdings den Verdacht, dass versuchst, das zu überspringen, tue das nicht!


Die Mal Zwei der ich immer und immer wieder begegnet bin, ich glaube so weit waren wir schon mal.
Könntest du erklären, weshalb das so ist (steht dort alles explizit, und das gleich zweimal), wärst du schon viel weiter. Aber so bist du noch nicht bei diesem Faktor. Oder kannst du es? Dann wärst du jetzt immerhin zum ersten Mal so weit. Wenn du es jetzt noch nicht erklären kannst, solltest du noch einmal von vorne anfangen, bevor du auch nur wagst, mit den Sachen weiter unten weiterzumachen. Wir waren übrigens noch nie so weit. Den Faktor hattest du aus Foren abgeschrieben, und ich hatte die ehrenvolle Aufgabe, dein auf dieser Basis Geratenes zu falsifizieren. Aber selbstverständlich hatten wir nur ein etwas aus der Kehre geratenes Dach...


ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - 2 * Fahrtgeschwindigkeit(x;y)
entspricht als einzelkomponenten folgendem?
V[0] = V[0] - 2 * (X[0]);
Wenn mit "=" der Zuweisungsoperator gemeint ist, stimmt es. Aber ich wollte ja keinen Code mehr kommentieren, s.o.


X ist auf 1 Normiert, so das sich die Fahrtgeschwindigkeit nicht ändert:)

Soweit richtig?
Leider nicht. Ich erinnere daran, dass so eine Aussage nicht in der Gleichung, auf die du dich beziehst, steht. Bitte meine Aussage zu der Normierung noch einmal lesen. Denn es ist wichtig zu wissen (später: zu erkennen), dass zusätzlich zu dem resultierenden Vektor die Richtungsinformation einer der Komponenten genügt, um beide Komponenten vollständig, sowohl die Fahrtgeschwindigkeit (Normale zum Ufer) als auch die Fließgeschwindigkeit, zu rekonstruieren. Bitte sorgfältiger arbeiten, nicht böse gemeint, geht leider nicht anders.




|
|
|
|
| Kante
|
/|\ |
/ | \ → |
/ | \ a |
/ | \ |
/ (*|*) \, →
<--------------------- Normalenvektor n →
\ (*|*) / <- Normaleneinheitsvektor n0
\ | /
\ | / →
\ | / a'
\|/
´


Der Blaue Anteil bleibt erhalten, der Grüne ändert sich.
Richtig. :gratz Und was ändert sich an dem grünen Anteil?


Wenn ich jetzt 2 mal N abziehe, was erstmal logisch erscheinen würde,
Es ist erst dann logisch, wenn du es herleiten kannst. Alles andere sind bloß Erscheinungen.


komme ich auf keinen Grünen Zweig, Programm bestätigt meine Vermutung. -> wieder vergessen.
Nö, da steckt schon 2 * irgendeins von den beiden n drin, aber nicht so trivial. Du hast aber immer noch nicht gesagt, worauf du überhaupt hinaus willst, solange ist das alles nur Stochern im Nebel. Bitte fange mit dem Tutorial von vorne an und verstehe es. Du machst dir einiges mit deiner oberflächlichen Arbeitsweise kaputt, leider. Ich sage das nicht, um dich zu ärgern, sondern um die Ernsthaftigkeit bei dir anzuregen, anders geht es leider nicht. ;)


Wir haben aber noch was von oben:
Nein, wir haben nichts einfach so. Bitte begründen, auch wenn es richtig ist!


ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - 2 * Fahrtgeschwindigkeit(x;y)
was habe ich nicht direkt zur hand? Fahrtgeschwindigkeit, also muss ich das weiter zerlegen.
Du hättest dir schon mal die Mühe machen dürfen, die Bezeichnungen des Problems zu verwenden, um das es geht und diese Entsprechungen zu erklären. Aber nun gut, tun wir so, als ginge es um ein Boot:

Wenigstens hier kann ich dir mal eine Erfolgsmeldung geben: Ja, die Fahrtgeschwindigkeit ist zu ermitteln, bei dem Boot ist sie gegeben und bei unserer Problemstellung nicht, das hast du erkannt. :gratz :)

Was aber ist diese Komponente in unserer Grafik sowie Problemstellung (einzeichnen und erklären)?
Was ist bei unserer Problemstellung stattdessen gegeben (einzeichnen und erklären)?


So, und ich kann jetzt ganz frech behaupten, wüsste ich genau wieso man den einen Vektor nomieren kann, könte ich das jetzthttp://www.worldofugly.de/ugly/003.gif
Da ist etwas dran, bitte im Hinterkopf behalten.

Das war ja schon mal etwas, weitermachen!

LG, jabu

Multithread
30.07.2013, 19:15
Ich sagte ja, dass ich Geratenes nicht mehr kommentieren werde, was sinngemäß auch für Gefühltes gilt. Außerdem sagte ich, dass ich Code nicht mehr kommentieren werde, solange das Problem nicht gelöst ist. Zuweisungsoperatoren treffen keine mathematische Aussage, weshalb das im weiteren Verlauf übel nach hinten losgehen kann. Wir brauchen aber mathematische Aussagen, z. B. dass links das Gleiche wie rechts steht. Eine Zuweisung ist jedoch nur eine Manipulation. In meinem Tutorial sind aber immer mathematische Ausdrücke gemeint, solange da kein C, C++, C# -Code bzw. Pseudocode steht. Also ist es verdammt wichtig, dass du siehst, dass ich keine Geradeausberechnungen liefere, also nichts von rechts an links zuweise, sondern mathematische Aussagen treffe, deren simplen Gehalt du unbedingt verstehen musst, insbesondere die Summe zweier Vektoren, dass diese einem resultierenden Vektor entspricht. Das ist keine Zuweisung, sondern die Aussage, dass es sich um das selbe handelt. Zudem ist es von elementarer Bedeutung, dass dir klar ist, was eine Äquivalenzumformung ist (lernt man in der Hauptschule in der achten bis neunten Klasse, um hier mal den kleinsten Nenner aufzuführen). Also gehe ich davon als selbstverständlich aus. Falls nicht, reden wir aneinander vorbei.

Wenn du vieleicht nicht so viele Fremdwörter Gebrauchen würdest?^2^
Äquivalenzumformung sagt mir nichts, Gleichungen umstellen sollte ich aber gerade noch so hinbekommen:D




Der Kosinus eines Winkels ist nicht der Winkel, aber was drückt der Kosinus eines Winkels aus?
(Bitte nicht mit Ahnungslosigkeit kommentieren, sondern damit beschäftigen. Wenn das noch nicht verstanden ist, können wir hier erstmal aufhören.)

Der Kosinus liegt, wenn du also den Kreis hast, drückt der Kosinus die Länge einer Geraden aus die auf der einen Strecke des Winkels liegt.
Die Länge dieser Strecke wird durch den Bogen über beide Nominierten Strecken definiert. Wobei vom Endpunkt der einen ein Lot auf die Andere gefällt wird, die Strecke von diesem Lot Punkt aus bis zum schnittpunkt der beiden Normierten strecken, das ist der Kosinus.
Ich kannst dir auch gerne aufzeichnen, das würde ich hinbekommen, aber weshalb ist das hier wichtig?




Das müsstest du sogar, um auch den Rest zu verstehen. Bei dem Boot kommt es nicht zur Anwendung, weil alles, was wir brauchen, gegeben ist. Jetzt kannst du schon erahnen, dass ich es nicht einfach nur so erwähnt habe. Die Sache mit dem Boot kann dir mehr vermitteln als du glaubst, wenn du aufmerksam hinsiehst. Dafür ist sie absichtlich simpler, um das grundlegende Verständnis aufzubauen. Ich habe allerdings den Verdacht, dass versuchst, das zu überspringen, tue das nicht!

http://www.worldofugly.de/ugly/047.gif




Könntest du erklären, weshalb das so ist (steht dort alles explizit, und das gleich zweimal), wärst du schon viel weiter. Aber so bist du noch nicht bei diesem Faktor. Oder kannst du es? Dann wärst du jetzt immerhin zum ersten Mal so weit. Wenn du es jetzt noch nicht erklären kannst, solltest du noch einmal von vorne anfangen, bevor du auch nur wagst, mit den Sachen weiter unten weiterzumachen. Wir waren übrigens noch nie so weit. Den Faktor hattest du aus Foren abgeschrieben, und ich hatte die ehrenvolle Aufgabe, dein auf dieser Basis Geratenes zu falsifizieren. Aber selbstverständlich hatten wir nur ein etwas aus der Kehre geratenes Dach...

Das ist so weil wegen§lehrer

Die *2 kommen daher, da wir einmal die alte Richtung in eine Bestimmte Richtung lenken, genauer gesagt auf die Senkrechte zur Wand. Und ein 2tes Mal in die gleiche Richtung in dem Moment wo wir wieder von der Wand weg gehen, der Fluss fliest ja weiterhin in die Gleiche Richtung um beim Beispiel mit dem Boot zu bleiben.





Wenn mit "=" der Zuweisungsoperator gemeint ist, stimmt es. Aber ich wollte ja keinen Code mehr kommentieren, s.o.

Ist doch schon mal ein Anfang:)




Leider nicht. Ich erinnere daran, dass so eine Aussage nicht in der Gleichung, auf die du dich beziehst, steht. Bitte meine Aussage zu der Normierung noch einmal lesen. Denn es ist wichtig zu wissen (später: zu erkennen), dass zusätzlich zu dem resultierenden Vektor die Richtungsinformation einer der Komponenten genügt, um beide Komponenten vollständig, sowohl die Fahrtgeschwindigkeit (Normale zum Ufer) als auch die Fließgeschwindigkeit, zu rekonstruieren. Bitte sorgfältiger arbeiten, nicht böse gemeint, geht leider nicht anders.

Ist doch schon mal ein Anfang:)





Richtig. :gratz Und was ändert sich an dem grünen Anteil?

Er wird 2 Mal subtrahiert um aus a, a' zu machen.





Es ist erst dann logisch, wenn du es herleiten kannst. Alles andere sind bloß Erscheinungen.

Auch gut, dann hatte ich ne Erscheinung.




Nö, da steckt schon 2 * irgendeins von den beiden n drin, aber nicht so trivial. Du hast aber immer noch nicht gesagt, worauf du überhaupt hinaus willst, solange ist das alles nur Stochern im Nebel. Bitte fange mit dem Tutorial von vorne an und verstehe es. Du machst dir einiges mit deiner oberflächlichen Arbeitsweise kaputt, leider. Ich sage das nicht, um dich zu ärgern, sondern um die Ernsthaftigkeit bei dir anzuregen, anders geht es leider nicht. ;)

Auch gut, dann hatte ich ne Erscheinung.




Nein, wir haben nichts einfach so. Bitte begründen, auch wenn es richtig ist!

ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - 2 * Fahrtgeschwindigkeit(x;y)
->
ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - 2 * (ResultierendeGeschwindigkeit(x;y) - ChemikalieX(x;y))
Was wissen wor von ChemikalieX(x;y)?
1. Die Richtung
2. Der Satz von Pythagoras hat Gültigkeit
3. Entspricht der Ankathethe (oder Gegenkathete, wie mans sieht)

Was ich vor lauter Blindheit immer noch nicht sehe: Wie bekomme ich aus dieser Richtungsinformation nun die länge?
Annäherung wäre per Brute Force, wäre sicher eine Variante§ugly9002
Auch wenn du keinen Code mehr Komentierst, ich schreibe mal meine überlegung dazu auf, ev. bin ich auf dem richtigen Weg:
1. Testlänge (Richtung bei Stehendem gewässer) auf ResultierendeGeschwindigkeit(x;y)' *1.5 setzten.
2. Fliesweite des Flusses während der Überquerung ausrechnen
3. Skalarprodukt berechnen aus Testlänge und Fliesweite
4. Testen in welche Richtung das Skalarprodukt kleiner ist. Das Skalarprodukt ist lediglich eine Potenz 2ten Grades, geht also:D
5. Die kürzere Strecke nehmen, punkt in der Mitte berechnen und zurück zu punkt 2, bis das Skalar sehr klein ist.
-> Winhttp://www.worldofugly.de/ugly/024.gif

Erkenntnis daraus -> bisher keine, abgesehen davon das man den Brute Force Algorithmus noch Optimieren könnte



Du hättest dir schon mal die Mühe machen dürfen, die Bezeichnungen des Problems zu verwenden, um das es geht und diese Entsprechungen zu erklären. Aber nun gut, tun wir so, als ginge es um ein Boot:

Wenigstens hier kann ich dir mal eine Erfolgsmeldung geben: Ja, die Fahrtgeschwindigkeit ist zu ermitteln, bei dem Boot ist sie gegeben und bei unserer Problemstellung nicht, das hast du erkannt. :gratz :)

Ik bin Klugg:o




Was aber ist diese Komponente in unserer Grafik sowie Problemstellung (einzeichnen und erklären)?
Was ist bei unserer Problemstellung stattdessen gegeben (einzeichnen und erklären)?


|
|
| Kante
|
/|\ |
/ | \ → |
/ | \ a |
/ | \ |
/ (*|*) \, →
<--------------------- Normalenvektor n →
\ (*|*) / <- Normaleneinheitsvektor n0
\ | /
\ | / →
\ | / a'
\|/

Die Fahrgeschwindigkeit ist das Pinke.
hab nochmals was (http://www.chemgapedia.de/vsengine/vlu/vsc/de/ma/1/mc/ma_02/ma_02_01/ma_02_01_04.vlu/Page/vsc/de/ma/1/mc/ma_02/ma_02_01/ma_02_01_09.vscml.html)
pink entspricht a→*Cos(a)
cos(a) können wir nun durch das Skalarprodukt ersetzten, da das Skalarprodukt cos(a) ebenfalls beinhaltet. Logik? screw it, I'm pinkie pie:D
dann ist
|pink→| = |a→|*(Skalar/|a→|/|pink→|)
\\o//

//o\\ Ist das bis Hier hin richtig?


Irgendwie wird es dann ja möglich sein Pink auf eine Seite zu bekommen. (ausmultiplizieren, pinkie nach links.)
Bleibt aber eine weitere Frage, wie bekomme ich aus der Länge von pink dann deren Einzelkomponenten raus?
Indem ich die Wandrichtung auf Länge von Pink umrechne http://www.worldofugly.de/ugly/040.gif

EDIT: Fuck, woher bekomme ich jetzt so schnell noch einen Skalarwert, dieser setzt sich doch auch aus a und pink(nicht nominiert) zusammen§gnah





Da ist etwas dran, bitte im Hinterkopf behalten.

Das war ja schon mal etwas, weitermachen!

LG, jabu
So, ich weiss jetzt wieso ich den Vektor nominieren kann:p
Naja, zumindest weiss ich das es auch mit einem nominierten Vektor geht.

jabu
31.07.2013, 21:13
Wenn du vieleicht nicht so viele Fremdwörter Gebrauchen würdest?^2^
Äquivalenzumformung sagt mir nichts, Gleichungen umstellen sollte ich aber gerade noch so hinbekommen:D
Wollte nur sicher gehen, dass dir das geläufig ist, man kann ja nie wissen...


Der Kosinus liegt, wenn du also den Kreis hast, drückt der Kosinus die Länge einer Geraden aus die auf der einen Strecke des Winkels liegt.
Das ist als Teil einer reinen Veranschaulichung für uns etwas mager.


Die Länge dieser Strecke wird durch den Bogen über beide Nominierten Strecken definiert.Dazu hatte wohl mal eine Zeichnung gehört? Nun gut, es geht um den Einheitskreis (Radius = 1). Erst so ergibt der Satz davor einen Sinn. Also hast du das einem fremden Kontext entnommen, nämlich dem einer Zeichnung oder Vorgabe eines Einheitskreises.


Wobei vom Endpunkt der einen ein Lot auf die Andere gefällt wird, die Strecke von diesem Lot Punkt aus bis zum schnittpunkt der beiden Normierten strecken, das ist der Kosinus.
Das stimmt zahlenmäßig nur im Einheitskreis und erklärt noch nicht, was der Kosinus ausdrückt. Es geht um ein simples Verhältnis, was der Einheitskreis wegen der bei Multiplikation und Division neutralen Eins nicht so gut erkennen lässt. Das führt zu solch versimplifizierten Aussagen, der Kosinus des Winkels sei diese Strecke bis zum heruntergeloteten Punkt, was nämlich nur beim Radius Eins stimmt. So kommt man zu Aussagen, die im allgemeinen Fall falsch sind, nämlich wenn die Hypotenuse nicht den Betrag 1 hat.


Ich kannst dir auch gerne aufzeichnen, das würde ich hinbekommen, aber weshalb ist das hier wichtig?
Es müsste dir ganz von selbst auffallen, was das im Zusammenhang mit dem Skalarprodukt und der fehlenden Größe in unserer letzten Skizze bedeutet.


Die *2 kommen daher, da wir einmal die alte Richtung in eine Bestimmte Richtung lenken, genauer gesagt auf die Senkrechte zur Wand. Und ein 2tes Mal in die gleiche Richtung in dem Moment wo wir wieder von der Wand weg gehen, der Fluss fliest ja weiterhin in die Gleiche Richtung um beim Beispiel mit dem Boot zu bleiben.
Beim ersten Mal ist die Richtung zum Ufer hin, entgegen dem Normalenvektor des Ufers, auf dem Rückweg ist die Richtung genau umgekehrt, also entlang des Normalenvektors. Wenn du jetzt die Komponente zum Ufer hin in die vom Ufer weg überführen möchtest, musst du die Komponente zum Ufer hin nur Rückwärts gehen, während die Fließrichtung bleibt. Damit wäre die ganze Rechnung schon hiermit abgeschlossen, also mit:

ResultierendeGeschwindigkeit(x;y)' = Fließgeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y)

Nun geht es aber darum, dass bei uns Fließgeschwindigkeit(x;y) unbekannt ist, weil der Wandvektor selbst kein Maß für den Betrag der Senkrechte auf n (aka "Pink") ist (und wir wollen nicht beide Vektoren berechnen müssen). Die Richtung von Fahrtgeschwindigkeit(x;y) ist jedoch durch den Normalenvektor gegeben, weshalb wir Fließgeschwindigkeit(x;y) durch

Fließgeschwindigkeit(x;y) = ResultierendeGeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y)

ausdrücken, was im Ergebnis soviel bedeutet, dass wir esrtmal als Summand

ResultierendeGeschwindigkeit(x;y)

haben, was dem alten Vektor entspricht. Dieser beinhaltet ja bereits den Summanden

Fahrtgeschwindigkeit(x;y),

den wir wieder abziehen müssen, sodass lediglich

Fließgeschwindigkeit(x;y)

in ihm verbleibt. Das ist die Senkrechte aka "Pink". Jetzt zeigt der Vektor in unserem Beispiel (nicht Boot) genau nach unten. Mit

- Fahrtgeschwindigkeit(x;y)

addieren wir den Gegenvektor zu Fahrtgeschwindigkeit(x;y) bzw. ziehen sie noch einmal ab, was bezogen auf den neuen Vektor aber nur einmalige Subtraktion bedeutet und damit seinen Anteil senkrecht zu Wand/Ufer hin definiert (welcher nun tatsächlich von ihr/ihm wegweist).
Im Ergebnis haben wir bloß den Summanden parallel (in Richtung oder Gegenrichtung) zum Normalenvektor durch seinen Gegenvektor ersetzt, mehr nicht! :)



Er wird 2 Mal subtrahiert um aus a, a' zu machen.
Richtig, gut gemacht :gratz. :)

Und wo würdest du jetzt a' einzeichnen?


Siehst du jetzt,

dass diese Subtraktion eine aufwändige Spiegelung ersetzt?
dass diese einfache Subtraktion deine Winkelfunktionen in Rente schickt?
wie unerheblich der Sinus gewesen ist, auf den du anfangs noch hinaus wolltest?
dass der zum Normalenvektor senkrechte Anteil, welcher zur Wandrichtung parallel ist, unserer Fließgeschwindigkeit entspricht und stets beibehalten wird?
dass diese ebenso wie bei unserem Fluss aus der Berechnung herausfällt?



ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - 2 * Fahrtgeschwindigkeit(x;y)
->
ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - 2 * (ResultierendeGeschwindigkeit(x;y) - ChemikalieX(x;y))
Was wissen wor von ChemikalieX(x;y)?

Nein, nein, Fahrtgeschwindigkeit(x;y) ist doch, was du suchst. Also ist doch nichts abzuziehen. Du möchtest das indirekt über "Pink" ausdrücken, aber dann hättest du doch "Pink" auszurechnen, wobei doch der Normalenvektor, welcher parallel zu Fahrtgeschwindigkeit(x;y) ist, längst vorliegt. Es ist nur noch die "Länge" (Betrag) unbekannt. Das ist sie aber auch bei "Pink", weshalb du keinen Vorteil hättest, damit zu beginnen. Bei 3D würdest du dir sogar ins Knie schießen, weil du die ganze Flächenorientierung der Wand für "Pink" bräuchtest, überflüssig wie ein Kropf. In 2D klappt das noch, bringt aber keinen Vorteil, weil dir bei "Pink" der Betrag ebenso wie bei dem Vektor in Normalenrichtung fehlt und eher der Normalenvektor gegeben ist, weshalb man letzteren heranzieht. Du kannst das hinterher auch andersherum machen, wenn dir das lieber ist, aber lass uns erstmal hierbei bleiben, weil die ganze Erklärung so gestrickt ist, sonst ist das einfach nicht konsistent.

Beim Boot ist dieser Anteil parallel zur Normalen ja als "Fahrtrichtung" vorgegeben, was mein didaktischer Trick war, um einerseits die Sache zu vereinfachen und andererseits zugleich dein Denken in Anteilen zu fördern, welche nicht der reinen x- oder y-Richtung entsprechen, sondern prinzipiell beliebige Summanden darstellen und drittens, dich erkennen zu lassen, was die vorgegebene Fahrtgeschwindigkeit denn überhaupt ist und viertens, dich den globalen Zusammenhang erkennen zu lassen, dass sich jeder Vektor als Summe solcher Vektoren schreiben lässt, die zueinander rechtwinklig sind, aber eben nicht den Achsen-Richtungen entsprechen, sodass klar werden dürfte, dass der Bewegungsvektor in diese beiden Anteile zerfällt, allein, weil man das so haben will, hier einmal in Richtung einer Normalen sowie einmal senkrecht dazu. Wo du das tust ist völlig egal, ebenso, wei der Kram zum Koordinatensystem liegt. Du beschreibst den Bewegungsvektor einfach als Summe zweier Vektoren, einmal entgegen dem Normalenvektor und einmal senkrecht dazu, wobei man in dieser Summe immer einen dieser drei Vektoren weglassen kann, wie bei einfacher Addition auch nur zwei Summanden oder die Summe und ein Summand benötigt werden. Deshalb konnten wir nämlich in Fließrichtung einsetzen, wobei diese wegfällt, s. o.

Du kannst also immer einen Vektor als Summe zweier oder mehrerer Vektoren darstellen, wobei uns hier nur zwei zueinander rechtwinklige interessieren, wobei einer davon exakt in Gegenrichtung zur Normalen weist. Dann muss man diesen Anteil nur noch umkehren, was doppelte Subtraktion bedeutet, einmal den Anteil, der bereits vorhanden ist, kompensieren und noch einmal in diese Richtung zurück. Das wäre in unserer Skizze also genau ein "Umklappen" des der Wand zugeneigten Dreiecks einmal nach links. Das war es, was du idealerweise schon seit Beginn der Diskussion über das Dreieck hättest selbst sehen sollen. Auf diese simple geometrische Interpretation deinerseits habe ich immer gewartet, kam aber leider nichts dazu, hast mich immer nur fragend zitiert. Und nun sind wir wieder bei dem Wink mit dem Zaunpfahl, ist doch augenfällig, dass beim Umklappen des rechten rechtwinkligen Dreiecks über seine Gegenkathete nach links weg ein eben solches Dreieck entsteht, wo lediglich der zur Normale parallele Anteil exakt durch seinen Gegenvektor ersetzt bzw. um 180° gedreht wird, während der zu ihm senkrechte Anteil, welcher parallel zur Wand ist, unberührt bleibt. Also musst du diesen Anteil durch seinen Gegenvektor ersetzen. Da dieser aber nicht als einzelne Komponente in Erscheinung tritt, muss man den ursprünglichen Anteil in dieser Richtung abziehen und den Gegenvektor addieren, was seiner doppelten Subtraktion entspricht. Beim Boot war dieser Anteil als Fahrtrichtung vorgegeben (didaktischer Kniff, s. o.), bei der Reflektion ist er das nicht, weshalb du ihn berechnen musst. Also benötigst du den Anteil, welcher sich ergibt, wenn man von der Hypotenuse aus zu der Normalen senkrecht herunterprojeziert. Und wenn du einmal weißt, was der Kosinus ausdrückt, dann solltest du sehen, dass der Winkel eben genau das nicht ist, was man braucht (außer man provoziert seine Verwendung) ;)


Was ich vor lauter Blindheit immer noch nicht sehe: Wie bekomme ich aus dieser Richtungsinformation nun die länge?
Indem diese bereits im Bewegungsvektor drin stekt. Es ist eben die Fahrtrichtung bei dem Boot, welche dort vorgegeben war. Schau dir das Skalarprodukt an und was ein Kosinus ausdrückt, dann sollte das klar sein. Mehr möchte ich hier nicht verraten, um dich nicht wieder um deine Erkenntnis zu bringen. ;)


Annäherung wäre per Brute Force, wäre sicher eine Variante§ugly9002
Das wäre wirklich ungenau bzw. unperformant.


Auch wenn du keinen Code mehr Komentierst, ich schreibe mal meine überlegung dazu auf, ev. bin ich auf dem richtigen Weg:
1. Testlänge (Richtung bei Stehendem gewässer) auf ResultierendeGeschwindigkeit(x;y)' *1.5 setzten.
2. Fliesweite des Flusses während der Überquerung ausrechnen
3. Skalarprodukt berechnen aus Testlänge und Fliesweite
4. Testen in welche Richtung das Skalarprodukt kleiner ist. Das Skalarprodukt ist lediglich eine Potenz 2ten Grades, geht also:D
5. Die kürzere Strecke nehmen, punkt in der Mitte berechnen und zurück zu punkt 2, bis das Skalar sehr klein ist.
Mal abgesehen von den Fehlern wäre das unnötig kompliziert und redundant, wenn du es bis zur Funktionsfähigkeit hinbiegen würdest. Mal angenommen, du würdest ein funktionierendes Näherungsverfahren entwickeln und dort die formalen Parameter anstatt Zahlen eingeben, so würde am Ende die richtige Gleichung stehen bleiben. Daher ist das Prozedere in sich redundant. Es beinhaltet dann, was du brauchst und fügt ihm nur Unnötiges hinzu. Wenn eine formale Lösung existiert, was wir wissen, lässt sich so ein Näherungsverfahren darauf "einkondensieren", sodass am Ende nichts anderes als die formale Lösung stehen bleibt.


Erkenntnis daraus -> bisher keine, abgesehen davon das man den Brute Force Algorithmus noch Optimieren könnte
Solange du nicht merkst, dass ResultierendeGeschwindigkeit(x;y)' das Ergebnis ist, dieses aber mit irgendwas multiplizieren möchtest, existiert gar kein Algorithmus. Also kannst du ihn auch nicht optimieren. Das ist wieder genau der Käse wie bei der Dachneigung deiner imagimären Hütte, die du nie gabaut hast. ;) Als Idee zu einer Vorausüberlegung kann man so etwas gelten lassen, was sich aber schon mangels Schlüssigkeit nicht mehr kommunizieren lässt.


Ik bin Klugg:o
Will ich nicht abstreiten. Aber noch klüger wäre eine intensive Auseinandersetzung, dies ist eher extensiv.




|
|
| Kante
|
/|\ |
/ | \ → |
/ | \ a |
/ | \ |
/ (*|*) \, →
<--------------------- Normalenvektor n →
\ (*|*) / <- Normaleneinheitsvektor n0
\ | /
\ | / →
\ | / a'
\|/

Die Fahrgeschwindigkeit ist das Pinke.
Leider falsch. Dann hast du also noch gar nicht das Beispiel mit dem Boot verstanden (oder dich vertan)? Bitte das mit dem Boot zuerst durcharbeiten.


hab nochmals was (http://www.chemgapedia.de/vsengine/vlu/vsc/de/ma/1/mc/ma_02/ma_02_01/ma_02_01_04.vlu/Page/vsc/de/ma/1/mc/ma_02/ma_02_01/ma_02_01_09.vscml.html)
pink entspricht a→*Cos(a)
Nun gut, ich gehe mal großzügig davon aus, dass du mit a den Winkel zwischen Hypotenuse und Senkrechte auf n meinst, dann ist es richtig, wenn du noch die Betragsstriche um den Vektor herum setzt. Trotzdem ist das lilane nicht die Fahrgeschwindigkeit, sondern die unbeeinflusste Komponente, aka Fließgeschwindigkeit. Das dürftest du in dieser Skizze doch sofort sehen, wenn du dir die Reflektion ansiehst. Egal wo du a'→ anträgst, dieser Anteil ändert sich niemals.


cos(a) können wir nun durch das Skalarprodukt ersetzten, da das Skalarprodukt cos(a) ebenfalls beinhaltet. Logik? screw it, I'm pinkie pie:D
Na endlich. Aber ich hoffe dabei, dass du auch siehst, was genau gleich ist. Ein Winkel ist übrigens gar nicht im Spiel, sondern nur sein Kosinus, was ein einfaches Verhältnis ist. Das ist ja der Witz. Wenn man das sieht, ist es ganz einfach.


dann ist
|pink→| = |a→|*(Skalar/|a→|/|pink→|)
...etwas schreibfaul ("Skalar")?


//o\\ Ist das bis Hier hin richtig?
Wenn du es noch ordentlich hinschreibst, durchaus. Immerhin ist das ein Schritt zum Verständnis des Skalarproduktes hin, was ich schon mal gut finde.


Irgendwie wird es dann ja möglich sein Pink auf eine Seite zu bekommen. (ausmultiplizieren, pinkie nach links.)
Das geht sogar problemlos (kannst ja mal probieren, keine schlechte Aufgabe, dieses), und ich weiß auch schon, was herauskommt, eine Binsenweisheit sozusagen. :D


Bleibt aber eine weitere Frage, wie bekomme ich aus der Länge von pink dann deren Einzelkomponenten raus?
Gar nicht, das ist ja der Witz. Das kannst du umstellen, bis du grün wirst, weil nur eine Größe gegeben ist, nämlich a→ :D Da kannst du anstelle eines nicht gegebenen Pinks auch gerne rechts 3000 hinzuaddieren und links auch und das ganze jeweils mit beliebigen Variablen multiplizieren, wird schon zutreffend bleiben...


Indem ich die Wandrichtung auf Länge von Pink umrechne http://www.worldofugly.de/ugly/040.gif
Du meinst, indem du aus der Wandrichtung und a→ die Länge von Pink berechnest? Das kann man tun, auch gleich den ganzen Vektor. Das wäre in 2D sogar ein möglicher Ansatz, in 3D aber nicht so ohne Weiteres, weil Pink dort - wie bereits erwähnt - eine Fläche wäre. Das ist also zu speziell, dass es sich lohnen würde, sich das einzuprägen. An Komplexität sparst du grob geschätzte drei bis sechs Prozessortakte, wenn du den Normalenvektor nicht aus dem Wandvektor generierst. Der Rest ist gleich komplex in 2D, egal ob du den Wand- oder Normalenvektor nimmst. Wenn du die Vorteile der Normalenvektoren an anderer Stelle nicht nutzt, kannst du sogar bei jedem Durchlauf grob geschätzte hunderte bis hunderttausende Prozessortakte verschenken, je nachdem, wie voll die Map ist und was die Engine so daruf hat, also Ballern, Interaktion generell usw. Es macht also keinen Sinn, den kunstvoll umgehen zu wollen. Du bekommst ihn performancemäßig geschenkt.



EDIT: Fuck, woher bekomme ich jetzt so schnell noch einen Skalarwert, dieser setzt sich doch auch aus a und pink(nicht nominiert) zusammen§gnah
Und wenn du das ausmultiplizierst,

|pink→| * |a→| * cos α

kommt

|pink→| * |pink→|

heraus, weil hier gilt:

|pink→| = |a→| * cos α


Also kannst du bei dir dort oben reichlich kürzen, sodass dort am Ende furchtbar interessante

1 = 1 steht, was unzweifelhaft wahr ist, nur führt das zu nichts, s. o.

LG, jabu

Multithread
01.08.2013, 09:53
Kreis von mir angeschrieben:
http://upload.worldofplayers.de/files9/Kreis.png
Die Tangente ist falsch eingezeichnet, aber was solls.
Der Kosinus entspricht der Kathete im Rechtwinkligen Dreieck




Es müsste dir ganz von selbst auffallen, was das im Zusammenhang mit dem Skalarprodukt und der fehlenden Größe in unserer letzten Skizze bedeutet.

Das ist es oder? des Pudels Kern:(
Ich sehe nur einen:
Das Skalarprodukt entspricht der Multiplikation von unserer Gesuchten Grösse und (der Geschwindigkeit des Flusses * der Überquerungsdauer).
Das sind aber erstmal beides Unbekannte Grössen, hilft mir also nicht wirklich.




Beim ersten Mal ist die Richtung zum Ufer hin, entgegen dem Normalenvektor des Ufers, auf dem Rückweg ist die Richtung genau umgekehrt, also entlang des Normalenvektors. Wenn du jetzt die Komponente zum Ufer hin in die vom Ufer weg überführen möchtest, musst du die Komponente zum Ufer hin nur Rückwärts gehen, während die Fließrichtung bleibt. Damit wäre die ganze Rechnung schon hiermit abgeschlossen, also mit:

ResultierendeGeschwindigkeit(x;y)' = Fließgeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y)

Nun geht es aber darum, dass bei uns Fließgeschwindigkeit(x;y) unbekannt ist, weil der Wandvektor selbst kein Maß für den Betrag der Senkrechte auf n (aka "Pink") ist (und wir wollen nicht beide Vektoren berechnen müssen). Die Richtung von Fahrtgeschwindigkeit(x;y) ist jedoch durch den Normalenvektor gegeben, weshalb wir Fließgeschwindigkeit(x;y) durch

Fließgeschwindigkeit(x;y) = ResultierendeGeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y)

So:
also erstmal:
ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y)
Woher kennen wir die Fahrtgeschwindigkeit? Wir kennen doch nur Ihre Richtung?




ausdrücken, was im Ergebnis soviel bedeutet, dass wir esrtmal als Summand

ResultierendeGeschwindigkeit(x;y)

haben, was dem alten Vektor entspricht. Dieser beinhaltet ja bereits den Summanden

Fahrtgeschwindigkeit(x;y),

Dann wäre es ja :
ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y)
§kratz
Das kann so aber nicht Funktionieren, nicht solange die Fahrtgeschwindigkeit ein Normierter Vektor ist.

....
Was, wenn ich Resultierende Geschwindigkeit.X*N.X rechne und mit Y auch, dann sollte ich ja eigentlich die Länge vom Vektor bekommen der in Richtung N geht, vorausgesetzt die 3 Resultierenden Vektoren bilden ein Rechtwinkliges Dreieck. \\o//
Und wenn ich dazu nun nochmals die Differenz von resultierende Geschwindigkeit abziehe (vorzeichen beachten, der Vektor muss wieder länger werden), habe ich mein Resultat? §ugly

In der Theorie klingt es ja gut, aber funktionieren tut es nicht:


Vektor rechte = new Vektor(alteRichtung.X * N[0], alteRichtung.Y * N[1]);
Vektor diferenz = new Vektor( alteRichtung.X-rechte.X, alteRichtung.Y-rechte.Y);

Vektor resultat = new Vektor(rechte.X - diferenz.X, rechte.Y - diferenz.Y);
weder die Richtung noch die Geschwindigkeit stimmen, das kann also nicht stimmen.

Hmm, schon in der ersten Zeile kann was noch nicht stimmen...
Es müsste doch lauten resultat→ ist gleich |alteRichtung→| *N→
aber dann ist meine Resultierende Länge wieder genau gleich lang wie alte Richtung, geht nur in eine andere Richtung:(




den wir wieder abziehen müssen, sodass lediglich

Fließgeschwindigkeit(x;y)

in ihm verbleibt. Das ist die Senkrechte aka "Pink". Jetzt zeigt der Vektor in unserem Beispiel (nicht Boot) genau nach unten. Mit

- Fahrtgeschwindigkeit(x;y)

addieren wir den Gegenvektor zu Fahrtgeschwindigkeit(x;y) bzw. ziehen sie noch einmal ab, was bezogen auf den neuen Vektor aber nur einmalige Subtraktion bedeutet und damit seinen Anteil senkrecht zu Wand/Ufer hin definiert (welcher nun tatsächlich von ihr/ihm wegweist).
Im Ergebnis haben wir bloß den Summanden parallel (in Richtung oder Gegenrichtung) zum Normalenvektor durch seinen Gegenvektor ersetzt, mehr nicht! :)

So, jetzt habe ich den durchblick wieder verloren.




Richtig, gut gemacht :gratz. :)

Und wo würdest du jetzt a' einzeichnen?

Da wo es angeschrieben ist?:D
Unterhalb des Normalvektors, auf der jeweiligen Seite von pink wo auch a→ ist.





Siehst du jetzt,

dass diese Subtraktion eine aufwändige Spiegelung ersetzt?
dass diese einfache Subtraktion deine Winkelfunktionen in Rente schickt?
wie unerheblich der Sinus gewesen ist, auf den du anfangs noch hinaus wolltest?
dass der zum Normalenvektor senkrechte Anteil, welcher zur Wandrichtung parallel ist, unserer Fließgeschwindigkeit entspricht und stets beibehalten wird?
dass diese ebenso wie bei unserem Fluss aus der Berechnung herausfällt?

sehen: ja
verstehen: nein, und solange ich es nicht hinbekommen habe/Es Funktioniert, wird sich daran ganz sicher nichts ändern.




*hier stand viel text*

Also: Kosinus brauche ich nicht, gut dann vergesse ich den vorläufig ganz. Es bringt mir nichts wenn ich an 3 Stellen überlege wo nur eine richtig ist, es dauert nur 10 mal länger bis ich etwas verstehe, ein Schritt nach dem anderen.




Indem diese bereits im Bewegungsvektor drin stekt. Es ist eben die Fahrtrichtung bei dem Boot, welche dort vorgegeben war. Schau dir das Skalarprodukt an und was ein Kosinus ausdrückt, dann sollte das klar sein. Mehr möchte ich hier nicht verraten, um dich nicht wieder um deine Erkenntnis zu bringen. ;)


Das wäre wirklich ungenau bzw. unperformant.

nur das 2te, nach spätestens 2^27 Durchläufen habe ich die maximale Genauigkeit von Decimal erreicht:D
Im Normalfall schon viel eher, da ich nur ein relativ kleines Spektrum betrachte, 1000 Durchläufe dürften Reichenhttp://www.worldofugly.de/ugly/030.gif




Mal abgesehen von den Fehlern wäre das unnötig kompliziert und redundant, wenn du es bis zur Funktionsfähigkeit hinbiegen würdest. Mal angenommen, du würdest ein funktionierendes Näherungsverfahren entwickeln und dort die formalen Parameter anstatt Zahlen eingeben, so würde am Ende die richtige Gleichung stehen bleiben. Daher ist das Prozedere in sich redundant. Es beinhaltet dann, was du brauchst und fügt ihm nur Unnötiges hinzu. Wenn eine formale Lösung existiert, was wir wissen, lässt sich so ein Näherungsverfahren darauf "einkondensieren", sodass am Ende nichts anderes als die formale Lösung stehen bleibt.

Dann war meine Einschätzung bezüglich der Formel mit den vielen V und n's nicht mal so schlechthttp://www.worldofugly.de/ugly/003.gif




Solange du nicht merkst, dass ResultierendeGeschwindigkeit(x;y)' das Ergebnis ist, dieses aber mit irgendwas multiplizieren möchtest, existiert gar kein Algorithmus. Also kannst du ihn auch nicht optimieren. Das ist wieder genau der Käse wie bei der Dachneigung deiner imagimären Hütte, die du nie gabaut hast. ;) Als Idee zu einer Vorausüberlegung kann man so etwas gelten lassen, was sich aber schon mangels Schlüssigkeit nicht mehr kommunizieren lässt.

auch nicht gut:dnuhr:
Was ich mich frage: woher denkst du das ich nicht weiss das ResultierendeGeschwindigkeit(x;y)' das Resultat ist?



Will ich nicht abstreiten. Aber noch klüger wäre eine intensive Auseinandersetzung, dies ist eher extensiv.

Mal abgesehen davon das jeder meiner letzten Beiträge hier gut über eine Stunde aufwand und nachdenken erhalten...




Leider falsch. Dann hast du also noch gar nicht das Beispiel mit dem Boot verstanden (oder dich vertan)? Bitte das mit dem Boot zuerst durcharbeiten.

Dumm, ich habe den Normalvektor als Abprall Kante genommen, schon wieder§gnah




Na endlich. Aber ich hoffe dabei, dass du auch siehst, was genau gleich ist. Ein Winkel ist übrigens gar nicht im Spiel, sondern nur sein Kosinus, was ein einfaches Verhältnis ist. Das ist ja der Witz. Wenn man das sieht, ist es ganz einfach.

also das was übrig bleibt wenn ich den Kosinus zum Winkel ausrechne? (cos(Winkel X))
Dann brauche ich den Winkel ja wirklich nicht, denn diese Information wäre teil von N→




...etwas schreibfaul ("Skalar")?

Ich hätte auch nur S schreien können, aber stimmt schon, ausschreiben wäre wohl kein Luxus.



Wenn du es noch ordentlich hinschreibst, durchaus. Immerhin ist das ein Schritt zum Verständnis des Skalarproduktes hin, was ich schon mal gut finde.

Wenn es nur ein Schritt zum Verständnis vom Skalar ist, bringt es mir ja nichts?




Das geht sogar problemlos (kannst ja mal probieren, keine schlechte Aufgabe, dieses), und ich weiß auch schon, was herauskommt, eine Binsenweisheit sozusagen. :D


Gar nicht, das ist ja der Witz. Das kannst du umstellen, bis du grün wirst, weil nur eine Größe gegeben ist, nämlich a→ :D Da kannst du anstelle eines nicht gegebenen Pinks auch gerne rechts 3000 hinzuaddieren und links auch und das ganze jeweils mit beliebigen Variablen multiplizieren, wird schon zutreffend bleiben...

...




Du meinst, indem du aus der Wandrichtung und a→ die Länge von Pink berechnest? Das kann man tun, auch gleich den ganzen Vektor. Das wäre in 2D sogar ein möglicher Ansatz, in 3D aber nicht so ohne Weiteres, weil Pink dort - wie bereits erwähnt - eine Fläche wäre. Das ist also zu speziell, dass es sich lohnen würde, sich das einzuprägen. An Komplexität sparst du grob geschätzte drei bis sechs Prozessortakte, wenn du den Normalenvektor nicht aus dem Wandvektor generierst. Der Rest ist gleich komplex in 2D, egal ob du den Wand- oder Normalenvektor nimmst. Wenn du die Vorteile der Normalenvektoren an anderer Stelle nicht nutzt, kannst du sogar bei jedem Durchlauf grob geschätzte hunderte bis hunderttausende Prozessortakte verschenken, je nachdem, wie voll die Map ist und was die Engine so daruf hat, also Ballern, Interaktion generell usw. Es macht also keinen Sinn, den kunstvoll umgehen zu wollen. Du bekommst ihn performancemäßig geschenkt.

Die 3 bis 6 Prozesortakte können wir gerne noch einsparen sobald es geht.
Vorher aber nicht.




Also kannst du bei dir dort oben reichlich kürzen, sodass dort am Ende furchtbar interessante

1 = 1 steht, was unzweifelhaft wahr ist, nur führt das zu nichts, s. o.

LG, jabu
Fuck, schon fast gedacht das das nirgendwo hin führen wird.

Multithread
02.08.2013, 18:19
So, nochmals alles wichtige kurz:
Alles was ich weiss ist: Die Normierte Richtung welche dem Spiele entspricht
Sowie die Richtung und Länge des Aufprallenden Bewegungsrichtungs Vektors


\ | /
\ | /
\|/
___

Was ich bereits weiss das es nicht geht, bzw mindestens eine Komponente von Blau falsch ist:

1. Länge von Orange mit N für X und Y Multiplizieren -> Blau ist zu lang
2. Orange mit N multiplizieren für X und Y -> Blau zu Kurz, sehr wenige Ausnahmen wo es stimmt.
3. Orange mit -N multiplizieren für X und Y -> Blau zu Kurz, sehr wenige Ausnahmen wo es stimmt§ugly

Was könnte ich noch machen?
Laut hier (http://www.matheboard.de/archive/449869/2/thread.html) ist es ganz einfach: Länge Orang mit N(X,Y) multiplizieren.
allerdings Dividiert er danach erst noch den Roten Vektor durch das Ergebnis§kratz
x/|x|*a

jabu
02.08.2013, 18:47
Dieses mal nur kurz (sorry für x-Posting):


Kreis von mir angeschrieben:
http://upload.worldofplayers.de/files9/Kreis.png
Die Tangente ist falsch eingezeichnet, aber was solls.
Der Kosinus entspricht der Kathete im Rechtwinkligen Dreieck

Hatte ich doch schon erklärt, dass das^ im allgemeinen Fall falsch ist:

"Das stimmt zahlenmäßig nur im Einheitskreis und erklärt noch nicht, was der Kosinus ausdrückt. Es geht um ein simples Verhältnis, was der Einheitskreis wegen der bei Multiplikation und Division neutralen Eins nicht so gut erkennen lässt. Das führt zu solch versimplifizierten Aussagen, der Kosinus des Winkels sei diese Strecke bis zum heruntergeloteten Punkt, was nämlich nur beim Radius Eins stimmt. So kommt man zu Aussagen, die im allgemeinen Fall falsch sind, nämlich wenn die Hypotenuse nicht den Betrag 1 hat."

Wie es denn im allgemeinen Fall aussieht, musst du dir schon selbst erarbeiten und wenn das zu schwierig ist, eben mal wo nachgucken, was es mit dem Kosinus eines Winkels auf sich hat. Ich muss mich also andauernd wiederholen, weil du Schritte überspringst. ;)


Ich sehe nur einen:
Das Skalarprodukt entspricht der Multiplikation von unserer Gesuchten Grösse und (der Geschwindigkeit des Flusses * der Überquerungsdauer).
Bitte präzise ausdrücken, "Skalarprodukt" von was ("Das Skalarprodukt" ist undefiniert)? Warum der Umweg über die Überquerungsdauer? Das waren rhetorische Fragen, ich erwarte keine Antwort. Ansonsten sei gesagt, dass die "Geschwindigkeit des Flusses", multipliziert mit "der Überquerungsdauer" den Weg entlang des Flusses ergibt. Diese steht rechtwinklig zur gesuchten Größe (wenn man anstelle der Geschwindigkeit den Weg sucht und ich ebenfalls unterstelle, dass du mit der gesuchten Größe die in Fahrtrichtung meinst), weshalb das Skalarprodukt dieser beiden Vektoren immer 0 ist.


Das sind aber erstmal beides Unbekannte Grössen, hilft mir also nicht wirklich.
Wenn du neue Größen einführst, kann so etwas passieren.


ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y)
Woher kennen wir die Fahrtgeschwindigkeit? Wir kennen doch nur Ihre Richtung?
Es ging die ganze Zeit darum, dass du selbst herleiten kannst, dass nur die Fahrtgeschwindigkeit fehlt. Meine Herleitung ist unnütz, wenn du sie nicht zugleich und Schritt für Schritt an meinen geometrischen Skizzen verfolgst, was du aber nicht gemacht hast. Ansonsten:

Ja, es ist richtig, dass wir anstelle von Fahrtgeschwindigkeit(x;y) nur ihre Richtung haben :gratz. Den Rest musst du selbst herausfinden, sonst bringst du dich um deine Erkenntnis.(Das hatten wir aber auch schon alles beim letzten Mal).


Dann wäre es ja :
ResultierendeGeschwindigkeit(x;y)' = ResultierendeGeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y) - Fahrtgeschwindigkeit(x;y)

... was etwas soviel bedeutet:

a = b - c - c
<=>
a = b - c - c - c


http://www.youtube.com/watch?v=xTG9T-VUeXw :G :D ;)


Das kann so aber nicht Funktionieren, nicht solange die Fahrtgeschwindigkeit ein Normierter Vektor ist.
Wenn du es so machst, wie du es vorhattest, geht es tatsächlich nicht. Schön dass du es siehst. Es gibt schon Möglichkeiten, wie man an Fahrtgeschwindigkeit(x;y) kommt (daher das Beispiel).


Was, wenn ich Resultierende Geschwindigkeit.X*N.X rechne und mit Y auch, dann sollte ich ja eigentlich die Länge vom Vektor bekommen der in Richtung N geht,
Nun suchst du wenigstens den Betrag des richtigen Vektors, das ist gut. Aber befasse dich noch einmal mit den Grundlagen bzw. was ein Skalarprodukt ist. Hier solltest du erst einmal innehalten.


vorausgesetzt die 3 Resultierenden Vektoren bilden ein Rechtwinkliges Dreieck. \\o//
Na ja, einer davon ist ja gegeben (und eine Richtung). Bedenke aber, dass du bis hier hin erst den Betrag des gesuchten Vektors hättest, noch nicht den Vektor selbst.


Und wenn ich dazu nun nochmals die Differenz von resultierende Geschwindigkeit abziehe (vorzeichen beachten, der Vektor muss wieder länger werden), habe ich mein Resultat? §ugly
Bitte eindeutig ausdrücken. Das kann ich so leider nicht nachvollziehen. ;)


In der Theorie klingt es ja gut, aber funktionieren tut es nicht:


Vektor rechte = new Vektor(alteRichtung.X * N[0], alteRichtung.Y * N[1]);
Vektor diferenz = new Vektor( alteRichtung.X-rechte.X, alteRichtung.Y-rechte.Y);

Vektor resultat = new Vektor(rechte.X - diferenz.X, rechte.Y - diferenz.Y);
weder die Richtung noch die Geschwindigkeit stimmen, das kann also nicht stimmen.
Code ist auch nicht die Ebene, auf der man Probleme analysiert oder löst. Wichtige Definitionen fehlen. Wenn ich mir die alle aus den Fingern sauge und das in jeder Variante durchrechne bzw. nachvollziehe und es dann nicht stimmt, wäre es schade um die Zeit. Zu oft habe ich das schon bei dir machen müsssen und so Stunden an Lebenszeit verplempert, einmal ist Schluss damit, hatte ich auch längst gesagt, und dafür müsstest du eigentlich Verständnis haben. ;)
So wie es aussieht, versuchst du sogar etwas Vernünftiges, und den gröbsten Fehler hätte ich auch schon, wenn ich alles, was an Definitionen fehlt, immer nur zu deinen Gunsten auslege. Ob du das überhaupt so gemeint hattest, steht dort aber nicht. ;)


Hmm, schon in der ersten Zeile kann was noch nicht stimmen...
Es müsste doch lauten resultat→ ist gleich |alteRichtung→| *N→
aber dann ist meine Resultierende Länge wieder genau gleich lang wie alte Richtung, geht nur in eine andere Richtung:(
Das ist auch etwas kurz gedacht. Du sollst auch nicht den Betrag von alteRichtung→ nehmen, sondern etwas, was so lang wie der gesuchte Vektor ist.


Da wo es angeschrieben ist?:D
Unterhalb des Normalvektors, auf der jeweiligen Seite von pink wo auch a→ ist.
Wenn du ihn wirklich nur an dieser einen Stelle siehst, hast du es nicht ganz so leicht. Hättest du die Skizze mit der Spiegelung des Dreiecks angesehen, die ich vor gefühlten Ewigkeiten bereis gepostet habe, dürfte jetzt einiges klarer sein, also noch einmal:


|
|
|
|
| Kante
|
/|\ |
/ | \ → |
/ | \ a |
/ | \ |
/ (*|*) \,
<--------------------- Normalenvektor
<- Normaleneinheitsvektor

Vektor a(x;y) weist schräg nach unten.
Die gesamte Skizze ist gegenüber dem
Koordinatensystem als beliebig verdreht
anzusehen.

Und dann schau dir am besten die Skizze an, wo dieses gleichschenklige Dreieck zu einer Raute ergänzt wird. Ich hatte das ja in dem ausführlichen Beitrag weiter oben alles in der entsprechenden Reihenfolge behandelt, du müsstest es nur nutzen. Du hattest es ja leider vermieden, dich damit zu beschäftigen, jetzt holt es dich ein. ;)


sehen: ja
verstehen: nein, und solange ich es nicht hinbekommen habe/Es Funktioniert, wird sich daran ganz sicher nichts ändern.
Kommt noch, aber leider siehst du einiges noch nicht, was das Verstehen erschwert.


Also: Kosinus brauche ich nicht, gut dann vergesse ich den vorläufig ganz. Es bringt mir nichts wenn ich an 3 Stellen überlege wo nur eine richtig ist, es dauert nur 10 mal länger bis ich etwas verstehe, ein Schritt nach dem anderen.
Die wichtigste Erkenntnis soweit. :gratz
Trotzdem ist es ganz wichtig zu wissen, was der Kosinus ausdrückt, sonst ist ein Verständnis unserer Aufgabenstellung kaum möglich. Das musst du verstanden haben, um das Skalarprodukt zu verstehen (nicht um es hinschreiben zu können).


nur das 2te, nach spätestens 2^27 Durchläufen habe ich die maximale Genauigkeit von Decimal erreicht:D
Im Normalfall schon viel eher, da ich nur ein relativ kleines Spektrum betrachte, 1000 Durchläufe dürften Reichenhttp://www.worldofugly.de/ugly/030.gif
Das ist noch ganz weit von einem möglichen Funktionieren entfernt.


Dann war meine Einschätzung bezüglich der Formel mit den vielen V und n's nicht mal so schlechthttp://www.worldofugly.de/ugly/003.gif
Man kann vieles schätzen, aber nicht immer ist das Geschätzte auch zutreffend..


Was ich mich frage: woher denkst du das ich nicht weiss das ResultierendeGeschwindigkeit(x;y)' das Resultat ist?
Weil du mit noch keinem Wort eine geometrische Interpretation gegeben hattest, immer nur formale Sachen. Und auf die Frage hin, ob es geklingelt habe, hast du ja bestätigt, dass du das Diagramm zum Fluss nicht verstanden hast. Dabei habe ich mich extra bemüht, das besonders anschaulich zu machen und meine auch, dass mir das durchaus gelungen ist. Wenn du aber nicht versuchst, die Zusammenhänge zwischen den einzelnen Zeilen und ihren jeweiligen geometrischen Bedeutungen herzustellen, weißt du nicht, was ResultierendeGeschwindigkeit(x;y)' ist, sondern nur, dass das Resultat so heißt. Das ist ein fundamentaler Unterschied. Daher kann ich bei falschen Ansätzen auch nicht davon ausgehen, dass du das Richtige vor hattest. Du musst dich also selbst fragen, ob du die Skizzen verwenden willst oder nicht. Und solange du kein schlüssiges Konzept vorstellst, gehe ich davon aus, dass du dich nicht wirklich mit ihnen beschäftigt hast. Hättest du es getan, wäre so mancher deiner falschen Ansätze nicht gemacht worden. Ich sehe also beinahe genau an deinen Antworten, dass du wesentliche Teile ausgelassen hast. Deshalb muss eben diese Sache ein wenig länger dauern. ;)


Mal abgesehen davon das jeder meiner letzten Beiträge hier gut über eine Stunde aufwand und nachdenken erhalten...
und ich immer wieder mehrere Stunden Aufwand hatte, um deine Ausführungen wegen ihrer Ungenauigkeiten und formalen Fehler sowie Auslassungen mehrfach zu interpretieren, um mir dann die jeweils beste Variante herauszusuchen...
Die meisten Ausführungen waren ja von dir nicht hergeleitet, sondern lediglich nach "Einschätzungen" abgegeben. Dann musst du dich nicht wundern, wenn du dich in ihnen verzettelst. Diese Sachen, die vom Thema ablenken (Grobentwürfe zu rekursivem Näherungsverfahren, geratene Rechenwege, Doppelungen, weil du meine Sachen nicht aufmerksam nachvollzogen hast usw.) musst du nicht schreiben, dann lieferst du mir weitaus weniger Stoff, worauf ich dann nicht in geeigneter Weise reagieren müsste und du dann auch nicht usw. Ich gab dir alles vor, was du brauchst, um Schritt für Schritt ein Grundverständnis zu entwickeln, und du lässt dich nur teilweise darauf ein. Das ist eher so ein ineffizientes Querlesen und Querkommentieren, was du machst. Daher dauert das so lange. Mit einer systematischen Arbeitsweise, z.B. meinen Vorgaben entsprechend, wärst du längst mit allem durch.


Dumm, ich habe den Normalvektor als Abprall Kante genommen, schon wieder§gnah
Genau so etwas lässt ebenso die Interpretation zu, dass du von einem anderen "Resultat" ausgingest, s.o.


also das was übrig bleibt wenn ich den Kosinus zum Winkel ausrechne? (cos(Winkel X))
Dann brauche ich den Winkel ja wirklich nicht, denn diese Information wäre teil von N→
gewissermaßen auf gewisse Weise


Ich hätte auch nur S schreien können, aber stimmt schon, ausschreiben wäre wohl kein Luxus.
So wie es da steht, ist es nämlich formal falsch. Nur weil ich in deinem Sinne "Skalar" durch das richtige Skalarprodukt ersetzt habe, konnte ich dir eine Korrektheit bestätigen. Was meinst du, wie lange das jedes Mal dauert, wenn ich niet- und nagelfest durchtesten muss, wie du es wohl gemeint haben könntest? Vor allem habe ich wohl zu viel Zeit... Dies ist zwar ein einfaches Beispiel, aber leider machst das wiederholt. Wenn etwas nicht definiert ist, haben unsere Lehrer das immer durchgestrichen, 0 Punkte für die Aufgabe. Und was meinst du, was los war, wenn eine Aufgabe auf einer anderen aufbaute? Dann ging die also von falschen Voraussetzungen aus -> Thema verfehlt, 0 Punkte. Manchmal muss diese Genauigkeit einfach sein. Wenn man ihnen das hätte durchgehen lassen, hätten sie möglicherweise fest daran geglaubt, alles verstanden zu haben.


Wenn es nur ein Schritt zum Verständnis vom Skalar ist, bringt es mir ja nichts?
Da ist doch wieder diese Ungenauigkeit, was den nun "Skalar" oder "Skalarprodukt"? Ein Skalar ist bloß eine einfache Zahl, kein Vektor, trägt also keine Richtungsinformation. Beträge sind z.B. Skalare. Aber nicht jeder Skalar ist ein Betrag. Beträge sind stets positiv, während ein Skalar auch negativ sein kann, wie es bei einem Skalarprodukt immer wieder vorkommt. Und das ist gut so, weil deine Winkelfunktionen bei ihrer Umkehr das Vorzeichen nicht erkennen lassen, das Skalarprodukt schon. Damit sparst du auch deine Fallunterscheidungen.

Unsere Lösung ist performant, braucht wenige Zeilen, ist übersichtlich und funktioniert auch dann noch, wenn man eine Engine auseinanderreißt und komplett anders wieder zusammenbaut. Und sie funktioniert ebenso in einer 3D-Engine, falls du mal Interesse daran haben solltest. :)

Aus den gleichen Grundüberlegungen und Erkenntnissen heraus kann man Kollisionserkennungen für beliebige Polygone stricken. Das ist ja der Witz, weshalb sich das alles am Ende so lohnt. Du könntest unförmige Monster auf andere Monster oder auf schräge Kanten loslassen und meinetwegen deine Monster dabei noch Purzelbäume schlagen lassen usw. Einige dieser Engines können das auch gar nicht, im Prinzip sind dann auch deine Tiles egal, wären nur noch ein Stilmittel, quasi Retro-Look, der es aber ganz schön in sich hat.

LG, jabu :)

Sorry für x-Posting, musste dieses erst loswerden, hatte ich nämlich gestern begonnen.

jabu
02.08.2013, 19:25
So, nochmals alles wichtige kurz:
Alles was ich weiss ist: Die Normierte Richtung welche dem Spiele entspricht
Sowie die Richtung und Länge des Aufprallenden Bewegungsrichtungs Vektors
Ah, gut erkannt und schöne Skizze :gratz .




\ | /
\ | /
\|/
___

Was ich bereits weiss das es nicht geht, bzw mindestens eine Komponente von Blau falsch ist:
(es geht, und an Blau ist auch alles in Ordnung)


1. Länge von Orange mit N für X und Y Multiplizieren -> Blau ist zu lang
Richtig. Aber das größere Problem wäre, dass - ganz gleich welche Orientierung Orange hätte - immer das gleiche Blau herauskäme.


2. Orange mit N multiplizieren für X und Y -> Blau zu Kurz, sehr wenige Ausnahmen wo es stimmt.
Bitte nochmal darüber nachdenken, was für eine seltsame Operation du vor hast (für X und Y).


3. Orange mit -N multiplizieren für X und Y -> Blau zu Kurz, sehr wenige Ausnahmen wo es stimmt§ugly
gleiches Problem wie bei 2.



Was könnte ich noch machen?
Lernen, was ein Kosinus ist und danach lernen, was ein Skalarprodukt ist (was ich ewig wiederhole).


Laut hier (http://www.matheboard.de/archive/449869/2/thread.html) ist es ganz einfach: Länge Orang mit N(X,Y) multiplizieren.
Ich sehe dort zwar die Skizze nicht und habe auch keine Lust das alles durchzulesen, aber ich meine wohl, dass dort etwas leicht Abweichendes steht.


allerdings Dividiert er danach erst noch den Roten Vektor durch das Ergebnis§kratz
Machst du das extra, dass du immer den Wandvektor aus dem Hut zauberst?


x/|x|*a
Für die Division gibt es einen verdammt guten Grund. Schön dass du jetzt einsiehst, dass du dich noch nicht genügend mit dem Skalarprodukt beschäftigt hast, es holt dich immer wieder ein. Dann wüsstest du, weshalb er das macht. Übrigens steckt diese Division auch bei uns drin. Das ist schon ganz o.k., was du da aufgegabelt hast, wenn es auch ein reichlich chaotischer Thread ist. Aber du bist einer Sache auf der Spur. :)

LG, jabu

Multithread
02.08.2013, 20:23
So, ich versuche wie vorher langsam die Dinge zu kürzen, ich verliere sonst mehr und mehr den überblick.


"Das stimmt zahlenmäßig nur im Einheitskreis und erklärt noch nicht, was der Kosinus ausdrückt. Es geht um ein simples Verhältnis, was der Einheitskreis wegen der bei Multiplikation und Division neutralen Eins nicht so gut erkennen lässt. Das führt zu solch versimplifizierten Aussagen, der Kosinus des Winkels sei diese Strecke bis zum heruntergeloteten Punkt, was nämlich nur beim Radius Eins stimmt. So kommt man zu Aussagen, die im allgemeinen Fall falsch sind, nämlich wenn die Hypotenuse nicht den Betrag 1 hat."

Ich hab den Wiki artikel zum Kosinus jetzt sicher schon 3 mal durchgelesen, und jetzt erst bemerkt das du mich auf folgendes hinweisen wolltest:
Cosinus=Ankathete/Hypothenuse | *Hypo
cosinus * Hypothenuse = Ankathete
http://www.worldofugly.de/ugly/026.gif
Jetzt habe ich auch verstanden was du mit Bedeutung meinst.





Es ging die ganze Zeit darum, dass du selbst herleiten kannst, dass nur die Fahrtgeschwindigkeit fehlt. Meine Herleitung ist unnütz, wenn du sie nicht zugleich und Schritt für Schritt an meinen geometrischen Skizzen verfolgst, was du aber nicht gemacht hast. Ansonsten:

Ja, es ist richtig, dass wir anstelle von Fahrtgeschwindigkeit(x;y) nur ihre Richtung haben :gratz. Den Rest musst du selbst herausfinden, sonst bringst du dich um deine Erkenntnis.(Das hatten wir aber auch schon alles beim letzten Mal).

bis jetzt blieb ja jegliche erkentnis aus....




http://www.youtube.com/watch?v=xTG9T-VUeXw :G :D ;)

Zwei mal drei macht vier, widde widde witt und drei macht neune,
ich mach' mir die Welt, widde widde wie sie mir gefällt.

Hey Pippi Langstrumpf, trallahi, trallahei, trallahopsassa,
Hey Pippi Langstrumpf, die macht was ihr gefällt!

Drei mal drei macht sechs, widde widde wer will's von mir lernen?
Alle groß und klein, tralla lalla lad' ich zu mir ein.

Ich hab' ein Haus,
ein kunterbuntes Haus,
ein Äffchen und ein Pferd,
die schauen dort zum Fenster raus,
ich hab' ein Haus,
ein Äffchen und ein Pferd,
und jeder, der uns mag,
kriegt unser Einmaleins gelehrt.

Zwei mal drei macht vier, widde widde witt und drei macht neune,
wir machen uns die Welt, widde widde wie sie uns gefällt.

Drei mal drei macht sechs, widde widde wer will's von uns lernen?
Alle groß und klein, tralla lalla lad' ich zu uns ein.
$tanz

http://www.youtube.com/watch?v=KbIKJp7nEMI




Wenn du es so machst, wie du es vorhattest, geht es tatsächlich nicht. Schön dass du es siehst. Es gibt schon Möglichkeiten, wie man an Fahrtgeschwindigkeit(x;y) kommt (daher das Beispiel).


Nun suchst du wenigstens den Betrag des richtigen Vektors, das ist gut. Aber befasse dich noch einmal mit den Grundlagen bzw. was ein Skalarprodukt ist. Hier solltest du erst einmal innehalten.

Ich nehm nochmals nen Anlauf:
N entspricht der richtung von Blau (die Spiegelachse), Orange ist der Vektor den wir schon haben.

cos(Ypsilon)=((N→*Orange→)/(|N→|*|Orange→|))

|Blau→|=((N→*Orange→)/(|N→|*|Orange→|))*|Orange→|

und da N→ die Richtung von |Blau→| ist, kann ich nun Blau→ berechnen:)




Code ist auch nicht die Ebene, auf der man Probleme analysiert oder löst. Wichtige Definitionen fehlen. Wenn ich mir die alle aus den Fingern sauge und das in jeder Variante durchrechne bzw. nachvollziehe und es dann nicht stimmt, wäre es schade um die Zeit. Zu oft habe ich das schon bei dir machen müsssen und so Stunden an Lebenszeit verplempert, einmal ist Schluss damit, hatte ich auch längst gesagt, und dafür müsstest du eigentlich Verständnis haben. ;)
So wie es aussieht, versuchst du sogar etwas Vernünftiges, und den gröbsten Fehler hätte ich auch schon, wenn ich alles, was an Definitionen fehlt, immer nur zu deinen Gunsten auslege. Ob du das überhaupt so gemeint hattest, steht dort aber nicht. ;)

Code ist eine Sprache die ich verstehe, entsprechend versuche ich Probleme in dieser zu lösen. Du löst deine Probleme ja auch nicht auf Französisch.




Wenn du ihn wirklich nur an dieser einen Stelle siehst, hast du es nicht ganz so leicht. Hättest du die Skizze mit der Spiegelung des Dreiecks angesehen, die ich vor gefühlten Ewigkeiten bereis gepostet habe, dürfte jetzt einiges klarer sein, also noch einmal:


|
|
|
|
| Kante
|
/|\ |
/ | \ → |
/ | \ a |
/ | \ |
/ (*|*) \,
<--------------------- Normalenvektor
<- Normaleneinheitsvektor

Vektor a(x;y) weist schräg nach unten.
Die gesamte Skizze ist gegenüber dem
Koordinatensystem als beliebig verdreht
anzusehen.


Naja, der Vektor der am Normalvektor und an der Kante Gespielgelt ist, entspricht dem Vektor a.
Aber ich sehe nicht inwiefern mir das weiterhelfen würde.




Und dann schau dir am besten die Skizze an, wo dieses gleichschenklige Dreieck zu einer Raute ergänzt wird. Ich hatte das ja in dem ausführlichen Beitrag weiter oben alles in der entsprechenden Reihenfolge behandelt, du müsstest es nur nutzen. Du hattest es ja leider vermieden, dich damit zu beschäftigen, jetzt holt es dich ein. ;)


Kommt noch, aber leider siehst du einiges noch nicht, was das Verstehen erschwert.

Ich hab dich gewarnt das ich ne Blinde Kuh bin;)




Die wichtigste Erkenntnis soweit. :gratz
Trotzdem ist es ganz wichtig zu wissen, was der Kosinus ausdrückt, sonst ist ein Verständnis unserer Aufgabenstellung kaum möglich. Das musst du verstanden haben, um das Skalarprodukt zu verstehen (nicht um es hinschreiben zu können).

an sich brauche ich Ihn aber doch, zumindest seine beiden (oder sind es 3?) Herleitungen.




gewissermaßen auf gewisse Weise

Das ist doch mal ne aussage auf die ich aufbauen kann§ugly
Frag mich nicht wieso, aber die hilft mir echt weiter.




Da ist doch wieder diese Ungenauigkeit, was den nun "Skalar" oder "Skalarprodukt"? Ein Skalar ist bloß eine einfache Zahl, kein Vektor, trägt also keine Richtungsinformation. Beträge sind z.B. Skalare. Aber nicht jeder Skalar ist ein Betrag. Beträge sind stets positiv, während ein Skalar auch negativ sein kann, wie es bei einem Skalarprodukt immer wieder vorkommt. Und das ist gut so, weil deine Winkelfunktionen bei ihrer Umkehr das Vorzeichen nicht erkennen lassen, das Skalarprodukt schon. Damit sparst du auch deine Fallunterscheidungen.

Sagt man dann korrekt:
Skalarprodukt(a,N) ?




Unsere Lösung ist performant, braucht wenige Zeilen, ist übersichtlich und funktioniert auch dann noch, wenn man eine Engine auseinanderreißt und komplett anders wieder zusammenbaut. Und sie funktioniert ebenso in einer 3D-Engine, falls du mal Interesse daran haben solltest. :)
Ich weiss nicht ob ich Interesse an einer 3D engine habe, wenn ich schon so einen ärger mit der 2D Variante habe:dnuhr:




Aus den gleichen Grundüberlegungen und Erkenntnissen heraus kann man Kollisionserkennungen für beliebige Polygone stricken. Das ist ja der Witz, weshalb sich das alles am Ende so lohnt. Du könntest unförmige Monster auf andere Monster oder auf schräge Kanten loslassen und meinetwegen deine Monster dabei noch Purzelbäume schlagen lassen usw. Einige dieser Engines können das auch gar nicht, im Prinzip sind dann auch deine Tiles egal, wären nur noch ein Stilmittel, quasi Retro-Look, der es aber ganz schön in sich hat.

Das mit den Beliebigen polygonen will ich ja am ende:o

Was die Tiles betrift: nur damit ich einfacher Landschaften generieren kann:D



Ah, gut erkannt und schöne Skizze :gratz .

(es geht, und an Blau ist auch alles in Ordnung)


Bitte nochmal darüber nachdenken, was für eine seltsame Operation du vor hast (für X und Y).

habe ich schon, sonst hätte ich es wohl kaum verworfen;)




Lernen, was ein Kosinus ist und danach lernen, was ein Skalarprodukt ist (was ich ewig wiederhole).

also ich glaube das Skalarprodukt habe ich verstanden;)




Ich sehe dort zwar die Skizze nicht und habe auch keine Lust das alles durchzulesen, aber ich meine wohl, dass dort etwas leicht Abweichendes steht.


Machst du das extra, dass du immer den Wandvektor aus dem Hut zauberst?

Wenn ich es Extra machen würde, hätte ich das Resultat wohl schon lange gefunden.




Für die Division gibt es einen verdammt guten Grund. Schön dass du jetzt einsiehst, dass du dich noch nicht genügend mit dem Skalarprodukt beschäftigt hast, es holt dich immer wieder ein. Dann wüsstest du, weshalb er das macht. Übrigens steckt diese Division auch bei uns drin. Das ist schon ganz o.k., was du da aufgegabelt hast, wenn es auch ein reichlich chaotischer Thread ist. Aber du bist einer Sache auf der Spur. :)

LG, jabu
Ich verstehe die Formel immer noch nicht ganz, kann es sein das es das gleiche ist wie das was ich weiter oben Geschrieben habe?

jabu
02.08.2013, 22:49
Erstmal möchte ich zur wirklich guten Arbeit gratulieren, auch wenn noch Fragen verbleiben, das macht gar nichts. Der Beitrag ist halb fertig, aber leider bin ich schon zu müde, um dem Thema angemessen gerecht zu werden. Also bis dann und unbedingt weiter so (mit deinen Gleichungen kannst du weitermachen, prima)! :gratz

Multithread
03.08.2013, 06:19
Danke für alles :gratz

|Blau→|=((N→*Orange→)/(|N→|*|Orange→|))*|Orange→|

das kann man kürzen:
|Blau→|=((N→*Orange→)/(|N→|))

und da N die Länge 1 hat:

|Blau→|=(N→*Orange→)/1
^Hast du sonst noch was gemacht? Ich habe noch ein Problem mit der Gravitation welche mir die Figuren laaaaangsam durch den Boden zieht.

Aber jetzt mal ehrlich, sol das verarsche sein? das Skalarprodukt von N und Orange Entspricht der Länge von Blau?§ugly

jabu
03.08.2013, 14:15
Schade, dass ich noch nicht ganz die Zeit habe, daher nur kurz:


|Blau→|=((N→*Orange→)/(|N→|*|Orange→|))*|Orange→|
Bis dahin o.k.
Aber bedenke, was N→ ist (siehe unter nächstem Punkt)!


das kann man kürzen:
Schon, wobei es aber auf die logischen Schlüsse bzw. auf die geometrische Interpretation dieses Kürzens ankommt. Du musst einfach sehen, was du bei der Division machst. Und eigentlich müsstest du noch vor diesen Punkt gehen und dir vorstellen, was (N→*Orange→)/(|N→|*|Orange→|) bedeutet, wozu du noch einmal zurück gehen müsstest, um zu klären, was (N→*Orange→) bedeutet. Erst bei einer geometrischen Betrachtung dessen siehst du, was dort passiert. Das ist nicht ganz einfach, du musst dem Skalarprodukt beim Arbeiten zuschauen. Dann solltest du nicht nur eine formale Herleitung haben, sondern ein tiefergehendes Verständnis, was dieses Skalarprodukt macht. Das Problem (eines der letzten) ist im Moment noch, dass du das Skalarprodukt als eine Formel verwendet hast, weshalb du zu guten und richtigen formalen Schlüssen gekommen bist. Das Problem ist nur, dass ein richtiges Verstehen erst über die innere Logik des Skalarproduktes möglich ist. Also, warum ist das Skalarprodukt überhaupt eine richtige Aussage, also dieses (?):

N→ * Orange→ = |N→| * |Orange→| * cos α

Was passiert bei diesen Operationen genau, und wie kommt man darauf? Die Zeit, welche du darauf verwendest, sollte wertvoll investiert sein, denn damit sollte manches klarer werden. Das ist ja genau das, weswegen ich mir schon die Finger wund schreibe. Das mit dem Kosinus hast du verstanden, nun ist das Skalarprodukt an der Reihe.

Du stehst kurz vor der Lösung von Blau→ bzw. hast sie schon formal berechnet. Aber deine Lücke ist eben im Moment noch, dass du formal auf etwas baust, was du noch nicht ganz durchdrungen hast (Skalarprodukt).

Übrigens ist es sehr einfach, mit dem Skalarprodukt zu rechnen, aber man muss schon einiges an Vorstellungskraft hineinstecken, um seine komponentenweise Berechnung zu belegen. Aber das erwarte ich auch nicht unbedingt.


|Blau→|=(N→*Orange→)/1
^Hast du sonst noch was gemacht? Ich habe noch ein Problem mit der Gravitation welche mir die Figuren laaaaangsam durch den Boden zieht.
Beim Code bist du noch nicht. Es ist sinnlos zu programmieren, wenn man das Problem noch nicht verstanden hat, es sei denn, du möchtest deine Kenntnisse und Fertigkeiten im Bereich der Programmierung festigen. Es ist ein Irrtum deinerseits, wenn du meinst, du hättest bloß einen Fehler oder ich hätte bloß noch irgendwas gemacht. Trenne dich von Code, Softwareentwicklung ≠ Programmierung.

Btw, woher nimmst du denn N?


Aber jetzt mal ehrlich, sol das verarsche sein?
Dann wäre es das erste Mal, nein ist es nicht. Du kannst dir sicher vorstellen, wozu das führen würde, wenn ich nur an einer einzigen Stelle sowas tun würde. Die daraus resultierende Konfusion würde mich sicher überfordern bzw. unser Ziel gefährden.


das Skalarprodukt von N und Orange Entspricht der Länge von Blau?§ugly
Solange N bei dir nur ein Buchstabe ist, ist N bei dir mal das eine und mal das andere (aber in deinen Gleichungen ist N das, was es sein sollte, weshalb ich auch so erleichtert und froh bin!). Wenn es der Normalenvektor ist (Senkrechte auf der Wand), dann kann ich deine Frage für den allgemeinen Fall klar mit "Nein" beantworten. Aber ich kann dir auch verraten, dass es zur Länge von Blau proportional ist. Das ist doch schon mal nicht schlecht, oder?

Du hattest doch selbst ganz richtig Folgendes geschrieben:

|Blau→|=(( N→ * Orange→ ) / ( |N→| * |Orange→| ) ) * |Orange→|

und nicht etwa:

|Blau→|= N→ * Orange→


Lg, jabu


PS
Angehängt, was ich gestern angefangen hatte, es wird mir zu viel, das zu beenden:



Ich hab den Wiki artikel zum Kosinus jetzt sicher schon 3 mal durchgelesen, und jetzt erst bemerkt das du mich auf folgendes hinweisen wolltest:
Cosinus=Ankathete/Hypothenuse | *Hypo
cosinus * Hypothenuse = Ankathete
http://www.worldofugly.de/ugly/026.gif
Jetzt habe ich auch verstanden was du mit Bedeutung meinst.
Sehr schön! :gratz Und jetzt dürfte auch klar sein, über was der Radius 1 des Einheitskreises hinwegtäuschen kann, wenn man nicht ganz genau hinsieht.
Aber was der Kosinus ausdrückt, müsstest du quasi immer im Hinterkopf behalten, geometrisch sowie formal. Das ist also nichts, was man einfach nur nachschlägt, wenn man es gerade mal braucht. Du musst diese Sachen verinnerlichen, um dann auf ihrer Grundlage anderes sehen zu können. Je intensiver die Geometrie mit dir spricht, desto besser.

Und sorry wegen Pippi Langstrumpf, aber ich fand das an der Stelle echt zum Schreien komisch :D und danke für den Text sowie für Otto.


N entspricht der richtung von Blau (die Spiegelachse), Orange ist der Vektor den wir schon haben.
Jupp.


cos(Ypsilon)=((N→*Orange→)/(|N→|*|Orange→|))
Gut.

|Blau→|=((N→*Orange→)/(|N→|*|Orange→|))*|Orange→|
Sehr ordentlich gefolgert. :gratz

Am besten denkst du noch ein wenig darüber nach, was das bedeutet. Es gibt neben formalen Konsequenzen mehrere Ansätze, um sich das geometrisch vorzustellen. Damit solltest du so viel wie möglich herumspielen! Es kann hier und dort zu dem einen oder anderen kleinen Aha-Effekt führen, der sich noch als nützlich erweisen kann bzw. wohl noch wird.


und da N→ die Richtung von |Blau→| ist, kann ich nun Blau→ berechnen:)
Jupp, prima.


Code ist eine Sprache die ich verstehe, entsprechend versuche ich Probleme in dieser zu lösen. Du löst deine Probleme ja auch nicht auf Französisch.
Aber ich könnte sie auch in Code lösen. Dass sie dann verständlicher wären, bezweifle ich allerdings ganz stark. Du hast im Code nicht die abstrakteren Ausdrucksmöglichkeiten der Mathematik und auch weder Gleichheit noch Äquivalenz, sondern stattdessen Speicher- bzw. Variablenmanipulation. Das ist tatsächlich aber etwas unterschiedliches. Und bereits aufgrund dieser subtilen Unterschiede sind dir mehrfach Fehler nicht aufgefallen, was nicht verwundert.

Übrigens ist - wie du weißt - Softwareentwicklung kein Synonym für Programmierung. Bei der Softwareentwicklung geht es vor allem darum, erst einmal das Problem zu beschreiben. Erst im Anschluss geht es um die Umsetzung in Code. Fast alle Projekte, die irgendwann im Desaster enden, haben ihre Ursachen in dieser ersten Phase bzw. bereits bei der Beschreibung des Problems.

Und so wie meistens, sieht man das dem ineffizienten Design deiner Engine an, obwohl ich gut finde, was du gemacht hast. Das mit der Ineffizienz ist nämlich kein Werturteil meinerseits, denn es hapert bereits an der Beschreibung der Realität. Du musst nicht der beste Coder sein, um gute Produkte zu entwickeln, aber du bist gut beraten, eine gewisse Sicht auf die Realität zu entwickeln, die Entwicklern sehr eigen ist. Es ist eine eher globale, nicht so sehr im Detail verhaftete, auf einer eher abstrakten Ebene. Das fängt bei solchen Fragen an, wie z.B. : "Was ist eine Firma?" oder "Was ist ein Spiel?". Das hört sich erstmal bescheuert an, aber es trifft die Sache ziemlich genau. Und daraus ergeben sich implizit Konsequenzen bis hin in die feinen Verästelungen deiner Lösung. Sozusagen ist deine Lösung eine abstrakte Beschreibung des Problems. Wenn du jetzt sozusagen orthogonal dazu arbeitest, kannst du jede Menge feinen Code produzieren, der aber in seiner Struktur nicht dem Problem entspricht, weshalb dieser dann unwartbar wird. Am Ende bricht dann die ganze Struktur. Ich sage ja nicht, dass es so schlimm kommen muss, aber jedes größere Projekt trägt diese Problematik in sich.

Bevor jemand die Struktur eines Games anlegt, sollte er sich beispielsweise erstmal lange in einen bequemen Sessel setzen und darüber nachdenken, was Zeit, was Bewegung und was Zustände sind. Das meine ich ganz ironiefrei.

Wenn er dann seine Game-Loop bastelt und hinterher seine Animationen einbaut, kann es passieren, dass ihm das ganze um die Ohren fliegt und er Tage bis Wochen an Arbeit wegwerfen muss, weil er sich anstatt mal eine Stunde in einen bequemen Sessel tagelang an die Tastatur gesetzt hat. Und vom Sessel geht es erstmal zur Kaffemaschine, dann zum Schreibtisch, vielleicht nochmal in den Sessel usw. Irgendwann unterzieht man sich vllt. dem Krampf, etwas in die Tastatur zu hämmern, das andere ist also wichtiger und auch viel angenehmer. :D

Und es ist auch reichlich entspannter, wenn man an den Tasten nicht erst das Problem begreifen muss. Man braucht einfach diese Reserven, weil der Code schon komplex genug ist. Erst die Trennung dieser beiden Ebenen ermöglicht hochwertige Produkte.
Auf einer abstrakten Ebene fallen manche Probleme in sich zusammen, während im Code haufenweise unnötige Zeilen stehen, welche auch noch Bahnen vorgeben, welche man kaum noch verlassen kann. Und mit jeder Zeile mehr werden die Leitplanken entlang dieser Bahnen immer mehr gefestigt, was dann nicht mehr zu der Frage führt, wie man ein Problem löst, sondern zu: "Wie mache ich das in meinem Code?" Spätestens dann sollte man merken, dass es an dem Code liegt, nicht an dem Problem selbst. Daher ist es manchmal gut, sich vorhandenen Code erstmal nicht mehr anzusehen, weil er gleich mit seiner Beschränktheit Vorgaben macht, die mit dem eigentlichen Problem nichts zu tun haben.

... (einfach zu viel)


also ich glaube das Skalarprodukt habe ich verstanden;)
Du kannst es benennen, Verstehen ist eine andere Ebene, aber schön, dass du dabei bist!

Multithread
03.08.2013, 17:57
Bis dahin o.k.
Aber bedenke, was N→ ist (siehe unter nächstem Punkt)!

Entsprechend habe ich es auch umgesetzt:

kollisionPunkt = (new Point((int)(lx / _wande.Count), (int)(ly / _wande.Count)));
senkrechte = new Vektor(_g.X - kollisionPunkt.X, _g.Y - kollisionPunkt.Y);
}
_g.Kollisionsrichtung = senkrechte;

double value = Math.Sqrt((double)(senkrechte.X * senkrechte.X + senkrechte.Y * senkrechte.Y));
decimal[] N = new decimal[2];
N[0] = senkrechte.X / (decimal)value;
N[1] = senkrechte.Y / (decimal)value;

decimal skalarAN = (alteRichtung.X * N[0] + alteRichtung.Y * N[1]);

Vektor resultat = new Vektor(skalarAN * N[0], skalarAN * N[0]);
return resultat;
Irgendwann brauche ich das ganze nochmals, deshalb möchte ich auch das verständnis vom Skalar noch machen.
Irgendwann ist dann, wenn es darum geht das man auch schräge Böden laufen kann, sprich das die Bewegungsrichtung die ich vorgebe nicht exakt dem Boden entlang muss, sondern das ich das dann beim bewegen regeln kann:D

So was ich jetzt noch gemerkt habe: wenn ich SkalarAN mit N multipliziere, dann habe ich nur die Richtung vom Schwerpunkt zum Kollisionspunkt, da muss ich jetzt nochmals die Differenz zwischen resultat und alteRichtung von resultat subbtrahieren.



Schon, wobei es aber auf die logischen Schlüsse bzw. auf die geometrische Interpretation dieses Kürzens ankommt. Du musst einfach sehen, was du bei der Division machst. Und eigentlich müsstest du noch vor diesen Punkt gehen und dir vorstellen, was (N→*Orange→)/(|N→|*|Orange→|) bedeutet, wozu du noch einmal zurück gehen müsstest, um zu klären, was (N→*Orange→) bedeutet. Erst bei einer geometrischen Betrachtung dessen siehst du, was dort passiert. Das ist nicht ganz einfach, du musst dem Skalarprodukt beim Arbeiten zuschauen. Dann solltest du nicht nur eine formale Herleitung haben, sondern ein tiefergehendes Verständnis, was dieses Skalarprodukt macht. Das Problem (eines der letzten) ist im Moment noch, dass du das Skalarprodukt als eine Formel verwendet hast, weshalb du zu guten und richtigen formalen Schlüssen gekommen bist. Das Problem ist nur, dass ein richtiges Verstehen erst über die innere Logik des Skalarproduktes möglich ist. Also, warum ist das Skalarprodukt überhaupt eine richtige Aussage, also dieses (?):

N→ * Orange→ = |N→| * |Orange→| * cos α

die innere Logik suche ich noch.
Auch wenn Sie da Mathematisch vor mir steht:(




Was passiert bei diesen Operationen genau, und wie kommt man darauf? Die Zeit, welche du darauf verwendest, sollte wertvoll investiert sein, denn damit sollte manches klarer werden. Das ist ja genau das, weswegen ich mir schon die Finger wund schreibe. Das mit dem Kosinus hast du verstanden, nun ist das Skalarprodukt an der Reihe.

Du stehst kurz vor der Lösung von Blau→ bzw. hast sie schon formal berechnet. Aber deine Lücke ist eben im Moment noch, dass du formal auf etwas baust, was du noch nicht ganz durchdrungen hast (Skalarprodukt).

Wäre nicht das erste mal das ich sowas mache*unschuldig umherpfeif*




Übrigens ist es sehr einfach, mit dem Skalarprodukt zu rechnen, aber man muss schon einiges an Vorstellungskraft hineinstecken, um seine komponentenweise Berechnung zu belegen. Aber das erwarte ich auch nicht unbedingt.


Beim Code bist du noch nicht. Es ist sinnlos zu programmieren, wenn man das Problem noch nicht verstanden hat, es sei denn, du möchtest deine Kenntnisse und Fertigkeiten im Bereich der Programmierung festigen. Es ist ein Irrtum deinerseits, wenn du meinst, du hättest bloß einen Fehler oder ich hätte bloß noch irgendwas gemacht. Trenne dich von Code, Softwareentwicklung ≠ Programmierung.

Mein erster verdacht war ja: das sich die Schwerkraft über die Kollision gesetzt hat, aber das hat sich auf 2 Arten nicht bestätigt: Deine Worte und der Fakt das die Bewegungsrichtung nicht gerade nach unten war:D




Btw, woher nimmst du denn N?

Nomierte Richtung des Kürzesten weges vom einen Ufer zum anderen:)




Solange N bei dir nur ein Buchstabe ist, ist N bei dir mal das eine und mal das andere (aber in deinen Gleichungen ist N das, was es sein sollte, weshalb ich auch so erleichtert und froh bin!). Wenn es der Normalenvektor ist (Senkrechte auf der Wand), dann kann ich deine Frage für den allgemeinen Fall klar mit "Nein" beantworten. Aber ich kann dir auch verraten, dass es zur Länge von Blau proportional ist. Das ist doch schon mal nicht schlecht, oder?


Nomierte Richtung des Kürzesten weges vom einen Ufer zum anderen:)




Du hattest doch selbst ganz richtig Folgendes geschrieben:

|Blau→|=(( N→ * Orange→ ) / ( |N→| * |Orange→| ) ) * |Orange→|

und nicht etwa:

|Blau→|= N→ * Orange→


Inwiefern soll das nicht die Gleiche Gleichung sein?


|Blau→|=(( N→ * Orange→ )* |Orange→|
( |N→| * |Orange→| ) )
kürzen:


|Blau→|=(( N→ * Orange→ )* |Orange→|
( 1 * |Orange→| ) )
bleibt:


|Blau→|= N→ * Orange→
Ich bin mir fast 100% sicher das ich da keinen Fehler gemacht habe beim umformen.





Sehr schön! :gratz Und jetzt dürfte auch klar sein, über was der Radius 1 des Einheitskreises hinwegtäuschen kann, wenn man nicht ganz genau hinsieht.
Aber was der Kosinus ausdrückt, müsstest du quasi immer im Hinterkopf behalten, geometrisch sowie formal. Das ist also nichts, was man einfach nur nachschlägt, wenn man es gerade mal braucht. Du musst diese Sachen verinnerlichen, um dann auf ihrer Grundlage anderes sehen zu können. Je intensiver die Geometrie mit dir spricht, desto besser.

ob man sowas wieder vergisst? meist leider sehr schnell wenn man es nicht mehr braucht:(





Und sorry wegen Pippi Langstrumpf, aber ich fand das an der Stelle echt zum Schreien komisch :D und danke für den Text sowie für Otto.

kp, bin ein Humorvoller Mensch, wie du ev. schon bemerkt hast:D




Am besten denkst du noch ein wenig darüber nach, was das bedeutet. Es gibt neben formalen Konsequenzen mehrere Ansätze, um sich das geometrisch vorzustellen. Damit solltest du so viel wie möglich herumspielen! Es kann hier und dort zu dem einen oder anderen kleinen Aha-Effekt führen, der sich noch als nützlich erweisen kann bzw. wohl noch wird.

der Aha Effekt blieb bisher aus:(




Aber ich könnte sie auch in Code lösen. Dass sie dann verständlicher wären, bezweifle ich allerdings ganz stark. Du hast im Code nicht die abstrakteren Ausdrucksmöglichkeiten der Mathematik und auch weder Gleichheit noch Äquivalenz, sondern stattdessen Speicher- bzw. Variablenmanipulation. Das ist tatsächlich aber etwas unterschiedliches. Und bereits aufgrund dieser subtilen Unterschiede sind dir mehrfach Fehler nicht aufgefallen, was nicht verwundert.

kann sein.



Übrigens ist - wie du weißt - Softwareentwicklung kein Synonym für Programmierung. Bei der Softwareentwicklung geht es vor allem darum, erst einmal das Problem zu beschreiben. Erst im Anschluss geht es um die Umsetzung in Code. Fast alle Projekte, die irgendwann im Desaster enden, haben ihre Ursachen in dieser ersten Phase bzw. bereits bei der Beschreibung des Problems.

Ne, synonyme sind es nicht, aber Programmieren setzt fast zwingend Softwareentwicklung voraus:D



Und so wie meistens, sieht man das dem ineffizienten Design deiner Engine an, obwohl ich gut finde, was du gemacht hast. Das mit der Ineffizienz ist nämlich kein Werturteil meinerseits, denn es hapert bereits an der Beschreibung der Realität. Du musst nicht der beste Coder sein, um gute Produkte zu entwickeln, aber du bist gut beraten, eine gewisse Sicht auf die Realität zu entwickeln, die Entwicklern sehr eigen ist. Es ist eine eher globale, nicht so sehr im Detail verhaftete, auf einer eher abstrakten Ebene. Das fängt bei solchen Fragen an, wie z.B. : "Was ist eine Firma?" oder "Was ist ein Spiel?". Das hört sich erstmal bescheuert an, aber es trifft die Sache ziemlich genau. Und daraus ergeben sich implizit Konsequenzen bis hin in die feinen Verästelungen deiner Lösung. Sozusagen ist deine Lösung eine abstrakte Beschreibung des Problems. Wenn du jetzt sozusagen orthogonal dazu arbeitest, kannst du jede Menge feinen Code produzieren, der aber in seiner Struktur nicht dem Problem entspricht, weshalb dieser dann unwartbar wird. Am Ende bricht dann die ganze Struktur. Ich sage ja nicht, dass es so schlimm kommen muss, aber jedes größere Projekt trägt diese Problematik in sich.

Ja, das design ist sicher nicht das effizientiste, aber es geht dabei auch darum das ich was neues Lerne.
Ob du es mir glaubst oder nicht, aber das Design wird noch effizienter§ugly
Sieht man sehr gut an CoRG (die dll). Deren Design ist bereits um einiges weiter entwickelt, genau genommen ganze 2 Jahre weiter:D




Bevor jemand die Struktur eines Games anlegt, sollte er sich beispielsweise erstmal lange in einen bequemen Sessel setzen und darüber nachdenken, was Zeit, was Bewegung und was Zustände sind. Das meine ich ganz ironiefrei.

Sagen wir es mal so: ich weiss selber noch nicht so genau was ich am ende da haben werde und haben möchte:(
Wobei ich als Entwickler möchten fast direkt in haben umsetzten kann:D




Wenn er dann seine Game-Loop bastelt und hinterher seine Animationen einbaut, kann es passieren, dass ihm das ganze um die Ohren fliegt und er Tage bis Wochen an Arbeit wegwerfen muss, weil er sich anstatt mal eine Stunde in einen bequemen Sessel tagelang an die Tastatur gesetzt hat. Und vom Sessel geht es erstmal zur Kaffemaschine, dann zum Schreibtisch, vielleicht nochmal in den Sessel usw. Irgendwann unterzieht man sich vllt. dem Krampf, etwas in die Tastatur zu hämmern, das andere ist also wichtiger und auch viel angenehmer. :D

Das ist ein teil von OO, sobald du an Tausenden stellen was ändern musst, ist etwas schiefgelaufen, meist reicht es einige "Wenige" stellen zu ändern. Aber nen Affenschwanz kann das immer dran haben, habe ich auch schon gesehen.




Und es ist auch reichlich entspannter, wenn man an den Tasten nicht erst das Problem begreifen muss. Man braucht einfach diese Reserven, weil der Code schon komplex genug ist. Erst die Trennung dieser beiden Ebenen ermöglicht hochwertige Produkte.
Auf einer abstrakten Ebene fallen manche Probleme in sich zusammen, während im Code haufenweise unnötige Zeilen stehen, welche auch noch Bahnen vorgeben, welche man kaum noch verlassen kann. Und mit jeder Zeile mehr werden die Leitplanken entlang dieser Bahnen immer mehr gefestigt, was dann nicht mehr zu der Frage führt, wie man ein Problem löst, sondern zu: "Wie mache ich das in meinem Code?" Spätestens dann sollte man merken, dass es an dem Code liegt, nicht an dem Problem selbst. Daher ist es manchmal gut, sich vorhandenen Code erstmal nicht mehr anzusehen, weil er gleich mit seiner Beschränktheit Vorgaben macht, die mit dem eigentlichen Problem nichts zu tun haben.

Das ist meine schwäche, ich löschen depricated Zeilen meist sehr spät.
Entsprechend viele Altlasten findet man sehr oft noch in meinem Code:(




Du kannst es benennen, Verstehen ist eine andere Ebene, aber schön, dass du dabei bist!
$§p4 Ay Ay Capitansci

jabu
05.08.2013, 15:19
I fixed your code, quick and dirty:


// Bedenke, dass _wande hier keine Liste von Wand-Elementen ist.

public Vektor abprallen(Gegenstand _g, List<Point> _wande, GravitationRichtung _richtung)
{
Point position = new Point(_g.X, _g.Y);
Vektor alteRichtung = _g.Bewegungsrichtung;
Vektor senkrechte = null;
Point kollisionPunkt = Point.Empty;

if (_wande.Count > 0)
{
long lx = 0;
long ly = 0;
foreach (Point _p in _wande)
{
lx += _p.X;
ly += _p.Y;
}
// arithmetischer Mittelwert von Kollisionspunkten, etwas unglücklich,
// wenn man es in diesem Kontext verwendet
kollisionPunkt = (new Point((int)(lx / _wande.Count), (int)(ly / _wande.Count)));

// Nicht wirklich senkrecht
senkrechte = new Vektor(_g.X - kollisionPunkt.X, _g.Y - kollisionPunkt.Y);
}

double value = Math.Sqrt((double)(senkrechte.X * senkrechte.X + senkrechte.Y * senkrechte.Y));
decimal[] N = new decimal[2];
N[0] = senkrechte.X / (decimal)value;
N[1] = senkrechte.Y / (decimal)value;

decimal skalarAN = (alteRichtung.X * N[0] + alteRichtung.Y * N[1]);

skalarAN *= -1m; // dass es sich um komplett die falsche Richtung handeln musste,
// fällt auch erst dann auf, wenn man sich klar macht, was da läuft.

Vektor resultat = new Vektor(skalarAN * N[0], skalarAN * N[1]); // Vertipper "N[0]"

_g.Bewegungsrichtung = resultat; // return wirkungslos, daher diese Zeile
return resultat; // return wirkungslos, s.o.

So läuft es nun in deiner neuen Engine (VYPH2D_Game_Engine_Demo). Allerdings ist nicht nur die Senkrechte schief und ihr Winkel zusätzlich noch von Rundungsfehlern zerhackstückelt, sondern handelt es sich doch nur um eine Teillösung. Unter Beseitigung dieser Ungenauigkeiten hätte "resultat" die Richtung der Normale und als Betrag den Betrag des Anteils der ursprünglichen Geschwindigkeit, welcher in Normalenrichtung weist, was man praktisch als die Ankathete in Normalenrichtung ansehen kann. So wie du es hattest, war leider keine Funktion erkennbar.

Und dann fehlt noch eine Bilder.ini als Beispiel. Die Funktion, die aus Hintergrund.List und Bilder.ini liest, ist nämlich strukturell defekt. Es mag ja sein, dass sie unter ganz bestimmten Voraussetzungen funktioniert, kannst also mal so ein Beispiel geben, wie die Bilder.ini aussehen soll (in deinen gezippten Ordnern ist jedenfalls keine dabei). Bis dahin habe ich die alte Funktion zum Laden der Bilder in die neue Engine eingebaut und die Datentypen entsprechend angepasst, was gar nicht so einfach war.
So, wie du die Hintergrund.List mit der Bilder.ini in einer Funktion verwurstest, ist das strukturell defekt. Kannst ja mal was neues hochladen, wenn du damit weiter bist. Jedenfalls ist die Vorgängerversion(dtQTkaxkGbbMvPLy2D_Game_Engine_Demo) bisher diejenige mit den wenigsten Schmerzen.

MfG, jabu

jabu
05.08.2013, 16:19
Was du hattest, ist dieses:


kollisionPunkt = (new Point((int)(lx / _wande.Count), (int)(ly / _wande.Count)));

// Versuch, die Normale durch einen Abstandsvektor zu ersetzen:
// Leider ist senkrechte nicht senkrecht, siehe hier:
//
// _g
// \
// \ |
// \|______kollisionPunkt
// |\
// \_g (kann auch schon hier sein)
//
// Wie man sieht, muss senkrechte keinen nennenswerten Betrag haben,
// was zu mehr oder minder starken Rundungsfehlern führt,
// die sehr oft die Richtung erkennbar umbiegen.
//
senkrechte = new Vektor(_g.X - kollisionPunkt.X, _g.Y - kollisionPunkt.Y);
//
// Die Klammer sagt mir, dass ich nicht wissen kann,
// unter welchen Voraussetzungen dein Code ausgeführt wird.
}

// lustigerweise weißt du hier wieder,
// dass die Senkrechte nicht senkrecht ist...
// Ich behaupte aber, dass du diesen Quark einfach vom alten Code kopiert hast...
// Dieser Vektor weist vom Kollisionspunkt weg und hin zu _g.
//
_g.Kollisionsrichtung = senkrechte;

// value = |senkrechte|
//
double value = Math.Sqrt((double)(senkrechte.X * senkrechte.X + senkrechte.Y * senkrechte.Y));

decimal[] N = new decimal[2]; // o.k.

// Normieren von senkrechte auf den Betrag 1
//
N[0] = senkrechte.X / (decimal)value;
N[1] = senkrechte.Y / (decimal)value;

// Skalarprodukt aus alteRichtung und dem Einheitsvektor zu senkrechte
// entspricht der Ankathete mit umgekehrtem Vorzeichen
//
decimal skalarAN = (alteRichtung.X * N[0] + alteRichtung.Y * N[1]);

// N weist in die selbe Richtung wie senkrechte,
// also weg von kollisionPunkt und hin zu _g.
// Unsere Ankathete hat ein umgekehrtes Vorzeichen,
// woraus folgt, dass die komponentenweise Multiplikation
// zu einem Vektor in gegenrichtung zu N,
// also grob in die alteRichtung führt.
//
//
Vektor resultat = new Vektor(skalarAN * N[0], skalarAN * N[0]);
return resultat;




Irgendwann brauche ich das ganze nochmals, deshalb möchte ich auch das verständnis vom Skalar noch machen.
Irgendwann ist dann, wenn es darum geht das man auch schräge Böden laufen kann, sprich das die Bewegungsrichtung die ich vorgebe nicht exakt dem Boden entlang muss, sondern das ich das dann beim bewegen regeln kann:D
Einerseits wird es dafür ganz schön nützlich sein, andererseits brauchst du es schon jetzt...


So was ich jetzt noch gemerkt habe: wenn ich SkalarAN mit N multipliziere, dann habe ich nur die Richtung vom Schwerpunkt zum Kollisionspunkt,
Kann man mit "ungefähr" beantworten.


da muss ich jetzt nochmals die Differenz zwischen resultat und alteRichtung von resultat subbtrahieren.
Da aber bereits deine Senkrechte grob in Bewegungsrichtung weist (was auch mal entgegengesetzt sein kann), wird nicht viel dabei herauskommen, auch wenn das prinzipiell keine schlechte Idee ist. Das ist nämlich piepegal, wie herum man das rechnet. Am Ende fällt die Differenz eh aus der Rechnung heraus.


Nomierte Richtung des Kürzesten weges vom einen Ufer zum anderen:)
Eine Normale ist nicht automatisch normiert. Hier ist sie es nicht, also leider falsch. ;)


Inwiefern soll das nicht die Gleiche Gleichung sein?


|Blau→|=(( N→ * Orange→ )* |Orange→|
( |N→| * |Orange→| ) )
kürzen:


|Blau→|=(( N→ * Orange→ )* |Orange→|
( 1 * |Orange→| ) )
bleibt:


|Blau→|= N→ * Orange→
Ich bin mir fast 100% sicher das ich da keinen Fehler gemacht habe beim umformen.
Diese Sicherheit wird dir doch immer wieder zum Verhängnis.


kp, bin ein Humorvoller Mensch, wie du ev. schon bemerkt hast:D
§5troet Sonst hätte ich auch schon nen Fön bekommen...


Das ist ein teil von OO, sobald du an Tausenden stellen was ändern musst, ist etwas schiefgelaufen, meist reicht es einige "Wenige" stellen zu ändern. Aber nen Affenschwanz kann das immer dran haben, habe ich auch schon gesehen.
Dessen bin ich mir sogar ziemlich sicher. ;)

LG, jabu