Entwickler-Ecke

Multimedia / Grafik - Steuerung eines Punktes von Startpunkt zum Zielpunkt


dr. rom4o - Di 13.09.05 16:48
Titel: Steuerung eines Punktes von Startpunkt zum Zielpunkt
Hallo Leute, ich verzweifele bald.
Ich arbeite in diesem Projekt zur Zeit in tmt-Pascal aber
kann man ja einfach auf Delphi übertragen.
Ich möchte einen Punkt über den schnellsten Weg zu einem Zielpunkt
kommen lassen, dass er sozusagen eine gerade Linie hinter sich her zieht.
Das kann jedes Malprogramm was ich hier verlange.
Mein Problem ist dass ich die Verteilung der Wege in x und y - Richtung nicht
verhältnismässig hin bekomme. Naja ich hier ist mein code.
Der Punkt legt immer 45 Grad bis er auf waagerechter bzw. senkrechter Bahn zum
Zielpunkt steht.

Das ist der komplette code aber eigentlich interessiert nur die Procedure p_xmove


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:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
program gravity_particle;
uses crt,dos,graph;

const   x_max = 639;
        y_max = 479;

var
  grafiktreiber, grafikmode : Integer;
  Color          : Byte;
  m, n, x_pos, y_pos        : integer;
  x1,x2,xred,xmove          : 0..639;
  y1,y2,yred,ymove          : 0..479;
  zahl,hilf,radius          : word;
  vector,xv,yv              : real;
  zw_sum                    : real;
  schalter                  : boolean;

procedure p_xmove;
     begin
          xv:=xred-xmove;
          yv:=yred-ymove;
          if yv=0 then yv:=1;
          if xv=0 then xv:=1;

          if yv>xv then vector:=xv/yv
                   else vector:=yv/xv;

          if zw_sum>1 then schalter:=true;
          if zw_sum<1 then schalter:=false;
          if zw_sum=1 then schalter:=true;

          case schalter of
               true : begin
                           if xmove>xred then xmove:=xmove-1
                              else xmove:=xmove+1;
                           zw_sum:=zw_sum-abs(vector);
                      end;
               false: begin
                           if ymove>yred then ymove:=ymove-1
                              else ymove:=ymove+1;
                           zw_sum:=zw_sum+abs(vector);
                      end;
          end;
     end;

begin
   { clrscr;
    gotoxy(30,2);writeln('G R A P H');writeln('');
    m:=0; n:=0; x_pos:=0; y_pos:=0;
    write('> Anstieg(m)= '); readln(m);
    write('> y-ordinate= '); readln(n);
    readln;}


                grafiktreiber := detect;
                InitGraph(grafiktreiber, grafikmode, 'e:\turbo7.0\BP\BGI');
                if GraphResult <> grOk then Halt(1);
    x1:=0;
    x2:=0;
    xred:=400;
    yred:=200;
    y1:=0;
    y2:=0;
    color:=0;
    zahl:=0;
    hilf:=5;
    radius:=300;
    setbkcolor(4);

    zw_sum:=1.5;

    for hilf:=0 to 1 do {der rote Punkt}
       begin
            putpixel(xred,yred,4);
            putpixel(xred+hilf,yred+hilf,4);
            putpixel(xred,yred+hilf,4);
            putpixel(xred+hilf,yred,4);
       end;
   xmove:=50;ymove:=400;

   repeat
         //xmove:=xmove+1;
         p_xmove;
         putpixel(xmove,ymove,14);
         delay(10);
         //putpixel(xmove,ymove,0);
   until (keypressed);
  readln;
  CloseGraph;
end.


Wäre sehr froh über brauchbare tips.
Mir fehlt da irgendwie ein mathematisches Konzept.

Moderiert von user profile iconAXMD: Code- durch Delphi-Tags ersetzt.


Jonas1405 - Di 13.09.05 21:24

Hey ho!!!
Vielleicht ein Lösungsansatz: In den grafikprogrammen sind die schrägen Linien ja auch nie direkt sondern oft (spätestens wenn man nah ranzoomt) ziemlich kantig- deshalb wäre ein Lösungsansatz, dass du mit dem verhältniss rumspielst auf wie viele horizontale Pixel wieviele vertikale Pixel kommen- wenn dein zu erreichender Punktunter 45° "entfernt" ist dann musst du die Zahl auf wie viele horizintale Pixel ein vertikaler Pixel kommt verkleinern und irgendwann dürfte deine Strecke deinen zweiten Punkt treffen(über 45° ist es dann halt anders rum)

Ich hoffe das war verständlich-wenn nicht schreib nochmal- notfalls schicke ich dir eine Skizze von meiner Idee samt auführlichem Text per E-mail!!

Gruß Jonas :wink:


alzaimar - Di 13.09.05 21:27

Der Breshenham-Algorithmus ist dein Freund. Er zeichnet eine pixelgenaue Linie zwischen zwei Punkten....


dr. rom4o - Di 13.09.05 22:26
Titel: hey leute ICH DANKE EUCH
Danke für eure Ratschläge, ich glaube ich werde mit euren infos weiter kommen.
Ich melde mich dann noch mal.

thx

dr. rom4o


delfiphan - Di 13.09.05 22:58

Äquivalent* zum Bresenham Algorithmus kannst du auch mit Gleitkommazahlen rechnen und die jeweils runden. Musst einfach eine Fallunterscheidung machen:

Pseudocodemässig:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
x1,y1 = Startpunkt; x2,y2 = Endpunkt

w := x2-x1;
h := y2-y1;
x := x1;
y := y1;
falls w und h positiv:
 falls w>h
  wiederhole w mal:
   x := x + 1;
   y := y + h/w;
   PutPixel(round(x),round(y));  

 falls h>w:
  wiederhole h mal
   x := x + w/h;
   y := y + 1;
  PutPixel(round(x),round(y));

 etc.


* bis zur Maschinengenauigkeit