| Autor |
Beitrag |
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Do 03.03.11 20:00
|
|
F34r0fTh3D4rk
      
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Do 03.03.11 22:35
Du könntest dazu deine eigene Methode schreiben. Einfach auf Papier mal den allgemeinen Fall für den Schnitt zweier Geraden durchrechnen. Das kannst du dann ziemlich direkt implementieren.
Dann musst du es nur noch prüfen, ob der Schnitt in einem bestimmten Intervall auf deinen Geraden liegt, dann hast du die Kollision der Strecken.
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: Do 03.03.11 22:41
Das hab ich doch oben schon alles implementiert?! Ich hab das auch auf Papier umgestellt und berechnet. Ich hab sogar stichpunktartig die Rechnung mit aufgeschrieben. Ich versteh grad iwie nich wo es noch Probleme gibt
MfG Bergmann
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
beastofchaos 
      
Beiträge: 247
Erhaltene Danke: 4
|
Verfasst: Fr 04.03.11 20:36
Ich habe bisher mit einer zweiten Unit gearbeitet, in der alle Vektorfunktion definiert sind. Nun gibts da nco heni paar Fragen. z.B. hab ich die Funktion meistens mit dem Praefix "v2d_" verziert. Nun möchte ich eine classe erstellen, in der die Funktionen ohne Suffix genannt sind. Denn dann muss man im Programm v2d.add oder sonst was schreiben. Meine Unit müsste doch dann ungefähr so aussehen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| . . . type TVector2d = record
. . .
V2d = Class; function add(v1, v2: TVector2D): TVector2D; fucntion sub(v1, v2: TVector2D): TVector2D; . . . end; |
Aber wenn ich mal die Forms im Standardprogramm als Vorbild nehme wird das da so deklariert:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| . . . TForm1 = Class(TForm); . . . end; |
Muss man diese Class (irgendein Typ) machen der kann ich das umgehen?
edit: sollte ich vll einfach "V2d = Class(TObject);" schreiben oder wäre das falsch?
|
|
Marc.
      
Beiträge: 1876
Erhaltene Danke: 129
Win 8.1, Xubuntu 15.10
|
Verfasst: Fr 04.03.11 20:39
beastofchaos hat folgendes geschrieben : | Muss man diese Class (irgendein Typ) machen der kann ich das umgehen?
edit: sollte ich vll einfach "V2d = Class(TObject);" schreiben oder wäre das falsch? |
Das wäre sogar äquivalent.
Die Klasse in den Klammern ist die übergordnete (engl. Super) Klasse, von der deine Klasse erbt. Dabei stammt jede Klasse immer von TObject ab. Insofern brauchst du die nicht explizit in den Klammern mit anzugeben.
Schau dir auf jeden Fall mal den Abschnitt über OOP aus Christians Tutorial an. 
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: Fr 04.03.11 23:14
Hey,
dann würd ich aber die Methoden der Klasse als Klassenmethoden machen. Diese arbeiten dann ohne eine Referenz auf ein Objekt der Klasse. Eig ist es dann nix anderes als vorher, nur das du die Methoden über den Klassennamen aufrufst:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| type TTest = class class procedure DoIt; end;
class procedure TTest.DoIt; begin ShowMessage('Done'); end;
procedure TForm1.FormCreate(Sender: TObject); begin TTest.DoIt; end; | So musst du kein Objekt der Klasse erstellen. Das hat den Vorteil, das du mehr Ordnung in deinen Methoden hast und deine Vektoren aber immer noch per Zuweisung übergeben kannst. Wenn du jetzt eine komplett neue Klasse für deine Vektoren erstellst, wo auch die VektorDaten von der Klasse verwaltet werden, dann kannst du die Werte nicht mehr per Zuweisung übergeben. Bsp:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| type TVector = class x, y: Single; procedure DoSomething; constructor Create(x, y); end;
procedure TForm1.FormCreate(Sender: TObject); var v1, v2: TVector; begin v1 := TVector.Create(35.3, 7.6); v2 := v1; end; | v1 und v2 zeigen jetzt beide auf das selbe Objekt, es sind nich nur die selben Werte, sondern es wird der selbe Speicher benutzt. Und dann müsstest du deinen kompletten Methoden umstellen, da du da ja bestimmt relativ oft Zuweisungen drin hast, oder?
Es sei denn du hast eine etwas neuere Delphi-Version, bei der man die Operatoren überladen kann. Da kann man sich das dann wieder so zusammenbauen, das eine Zuweisung die Daten zwichen den Objekten kopiert, also nur die Werte übernimmt und nicht nur den Speicher. Aber ich denke mit KlassenMethoden ist das erreicht was du erreichen wolltest und das Programm muss nicht großartig verändert werden.
MfG Bergmann
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
beastofchaos 
      
Beiträge: 247
Erhaltene Danke: 4
|
Verfasst: Sa 05.03.11 00:46
Das ist jetzt ein Missverständnis xD
Mit der Klasse V2d will ich nur auf Prozeduren und Funktionen greifen. Den Typ Vector2d hab ich schon vorher definiert
Also eigentlich sieht das so aus:
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:
| Unit Vektoren;
uses Windows;
type
TVector2D = record x, y: extended; end; TLine = record p, r: TVector2d; end; . . . V2d = class procedure Reflect(var A, B: TVector2D): TVector2D; function StraightStraightIntersection(A, B: TLine): TVector2D; function add(A, B: TVector2D): TVector2D; . . . end; . . . procedure V2d.Reflect(var A, B: TVector2D): TVector2D; . . . |
Und V2d soll übrigens ja kein "Objekt", wie man es sich vll in der Realität vorstellt, sein, sondern der "Bereich" Vektor2d...
also ich werde es jetzt so wie hier machen, da das anscheinend eine gute Lösung ist 
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: Sa 05.03.11 01:01
Hey,
na genauso meinte ich das auch. Nur das normale Methoden dann objektgebunden sind. Und KlassenMethoden eben nicht. Ich bin mir nicht sicher ob es da irgendwelche Probleme gibt, wenn da kein Objekt angelegt wird. Eigentlich arbeitest du ja nicht mit objektgebundenen Variablen, aber sicher ist sicher, dehalb das class vor die Methoden.
Vlt kann da aber auch jmd anderes nochmal Licht ins Dunkel bringen. Hab damit auch ncoh nich so viel Erfahrung.
MfG Bergmann.
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
beastofchaos 
      
Beiträge: 247
Erhaltene Danke: 4
|
Verfasst: Sa 05.03.11 10:27
Jep, das kann sein. Ich machs so und hoffe, dass es keine Probleme gibt. Wenn doch, dann greif ich doch gerne auf deine Methode zurück
Ich dachte, jetzt hab ich eigentlich alles, aber es gibt wohl doch noch einen kleinen Denkfehler bei mir :/
Und zwar die Reflektion. Da Einfallswinkel = Ausfallswinkel und die Länge des einfallenden Vektors gleich der des austretenden Vektors ist, gilt doch folgendes:
(siehe Bild 1)
man kann auch andersrum arbeiten, also, anstatt den Vektor a mit -1 mal zu nehmen, die andere Normale nimmt und ganz am Ende den ausfallenden Vektor dann -1 mal nimmt. Heißt:
siehe (Bild 2)
in meiner function sieht das dann so aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| function TForm1.Reflect(v, bar: TVector2D): TVector2D; var bar_n: TVector2D; Alpha, len: extended; begin len := v2d_length(v); v := v2d_normalize(v); bar_n := v2d_normalize(to_v2d(-bar.y, bar.x));
Alpha := ArcCos(v2d_dotproduct(v, bar_n)); if Alpha > 90 then bar_n := v2d_scale(bar_n, -1);
result := v2d_scale(v2d_sub(v2d_scale(bar_n, 2), v), -len);
end; |
MfG Thomas
Einloggen, um Attachments anzusehen!
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Sa 05.03.11 11:20
Vektoren machen (teure) Winkelberechnungen eigentlich immer überflüssig. Allgemein bildest du über (a . u) * u einen Vektor a auf einen Einheitsvektor u ab (rechne es nach  ). Hier wird also v auf n abgebildet und verdoppelt, sodass sich eine Raute ergibt, von deren Spitze nur noch v abgzogen werden muss: mathworld.wolfram.com/Reflection.html. Das Schöne an dieser Projektion: Es ist ganz egal, in welche Richtung n zeigt.
Vielleicht siehst du jetzt auch, was an deinen Bildern falsch ist: Du gehst davon aus, dass die Pfeilspitzen von a, b, und n auf einer Parallelen zum Objekt liegen, was i.A. natürlich nicht der Fall ist. Deswegen erst diese Projektion.
beastofchaos hat folgendes geschrieben : | Wenn doch, dann greif ich doch gerne auf deine Methode zurück  |
Oder du machst es gleich richtig, denn deine Klasse zu instanzieren macht wirklich nicht viel Sinn  .
_________________ >λ=
|
|
beastofchaos 
      
Beiträge: 247
Erhaltene Danke: 4
|
Verfasst: So 06.03.11 00:14
ALso der Unterschied ist doch im moment:
1.Beispiel(meine Idee):
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:
| . . . type procedure to_v2d(v1, v2: TVector2D): TVector2D;
V2d = class procedure add(v1, v2: TVector2D): TVector2D; procedure sub(v1, v2: TVector2D): TVector2D; . . . end; . . . procedure V2d.add(v1, v2: TVector2D): TVector2D; begin result.x := v1.x + v2.x; result.y := v1.y + v2.y;
. . .
procedure TForm1.Create(Sender: TObject); var a, b, c: TVector2D; begin a := to_v2d(3, 4); b := to_v2d(4, 5); c := v2d.add(a, b); end; |
2. Beispiel(Eure Empfehlung):
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:
| . . . type procedure to_v2d(v1, v2: TVector2D): TVector2D;
V2d = class class procedure add(v1, v2: TVector2D): TVector2D; class procedure sub(v1, v2: TVector2D): TVector2D; . . . end; . . . class procedure V2d.add(v1, v2: TVector2D): TVector2D; begin result.x := v1.x + v2.x; result.y := v1.y + v2.y;
. . .
procedure TForm1.Create(Sender: TObject); var a, b, c: TVector2D; begin a := to_v2d(3, 4); b := to_v2d(4, 5); c := v2d.add(a, b); end; |
Und was hab ich jetzt im ersten Beispiel falschgemacht, was ihr im zweiten nicht gemacht habt?
Vll gibt mir dieses Tutorial Abhilfe, aber ich kam noch nicht dazu, es zu lesen... :/ vll morgen
Grüße, Thomas
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: So 06.03.11 00:25
Hey,
in dem Tutorial stand darüber nix (zumindest hab ich beim überfliegen nix gesehen).
Der Unterschied zu deiner und unserer Methode ist folgender: Deine Methoden arbeiten normalweiße nur, wenn man mithilfe der Klasse ein Objekt erstellt: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| type TTest = class procedure DoIt; end;
var Test: TTest;
Test := TTest.Create; Test.DoIt; Test.Free; | Du musst das Objekt erstellen und wieder freigeben. Wenn du jetzt aber kein Objekt erstellst, dann kann das unvorhersehbare Folgen haben. Deshalb sollst du es ja gleich richtig machen. Wenn du eine KlassenMethode erstellst, dann ist das nichts anderes als eine normale Methode (so wie du es jetzt in der Unit hast) nur das man die Methoden zur besseren Übersicht in die Klassen ablegen kann. Ein Konstructor ist z.B. auch eine Klassenmethode und kann ohne ein Objekt aufgerufen werden: Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| type TTest = class class procedure DoIt; end;
TTest.DoIt; | Du musst kein Objekt erstellen um die Methode aufzurufen. Und das ist genau das was du machen wolltest. Natürlich arbeitet dein Programm jetzt, aber das kann auch schnell mal nach hinten los gehen. Also lieber gleich ordentlich arbeiten. Und das kleine Wort class vor den Methoden ist nun wirklich keine Arbeit von mehreren Stunden
MfG Bergmann
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
Zuletzt bearbeitet von Bergmann89 am So 06.03.11 00:38, insgesamt 1-mal bearbeitet
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: So 06.03.11 00:32
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: So 06.03.11 00:39
Ja natürlich^^ Habs angepasst. Scheiß copy&paste, bringt nur Schwierigkeiten 
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
beastofchaos 
      
Beiträge: 247
Erhaltene Danke: 4
|
Verfasst: Di 08.03.11 23:56
Und was ist dann der Unterschied, ob ich davor ein "class" setzte oder nicht. Also nicht, ob es dann eine Klassenfunktion oder nicht ist, sondern was zweckmäßig ein Vorteil/Nachteil ist.
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: Mi 09.03.11 14:41
Hey,
das ham wir doch die ganze Zeit gesagt  Du musst kein Objekt anlegen und kannst die Methoden gleich über die Klasse aufrufen. Und die Klassenmethoden sind nu mal für das vorgesehen, was du vor hast, also solltest du sie auch benutzen. Und wenn du deine Methode benutzt ohne ein Objekt anzulegen, dann ist das sowieso falsch:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| type Test = class procedure DoIt; end;
var Test: TTest;
Test.DoIt; |
Und wenn du erst ein Objekt anlegen musst, dann musst du das auch überall benutzen können, wo du die Methoden benutzen willst. Also entweder wird das eine globale Variable (was sowieso schlecht ist), oder du musst jedesmal ein neues Objekt anlegen (was auch umständlich ist). Deshalb --> KLASSENMETHODEN!
MfG Bergmann
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
beastofchaos 
      
Beiträge: 247
Erhaltene Danke: 4
|
Verfasst: Mi 09.03.11 17:51
Ah, ich glaube jetzt hats Klick bei mir gemacht  Hab alles angeschaut und die Erleuchtung gefunden - also Unterschied ist, dass bei mir ein Typ deklariert wird und ich dann extra ein Objekt dafür noch in var angeben muss ( stimmt doch, oder? ) und dass bei euch die funktionen/prozeduren kein objekt brauchen sondern man einfach den Typen, ein punkt und dann die jeweilig funktion dann aufruft - also TTest.DoIt ( bei mir wäre es an der stelle Test.DoIt, bloß gäb es mehr drumherum gefasel xD ).
Danke danke xD
Ich weiß nicht, ob ich das noch mache, aber wüsstet ihr, nachdem ich das mit den Ecken- und Kugel-reflektionen verstanden habe, auch wie ich das bei dem gegenteil einer kugel mache, also, dass da eine halbe kugel als hindernis ist.
1. wie zeichne ich so ne halbe kugel in Delphi
2. müsste dann wieder die "äußere" tangente ( also die Orthogonale zum Vektor vom Mittelpunkt der Spielkugel zum Mittelpunkt der Hinderniskugel ) als reflektionsfläche zeichnen?
Ich weiß nicht, ob ich das relativ gut erklärend gefragt habe, aber hier ein bildchen für die situation im anhang
MfG Thomas
Einloggen, um Attachments anzusehen!
|
|
|