| Autor |
Beitrag |
klezmor
      
Beiträge: 558
delphi 6 personal delphi 2005 personal
|
Verfasst: Mo 24.10.05 18:24
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mi 26.10.05 14:51
Zwei Möglichkeiten:
- Bresenham Linien Algorithmus
- Mit Floats:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| dx := target_x-robot_x; dy := target_y-robot_y; L := sqrt(sqr(dx)+sqr(dy)); robot_x := robot_x + dx/L*SchrittWeiteInPixel; robot_y := robot_y + dy/L*SchrittWeiteInPixel; |
Wobei robot_x, robot_y und L floats sein müssen.
|
|
klezmor 
      
Beiträge: 558
delphi 6 personal delphi 2005 personal
|
Verfasst: Mi 26.10.05 22:39
Das funzt bei mir kein bisschen, leider verstehe ich diesen Algorhythmus nicht deshalb kann ich ihn auch nicht so in mein Programm einbauen, wie ich es für sinnvoll halte.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mi 26.10.05 23:23
Dann hast du ihn falsch eingebaut
Hier die Erklärung:
Delphi-Quelltext 1: 2:
| dx := target_x-robot_x; dy := target_y-robot_y; |
dx, dy: Die "Abstände" in x und y Richtung. [dx,dy] kann man sich als Vektor vorstellen, der von Robot nach Target zeigt.
Delphi-Quelltext 1:
| L := sqrt(sqr(dx)+sqr(dy)); |
L ist der Abstand zwischen target und robot in Pixels, bzw. die Länge des Vektors.
Delphi-Quelltext 1: 2:
| robot_x := robot_x + dx/L; robot_y := robot_y + dy/L; |
Die letzten beiden Zeilen bewegen den Roboter um 1 Pixel Richtung Target. Wieso? v = [dx,dy] ist der Vektor, welcher von Robot aus in Richtung Target zeigt; und der Vektor hat Länge L. Teilt man nun den Vektor v durch L, dann hat man die Einheitsrichtung; d.h. der Vektor, der 1 Pixel lang ist und in die korrekte Richtung zeigt. Diesen Vektor muss du zu [robot_x, robot_y] hinzuzählen, dann bist du 1 Pixel näher beim Target. Natürlich muss das ganze in Floats rechnen, da dx und dy i.A. kleiner als 1 sind und beim Runden eventuell auf 0 abgerundet werden würden...
|
|
klezmor 
      
Beiträge: 558
delphi 6 personal delphi 2005 personal
|
Verfasst: Di 01.11.05 20:41
Wenn man eine Linie zeichnet, dann müsste die Schrittweitinpixel ja = 1 sein, wenn ich dich richtig verstanden habe.
Ich glaube allerdings nicht, dass der algorhythmus, den du mir gegeben hast fähig ist eine linie zu zeichnen, denn wenn ich die schrittweite = 1 setze, würde eine ganz krumme line herauskommen. Kennt zufällig jemand den wirklichen linien algorhythmus.
|
|
klezmor 
      
Beiträge: 558
delphi 6 personal delphi 2005 personal
|
Verfasst: Di 01.11.05 20:45
Um mich nochmals klar auszudrücken ich will das shape so bewegen, dass es einer zuvor mit dem befehl canvas.moveto/lineto gezeichneten linie, hinterherfährt. Deshalb muss ich wissen wie der computer so eine line zeichnet?
|
|
klezmor 
      
Beiträge: 558
delphi 6 personal delphi 2005 personal
|
Verfasst: Mi 16.11.05 21:06
Wenn ich meinen alten algorhythmus verwende bewegt sich das shape oft erst gerade und lenkt dann plötzlich schräg ein, das liegt sicher an rundungsfehler, aber ich weiß nich wie ich die beheben kann.
Ich will einfach eine gleichmäßige gleichförmige Bewegung, die die ganze zeit den gleichen winkel zur x achse hat.
|
|
klezmor 
      
Beiträge: 558
delphi 6 personal delphi 2005 personal
|
Verfasst: Mo 21.11.05 18:26
Ok mein letzter versuch etwas leben in meinen thread zu bekommen.
Weiß wirklich niemand wie man ein objekt direkt zu einer vorgegebenen position verschieben kann, am besten sollte es ein flüssige bewegung sein.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 27.11.05 00:19
Ich habe dir eine funktionierende Antwort bereits gegeben. Falls du nicht mit floats rechnen willst, dann kannst du mal unter dem Begriff Bresenham Linien Algorithmus suchen. Beim Bresenham-Linienalgorithmus ist jedoch zu vermerken, dass die Schrittweite nur dann 1 Pixel ist, wenn eine horizontale oder vertikale Linie gezeichnet wird. Die Schrittweite ist im Extremfall 1.4 (sqrt(2)).
Nochmals zur Verdeutlichung meiner Antwort oben:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| dest = Zielort source = Anfangsort
p = dest-source L = length(p) dx = p/L
x = source while length(x-dest)>0.5 x = x + dx end |
PS: dest, source, p und dx sind Vektoren. L ist eine Zahl.
Zuletzt bearbeitet von delfiphan am Di 29.11.05 16:30, insgesamt 1-mal bearbeitet
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: So 27.11.05 09:59
klezmor hat folgendes geschrieben: | Ok mein letzter versuch etwas leben in meinen thread zu bekommen.
Weiß wirklich niemand wie man ein objekt direkt zu einer vorgegebenen position verschieben kann, am besten sollte es ein flüssige bewegung sein. |
Lies doch einfach mal, was delpfiphan geschrieben hat. Das ist ja nicht zum aushalten. Willst Du, das wir das auch noch buchstabieren? Bresenham Linien Algorithmus (ohne 'y'). Wikipedia.de. Vektorrechnung. Googel mal danach oder schau im Wiki nach. Mann!
_________________ Na denn, dann. Bis dann, denn.
|
|
klezmor 
      
Beiträge: 558
delphi 6 personal delphi 2005 personal
|
Verfasst: Mi 30.11.05 15:57
Ich glaube ihr versteht mich nicht richtig. Natürlich soll die schrittweite immer 1 pixel betragen. Wenn ich eine linie mit moveto, lineto zeichne dann ist die schrittweise ja auch immer ein pixel, auch wenn ich keine vertikale bzw. horizontale linie zeichne.
sonst gäbe es ja immer lücken bei bestimmten linien.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mi 30.11.05 18:48
Stimmt, ich verstehe nicht, was Du meinst. Wenn Du etwas von A nach B bewegst, aber nur Integer-Mathematik verwenden kannst (wie eben bei Pxeln), dann wird sich dein Bild zwangsweise entweder nach rechts, nach schräg rechts oder nach oben bewegen (unter der vereinfachten Annahme, das A.X <= B.X und A.Y <=B.Y ist).
_________________ Na denn, dann. Bis dann, denn.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 02.12.05 09:12
Mit Schrittweite 1 Pixel meine ich die Distanz zwischen zwei gezeichneten Pixel (angenommen ein Pixel wird als Dirac-Puls interpretiert)
Wenn du eine Linie von 0/0 nach 3/4 mit Schrittweite 1 Pixel zeichnest, dann heissen die exakten Koordinaten folgendermassen:
0.0 / 0.0
0.6 / 0.8
1.2 / 1.6
1.8 / 2.4
2.4 / 3.2
3.0 / 4.0
Von jedem Punkt zum nächsten ist die Distanz = Schrittweite = 1 Pixel (Nachprüfen mit Pythagoras).
Wenn du mit Bresenham eine Linie zeichnest, dann gehst du immer entweder geradeaus, oder schräg nach unten. Beim Geradeausgehen ist die Schrittweite 1; beim schräg nach unten gehen jedoch ca. 1.41 (=sqrt(2)).
Extremfall: Wenn du eine Linie von 0/0 bis 5/5 zeichnest, bist du in 5 Schritten dort, obwohl die Distanz ca. 7 ist! Dein Robot läuft also schräg schneller als horizontal.
|
|
klezmor 
      
Beiträge: 558
delphi 6 personal delphi 2005 personal
|
Verfasst: Sa 03.12.05 22:16
Ja und wie kann ich das problem dann lösen. Bei delphix gibt es doch auch funktionen, bei denen sich ein objekt regelmäßig in eine richtung bewegt oder?
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 04.12.05 00:30
Ich habs jetzt 3 mal erklärt, ich geb dir jetzt einfach mal den Source.
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:
| const Schrittweite = 1; var RobotX, RobotY, ZielX, ZielY, dx, dy, L: Extended; begin RobotX := 100; RobotY := 10; ZielX := 200; ZielY := 200; while sqr(RobotX-ZielX)+sqr(RobotY-ZielY) > sqr(Schrittweite/2) do begin dx := ZielX-RobotX; dy := ZielY-RobotY; L := sqrt(sqr(dx)+sqr(dy)); dx := dx/L; dy := dy/L; RobotX := RobotX + dx*Schrittweite; RobotY := RobotY + dy*Schrittweite; VerschiebeRoboterNach(Round(RobotX), Round(RobotY));
end; end; |
|
|