Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Drehender Würfel für den Informatikunterricht


Tris12345 - So 09.01.11 21:55
Titel: Drehender Würfel für den Informatikunterricht
Hallo liebe Community!
Ich habe in Informatik die Aufgabe bekommen, eine Würfel zu programmieren, der sich um den Mittelpunkt des Würfels dreht.
Die Würfelform habe ich hinbekommen, doch mit den cos und sin Formeln, die mir der Lehrer gegeben hat, kann ich einfach nichts anfangen.
Ich bitte um Hilfe und am Besten auch um eine Erklärung des Vorgangs.
Vielen Dank im Voraus!

Quelltext bisher:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
unit Unit7;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button1_Ende: TButton;
    Button2_drehen: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button1_EndeClick(Sender: TObject);

  private
    { private declarations }
  public
    { public declarations }
  end

var
  Form1: TForm1; 

implementation

{ TForm1 }

procedure TForm1.Button1_EndeClick(Sender: TObject);
begin
  close;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Canvas.MoveTo (200,150);
Canvas.LineTo( 150,200);
Canvas.LineTo (150,300);
Canvas.LineTo(250,300);
Canvas.LineTo (300,250);
Canvas.LineTo (300,150);
Canvas.LineTo(200,150);
Canvas.LineTo(200,250);
Canvas.LineTo (150,300);
Canvas.MoveTo (150,200);
Canvas.LineTo (250,200);
Canvas.LineTo(300,150);
Canvas.MoveTo (200,250);
Canvas.LineTo(300,250);
Canvas.MoveTo (250,200);
Canvas.LineTo (250,300);

end;

initialization
  {$I unit7.lrs}

end.


Moderiert von user profile iconMartok: Delphi-Tags ergänzt


bummi - So 09.01.11 22:18

Ich fürchte Dein Ansatz wird Dich nicht weit bringen..., vielleicht hilft Dir dieser Link

http://www.delphipraxis.net/107915-3d-wuerfel-mit-canvas-bitte-um-hilfe.html


Tris12345 - Mo 10.01.11 12:19

Leider kann ich damit genauso wenig anfangen. Meine bisherige Vorgehensweise hat eine Würfel erzeugt und ich weiß einfach nicht, wie ich die Koordinaten in einen Prozess binden soll, der die Punkte immer weiter in einem bestimmten Winkel verschiebt, so das eine Drehung um den Mittelpunkt entsteht


jaenicke - Mo 10.01.11 12:59

user profile iconTris12345 hat folgendes geschrieben Zum zitierten Posting springen:
ich weiß einfach nicht, wie ich die Koordinaten in einen Prozess binden soll, der die Punkte immer weiter in einem bestimmten Winkel verschiebt, so das eine Drehung um den Mittelpunkt entsteht
Dein Problem ist kein programmiertechnisches, sondern ein mathematisches.

Der entscheidende Punkt ist: Wie bist du denn auf die Koordinaten gekommen? Genau, du hast die berechnet. Und genau das muss dein Programm machen. Die Koordinaten als Zahlenwerte vorzugeben, bringt logischerweise nichts, da diese variieren.

Nimm dir einfach einmal ein Blatt Papier und erstelle die Rechnung manuell. Das selbe musst du dann nur noch im Quelltext schreiben. Das ist aber der kleinste Teil der Arbeit.

Gegeben ist wahrscheinlich am sinnvollsten der Mittelpunkt des Würfels sowie dessen Seitenlänge. Dazu dann noch der aktuelle Winkel in jeder Richtung. Und jetzt musst du aus diesen Angaben die Koordinaten der Ecken des Würfels berechnen.

Wenn du diese Berechnungen hast, dann kannst du das im Quelltext hinschreiben und mit den ergebenden Koordinaten zeichnen.


Bergmann89 - Di 11.01.11 02:36

Hey,

Stichwort Matrix [http://de.wikipedia.org/wiki/Matrix_%28Mathematik%29] ;)
Alle Daten in ne Matrix packen un dann kann man ganz easy damit rechnen. Mit der sogenannten ProjektionsMatrix kann man die 3D-Punkte dann auf einen 2D-Schirm projezieren. Ich hab das ganze mal eben schnell zusammen gebastelt (siehe Anhang). Jetzt ist die Fragem ob ihr Matricen schon dran hattet (Vektoren sollten dir auf alle Fälle ein Begriff sein). Wenn nicht einfach ma schnell einlesen, brauchst ja eig nur bisl MatrixMultiplikation, den Rest kann man sozusagen abschreiben ;) Das tolle an der Projektionsmatrix ist, das es dann auch wirklich 3D aussieht, mit Fluchtpunkt und allem drum und dran. Wenn du das ganze nich selbst machen willst, dann kannst du auch OpenGL das Zeichen überlassen. Mit den Einsteiger-Tutorials auf DelphiGL [http://wiki.delphigl.com/index.php/Tutorial] sollte man in ein paar Tagen das gewünschte Ergebnis erzielen können.
Wenn du irgendwo Progleme hast kannste ja nochma Fragen, wir helfen gern :)

MfG Bergmann.


Dude566 - Di 11.01.11 15:19

@user profile iconBergmann89,

könntest du den Quelltext zu dieser Demo bitte OpenSource machen, ich hatte zwar schon Vektorrechnung etc aber habe kein Plan wie ich soetwas realisieren könnte? :flehan:


Martok - Di 11.01.11 15:55

Perspektivisch ist hier sicher etwas an der Frage vorbei, ich würde mal raten es geht um Parallelprojektion. Die ist jedenfalls mit nur sin/cos machbar, ohne noch Matrizen einführen zu müssen. Wenn der Fragesteller gesagt hätte, welche Formeln er hat wäre das auch einfacher ;)
Ich hatte sowas [http://www.martoks-place.de/temp/ScreenShot-5053.png] grade gebaut, wenn ich Zeit haben sollte kann ich da ja mal eine Demo draus drechseln. Kann ich aber nicht für garantieren...
EDIT: mir fallen grade ein paar Optimierungen ein, das wird wohl wirklich mal ein Tutorial bzw FAQ-Eintrag. Wenn auch wohl nicht mehr rechtzeitig für den OP :|


Tris12345 - Di 11.01.11 16:42

Erst einmal vielen Dank für die Hilfestellungen.
Die Formeln waren die Folgenden:

Delphi-Quelltext
1:
2:
x1:=500 + Round(radius*cos((i*Pi)/180));
y1:=200 + Round(radius*sin((i*Pi)/180));

Nebenbei bemerkt: Die Formeln sehe ich jetzt gerade zum ersten Mal. Mir hat ein Teil der Aufgabe gefehlt, den ich mir jetzt von einem Mitschüler geholt habe. Leider bringt mir selbst diese Formel nicht viel mehr.

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


Jakob_Ullmann - Di 11.01.11 21:02

Ich arbeite mich mal von innen nach außen durch - in der Hoffnung, dass du mit Sinus und Kosinus etwas anzufangen weißt und von Bogenmaß nach Gradmaß bzw. anders herum umrechnen kannst.

(i * Pi) / 180 ist der Winkel, der im Gradmaß den Wert i° hat, umgerechnet ins Bogenmaß
(Erinnerung: 180° = pi)

cos(i°) [zur Vereinfachung, aber nichts anderes ist es], ist im folgenden Dreieck der Wert Ankathete/Hypotenuse.


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
        x
       /|
Hypo- / |
ten- /  |
use /   |
   /_   |  Gegenkathete
  /  \  |
 / i° | |
x-------x
   Ankathete


Hier ist Radius = Hypotenuse.

Radius * cos(i°) ist also Radius * (Ankathete/Radius) = Ankathete!!!

Mit Round() machst du daraus eine gerundete Ganzzahl.
500 ist eine Verschiebung nach rechts, ein "Offset".

Dasselbe macht die zweite Formel für die Gegenkathete (daher sin() und nicht cos()).


Delphi-Laie - Mi 12.01.11 11:47

user profile iconTris12345 hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe in Informatik die Aufgabe bekommen, eine Würfel zu programmieren, der sich um den Mittelpunkt des Würfels dreht.


Um einen Punkt, also ein nulldimensionales Gebilde, dreht sich im Raume / in drei Dimensionen bzw. dreht sich ein räumliches / dreidimensionales Gebilde nicht(s) oder wenigstens nicht eindeutig, sondern um eine Drehachse, also um ein eindimensionales Gebilde, und nur um diese(s) eindeutig.


jaenicke - Mi 12.01.11 11:54

Warum? Ich habe mir drei Regler für die drei Raumachsen vorgestellt, so dass man den Würfel in jede drehen kann.


Tris12345 - Mi 12.01.11 18:15

Bergmann?
Würdest du mir mal den Quelltext von dem Projekt geben, ich würde das gerne sehen und verstehen, weil ich so einfach keinen Anfang finde.


Bergmann89 - Mi 12.01.11 18:24

Ungern, weil ich nich sicher bin, ob du den Code einfach kopierst und dann abgibst. Ich kann dir ne Einstiegshilfe geben un bei konkreten Problemen kannst du gerne Fragen.
Zur Erklärung, eine Matrix besteht aus 4 Vektoren: einen für die x-Achse, einen für die y-Achse, einen für die z-Achse und einen für die Position. Etwa so:

Quelltext
1:
2:
3:
4:
x y z p
x y z p
x y z p
1 1 1 1

Auf die Matrix kann man jezt ganz normale Matrixoperationen anwenden: Rotation, Translation, Skalieren, ... (siehe Wikipedia). Diese Matrix nennt sich Modelmatrix und enthält die Transformationsvorschriften für die 3D-Punkte. Man kann jetzt jeden beliebigen Punkt mit der Matrix multiplizieren, als Ergebnis erhält man den gleichen Punkt, als wenn man die Transformationen auf einen Punkt einzelln angewendet hätte. Bsp.: du willst einen Punkt erst verschieben, um einen bestimmten Winkel drehen und nochma verschieben. Das könntest du jetzt für jeden Punkt einzelln ausrechnen, das ist aber sehr umständlich. Also erstellst du dir die Matrix und multiplizierst dann nur noch die Punkte mit der Matrix.
Jetzt musst du deine Punkte nur noch auf den 2D-Schrim bekommen, dazu gibt es die ProjektionsMatrix. Angenommen die Achse, die aus dem Bildschirm heraus kommt sei die z-Achse, dann würde die Projektionsmatrix so aussehen:

Quelltext
1:
2:
3:
4:
1 0 0 0
0 1 0 0
0 0 0 0
0 0 z 1

mit z = -1/CAM_POS

CAM_POS ist der Abstand der Camera zum 0-Punkt, also ein Wert auf der z-Achse. wenn du jetzt einen Punkt mit dieser Matrix multiplizierst, dann wird er auf die XY-Ebene projeziert (z wird 0). Der Einfachheit halber kann man die ProjektionsMatrix vor dem Berechnen der Punkte auch mit der ModelMatrix multiplizieren, dann muss man nur noch eine Multiplikation für jeden Punkt durchführen.

Was du jetzt brauchst ist eine ordentliche Datenstruktür für die Matrix, die Punkte und deinen Würfel. Weiterhin benötigst du die Methoden, die das ganze berechnen. Kongret brauchst du da die Multiplikation 2er Matricen, die Multiplikation einer Matrix mit einem Punkt und die Rotation einer Matrix. Das sollte dir den Einstieg etwas leichter machen...

MfG Bergmann.


Tris12345 - Mi 12.01.11 18:55

^^Ist mir schon klar, dass du dir das denkst, aber ich komm einfach nicht zurecht. Die Aufgabe ist meiner Meinung nach für 4 Tage sehr knapp bemessen, wenn wir noch nie was damit zu tun hatten und einfach ein paar Formeln bekommen.
Ich werde sehen, ob ich was schaffe. Ich danke dir erstmal für die ganzen Hilfen!


Bergmann89 - Mi 12.01.11 18:59

Naja das is sozusagen die Profilösung. Euer Lehrer hat sich das sicher auch etwas einfacher gedacht, nehme ich an. Sicher das er einen Würfel wollte und kein Viereck? Zur Not bau dir erstmal ein Viereck, was sich dreht. Das verzerrst du dann etwas (so das es nach ner Paralellprojektion aussieht), dann machst du noch ein 2. drunter und verbindest die 2, dann hast du auch deinen Würfel. DAs sollte in 4 Tagen mit den gegebenen Formeln zu schaffen sein ;)

MfG Bergmann.


Boldar - Mi 12.01.11 23:48

Man kann auch ohne das Wort Matrix je gehört zu haben, die Formeln im 3-dimensionalem Raum benutzen. Danach muss man eine Projektion durchführen, aber auch das geht ohne Matrizenrechnung.
http://www.minfos.de/selfdxd/DirectXGraphics/theorie/dg_ber.html#rotieren3d
http://de.wikipedia.org/wiki/Parallelprojektion