Autor Beitrag
klezmor
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: Mo 24.10.05 18:24 
Ich will ein typ namens robot, welcher die abgeleitete klasse von nem shape ist, zu einem von mir vorgegeben punkt bewegen lassen, das problem ist dass sich das shape schräg bewegen soll bei nem winkel von 45 Grad müsste ich ja dann einfach ein pixel in x und ein pixel in y richtung dazuaddieren aber bei anderen winkel weiß ich nicht wie ich das mathematisch lösen soll, so weit bin ich schon:
ausblenden 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:
procedure trobot.movePoint(const target_x,target_y:integer);
var robot_x,robot_y:integer;
    gradiant:real;
begin
robot_x:=left+(width div 2);
robot_y:=508-Top+Height ;
 if (robot_x<target_x) then 
 begin
  if (robot_y<target_y) then
  begin
  gradiant:=(target_y-robot_y)/(target_x-robot_x);// grad berechnen
  left:=left+?;// was muss hier hin 
  top:= top+ ?;// was muss hier hin
  end

  else
  begin

  end


 end

 else
 begin


 end;
end;


Moderiert von user profile iconChristian S.: Delphi-Tags hinzugefügt.
Moderiert von user profile iconTino: Option "Großbuchstaben im Titel erlauben?" aktiviert.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mi 26.10.05 14:51 
Zwei Möglichkeiten:

- Bresenham Linien Algorithmus
- Mit Floats:

ausblenden 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;
// mit z.B. SchrittWeiteInPixel := 1

Wobei robot_x, robot_y und L floats sein müssen.
klezmor Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mi 26.10.05 23:23 
Dann hast du ihn falsch eingebaut ;)

Hier die Erklärung:
ausblenden 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.

ausblenden 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.

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: 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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: So 27.11.05 09:59 
user profile iconklezmor 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 04.12.05 00:30 
Ich habs jetzt 3 mal erklärt, ich geb dir jetzt einfach mal den Source.

ausblenden 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;