Anfänger freut sich über Hilfe, "Bewegung" über zweidimensionales Array in Ansi C
-
Hallo zusammen,
ich bin kompletter Neuling im Prgrammieren und habe nur einfachste C-Erfahrung, aber hier ein ganz gutes Nachschlagewerk mit Beispielen liegen.
Ich möchte eine Simulation programmieren, die folgendes leistet.
Es gibt ein oder zwei zweidimensionale Arrays. Diese Stellen im Prinzip ein Schachbrett mit den verschiedenen Kästchen dar. Die äußersten Kästchen des Brettes dienen als Begrenzung der Fläche und werden mit irgendeinem Zeichen beschrieben. Alle anderen Felder bekommen anfangs eine 0.
Ein Array kann hier für die Begrenzung dienen und eins für die Nullen oder man erstellt ein kombiniertes.Nun kommt der kniffelige Teil, bei dem ich noch keine Ahnung habe, wie er zu realisieren ist.
Ich möchte das ein "Ball" in einem bestimmten Feld mit vorgegeben Winkel in eine vorgegebene Richtung fliegt und dabei jedes Brettchenfeld, was er kreuzt um einem Wert erhöht. Sobald der "Ball" auf die äußere Begrenzung des Arrays trifft, soll er mit einem vorgegebenen Richtungswechsel und Winkel erneut über das Brett fliegen und die Werte der überflogenen Kästchen erhöhen.Diese Simulation soll herauszufinden, ob ein Objekt, was es wirklich gibt und sich nach bestimmten Regeln verhällt, eine Fläche nach einer hinreichend großen Dauer gleichmäßig überquert, oder ob es Lücken gibt.
Am ende soll einfach nach einer bestimmten Zeit eine Zahlenmatrix herauskommen.
Ich habe bisher keine Idee, wie ich diesen fliegenden Ball realisieren soll und bin auch sonst für Hilfe und Beispiele sehr dankbar!
Vielen Dank
-
Wie realistisch soll das sein? Einerseits klingt deine Beschreibung nach einem vereinfachten Pong, andererseits macht mich aber
Diese Simulation soll herauszufinden, ob ein Objekt, was es wirklich gibt und sich nach bestimmten Regeln verhällt, eine Fläche nach einer hinreichend großen Dauer gleichmäßig überquert, oder ob es Lücken gibt.
stutzig.
Zwei (von vielen) Ansätzen:
1. Direkte numerische Integration der Bewegungsgleichungen: Klingt kompliziert, bedeutet aber einfach, dass du (zeit-)schrittweise vorgehst und deinen Ball entsprechend seiner Geschwindigkeit in jedem Schritt versetzt. Optimalerweise ist der Zeitschritt so gewählt, dass der Ball in jedem Schritt um ungefähr ein Kästchen, aber nicht mehr, weitergesetzt wird.
2. Event-driven: Da es einfach berechenbar ist, wo der Ball das nächste Mal die Wand treffen wird, kannst du genau dies (und auch den Weg dahin) berechnen und einfach alle Kästchen auf dem Weg markieren.Was in beiden Fällen noch eine Schwierigkeit werden kann, ist das Abprallen an der Wand. Je nach deinem Anspruch an Realismus reicht da ein einfaches Umkehren der Geschwindigkeit oder aber extrem komplizierte Methoden, die auch Fälle beachten, an die du jetzt wahrscheinlich noch nicht einmal denkst.
-
Vielen Dank für die Antwort!
Zum Realitätsanspruch sei gesagt, dass die Geschwindigkeit bei der Simulation keinerlei Rolle spielt und für das Abprallen gibt es feste Regeln wie z.B. wenn der Ball links auftrifft muss er nach rechts abprallen und das in einem Winkel zwischen 100° und 120° der per Zufall entschieden werden soll.
Aber für den Anfang gehts mir nur darum zu verstehen, wie ich das ganze überhaupt realisieren kann.
Die Feinheiten kann man dann nach und nach einsetzenIm Prinzip ist es erstmal ein vereinfachtes Pong.
Gibt es irgendwo Codebeispiele für die von dir genannten Ansätze?
-
Britzi schrieb:
Gibt es irgendwo Codebeispiele für die von dir genannten Ansätze?
Ich kenne keine speziellen, gratis, online Lehrbeispiele dafür, wenn es das ist, was du meinst. An sich werden diese Vorgehensweisen, besonders die erste, aber überall benutzt, wo sich irgendetwas bewegt. Sollte sich daher auch in vielen Lehrwerken zu Spielen finden. Und natürlich in Lehrwerken zu Simulationen, danach hast du schließlich gefragt und daher kommen auch die Antworten, die ich dir gegeben habe.
So schwierig ist das aber nicht, eigentlich solltest du das auch als Anfänger aus dem Stand hinbekommen, sofern dir die Grundmittel zu Aufbau eines Programms vertraut sind. Gerade die erste Methode ist doch das, worauf man als allererstes selber kommt, oder? Die zweite habe ich eigentlich nur genannt um zu zeigen, dass die Welt größer ist und weil sie hier extrem gut passt.
Oder heißt "Codebeispiele" bloß so viel wie "Ich habe keine Lust, kann das jemand für mich machen?"? Kommt hier leider viel zu oft vor.
-
Nein, ich möchte es schon selbst machen, aber mein Problem ist, dass ich absoulut nicht die leisteste Ahnung habe, wie sich überhaupt Bewegungen in C realisieren lassen und schon gar nicht in Kombination mit Arrays.
Dazu sagt mein schlaues Handbuch für C leider auch nichts!
Da gibts alles, aber nichts mit Bewegung!Kannst du vielleicht ein paar Stichwörter nennen, die ich nachschlagen kann?
Ich stehe einfach völlig auf dem Schlauch.Danke
-
Hallo Britzi,
eine Bewegung ist ersteinmal nur die Veränderung eines Punktes, d.h. (x,y) => (x+dx, y+dy), wobei dx und dy jeweils die Veränderung (delta) pro Achse ist.
Bei deiner Simulation mußt du jedoch jetzt 2 Dinge beachten:
1. Größe deines Balles
2. Rasterung der Ballposition auf das SchachbrettFür den einfachsten Fall: als Ballgröße ersteinmal 0 anzunehmen, d.h. nur den Punkt selbst beachten, brauchst du nur die aktuellen Punktkoordinaten auf das Brett projizieren.
Wenn du für x und y eine Fließkommazahl (float oder double) benutzt, kannst du einfach die Nachkomastellen per cast auf int abschneiden, um die Brettposition zu erhalten:double x, y; x += dx; y += dy; int brett_x = (int)x; int brett_y = (int)y;
Wenn dein Ball auch noch einen Radius > 0 hat, dann mußt du jedoch noch entscheiden/berechnen, welche Brettposition(en) dein Ball einnimmt.
Es ist jedoch generell von Vorteil, wenn du dich mit Vektorrechnung auskennst, da dies das Verständnis für Bewegungssimulationen stark vereinfacht.
P.S. Nützlich für deine Simulation ist noch der Wiki-Artikel Polarkoordinaten, denn du möchtest ja die Bewegung (bzw. Bewegungsänderung) mittels eines Winkels ausdrücken.
Um von Polarkoordinaten (Winkel alpha, Länge r) auf kartesische Koordinaten (x, y) zu kommen, einfach die Formel
dx = r * cos(alpha); dy = r * sin(alpha);
anwenden (beachte, daß alpha dabei im Bogenmaß anzugeben ist und r ist die Bewegungsänderung je Simulationsschritt (z.B. 0.01)!).
-
Vielen Dank,
ich bin nun etwas weiter gekommen, aber leider nur etwas.
Wenn ich z.B. ein 3x3 Array habe, wie schaffe ich es mit einer Schleife nur die drei diagonalen Felder zu treffen?
Und warum tut sich bei meinem Code nur was in der Zeile, nicht aber in Spalte?
Wieso soll ich für das Delta ein double nehmen und wie genau abschneiden?
Ich verstehe das leider noch nicht so richtig.Ich bin da echt ratlos.
Anbei mein Code, soweit wie ich nun gekommen bin.
Ich würde mich sehr über Verbesserungen und Ergänzungen freuen
Vielen Dank!
#include <stdio.h> #define zeilen 8 #define spalten 8 int x, y; x=5, y=5; // Schrittweite int main(void){ int brett[zeilen][spalten]; int j,i; for (j=0; j < zeilen; j++) { //Array, was in Inhalt auf Null setzt und "Zaun" bildet for (i=0; i < spalten; i++) { if (i==0 || i == spalten-1 || j == 0 || j == zeilen-1) { brett[j][i] = -9; } else { brett[j][i] = 0; } } } i = 1; j = 1; for (; j % x != 0 && j < zeilen; j++) { // Hier fehlt die zündende Idee. for (; i % y != 0 && i < spalten; i++) { brett[j][i] = brett [j][i]+1; //Wert eines Feldes um 1 erhöhen } } for (i=0; i<spalten; i++) { printf("\n"); for (j=0; j<zeilen; j++) printf("%d", brett[j][i]); } getchar(); }
-
Falsche Herangehensweise, falsche Denkweise. Du hast ein Feld, also denkst du, du müsstest irgendwie über alle Felder iterieren. Das hat aber mit deinem Problem und seiner Lösung überhaupt nichts zu tun, daher gibt es auch keine "zündende Idee", die man an der Stelle einfügen könnte.
Du musst stattdessen über dein Problem nachdenken (Ansätze wurden dir gegeben) und wie du dessen Lösung mit den dir bekannten Mitteln umsetzen kannst, anstatt wie du dein Problem in dir bekannte Lösungen für andere Probleme hämmern kannst.
Ein Ansatz für meinen Ansatz 1:
int x,y; // Position int vx, vy; // Geschwindigkeit for (step = 0; step < max_steps; ++step) { // x und y ausrechnen. // Eventuell vx und vy ausrechnen // feld[x][y] erhöhen }
-
Vielen Dank!
Ich habe es geschafft
Der letzte Tipp hat gefruchtet.Nun muss ich nur noch die Winkel einsetzten.
Bisher ändert sich der Winkel nicht, aber sonst läuft alles.Danke nochmals!
-
Viel Erfolg noch bei deiner Simulation.