Einzelnen Beitrag anzeigen

mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#1

zentralperspektive(Fluchtpunkt) auf einen Canvas Anwenden ?

  Alt 11. Mai 2010, 19:42
Bei meinen Nachforschungen(Google, IRC-Chanels) habe ich folgende Informationen bekommen:
01) Es wird eine zentralperspektive verwenden.
02) Zu Umsetzung, brauche ich ein "Fluchtpunkt" der auf einen Horizont liegt.
03) Alle Objekte(Die in einer TObjectList drin sind) sollen sich an drei Regeln halten:
A) Je dichter das Objekt am Fluchtpunkt ist, desto kleiner soll es gezeichnet werden
B) Je dichter das Object am Fluchtpunkt ist, desto mehr soll die Position zum Fluchtpunkt ausgerichtet sein.

Leider sind meine Mathematischen Kenntnisse sehr begrenzt. Aus meinen Versuchen ist jedoch folgender Code entstanden:

Delphi-Quellcode:
procedure TMySkyroads.Paint;
var
  i,px,py,pw,ph, dy,my,tx,ty,tw,th,dw,dh,cx,cy:integer;
  fy:Integer;
begin
  Canvas.Brush.Color:=clBlack;
  Canvas.FillRect(0,0,Width, Height);
  px:=0; py:=0; fy:=0;
  if ScrollY = -1 then ScrollY:=Height-100;
  // Ein Roter Horizont(Rot)
  Canvas.Pen.Color:=clRed;
  cx:=(Width div 2)-1; cy:=150;
  Canvas.MoveTo(0,cy-1);
  Canvas.LineTo(Width,cy-1);
  // Der Zentrierte Fluchtpunkt(Gelb)
  Canvas.Pen.Color:=clYellow;
  Canvas.MoveTo(cx,cy);
  Canvas.LineTo(cx+1,cy);
  Canvas.Pen.Color:=clLime;

  Canvas.MoveTo(cx,cy);
  Canvas.LineTo(0,cy+(Height div 2));

  Canvas.MoveTo(cx,cy);
  Canvas.LineTo(Width,cy+(Height div 2));

{  Canvas.Pen.Color:=clRed;
  Canvas.MoveTo(cx,cy);
  Canvas.LineTo(cx,cy+Height);}

// Das Gitter Zeichnen
// Einige Horizontale Linen(Blau)
{  Canvas.Pen.Color:=clGray;
  py:=cy;
  for i:=0 to 30 do begin
    Canvas.MoveTo(px,py);
    Canvas.LineTo(px+Width,py);
    inc(py,10);
  end; // for
  Canvas.Pen.Color:=clBlue;
  px:=-600;
  for i:=0 to 30 do begin
    Canvas.MoveTo(cx,cy);
    Canvas.LineTo(cx+px,cy+Height);
    inc(px,40);
  end; // for}


// exit;
  canvas.Font.Color:=clRed;
  canvas.Font.Size:=16;
  for i:=0 to Count-1 do begin
    canvas.Brush.Color:=MyRect[i].BackgrundColor;
    canvas.Pen.Color:=MyRect[i].BorderColor;
    px:=MyRect[i].Left;
    // Aktuelle Zeichen Position
    py:=ScrollY-MyRect[i].Top;
    if py-MyRect[i].Height >=cy then begin
      my:=abs(py);
     { if (my >=0) and (my <=50) then fy:=100;
      if (my >=50) and (my <=100) then fy:=70;
      if (my >=150) and (my <=200) then fy:=40;
      if (my >=250) and (my <=300) then fy:=30;
      if (my >=300) and (my <=400) then fy:=20;
      if (my >=400) and (my <=480) then fy:=10;}


// if (my >=0) and (my <=50) then fy:=6;
// if (my >=50) and (my <=100) then fy:=5;
// if (my >=150) and (my <=200) then fy:=4;
      if (my >=250) and (my <=260) then fy:=15; // 1
      if (my >=260) and (my <=270) then fy:=20; // 2
      if (my >=280) and (my <=290) then fy:=25; // 3

      if (my >=300) and (my <=310) then fy:=30; // 4
      if (my >=310) and (my <=320) then fy:=35; // 5
      if (my >=330) and (my <=340) then fy:=40; // 6

      if (my >=340) and (my <=350) then fy:=45; // 7
      if (my >=350) and (my <=360) then fy:=50; // 8
      if (my >=360) and (my <=370) then fy:=55; // 9

      if (my >=370) and (my <=380) then fy:=60; // 10
      if (my >=390) and (my <=400) then fy:=65; // 11
      if (my >=400) and (my <=410) then fy:=70; // 12

      if (my >=410) and (my <=420) then fy:=75; // 13
      if (my >=420) and (my <=430) then fy:=80; // 14
      if (my >=430) and (my <=440) then fy:=85; // 15

      if (my >=450) and (my <=460) then fy:=90; // 16
      if (my >=460) and (my <=470) then fy:=95; // 17
      if (my >=480) and (my <=490) then fy:=100; // 18
      pw:=((MyRect[i].Width*fy) div 100);
      ph:=((MyRect[i].Height*fy) div 100);
      tx:=Abs(cx - px);

     //(Round((Width-pw) / 2));
     px:=MyRect[i].Left;
     //Round(py*ScrollY / cy);
     py:=py;
      PaintObj1(Rect(px,py,pw,ph),Canvas);
    end;
// PaintObj1(Rect(px+8,py-6,pw+4,ph-6),Canvas);
// canvas.Rectangle(px,py,px+pw,py+ph);

  // canvas.Rectangle(px+8,py-6,px+4+pw,py+ph-6);

{    canvas.TextStyle.Alignment:=taCenter;
    canvas.TextStyle.Layout:=tlCenter;
    canvas.TextRect(Rect(px,py,px+pw, py+ph),px,py,IntTostr(i));}

  end; // for i
end; // TMySkyroads.Paint
Sorry, für die Unordnung. Es ist ein Test Code und noch nicht ausgereift. Der Code für "PaintObj1" sieht so aus:

Mit den Vielen IF Anweisungen, versuche ich einen Wert Bereich zu bestimmen. Ich verwende hier Prozent Angaben(Das hoffe ich jedenfalls). Das kann man hier ganz gut sehen:
Delphi-Quellcode:
pw:=((MyRect[i].Width*fy) div 100);
ph:=((MyRect[i].Height*fy) div 100);
Ich denke, das Hauptproblem dürfte daran liegen, dass ich nicht weiß wie ich X und Y anpassen muss bzw. wie der Notwendige Code dafür aussieht.

Delphi-Quellcode:
procedure PaintObj1(const aRect:TRect; canvas:TCanvas);
var
  d:Integer;
begin
  d:=Round( aRect.Right div 2) div 2; // Die Hälfte von der Hälfte ausrechnen.

  canvas.MoveTo(aRect.Left+d,aRect.Top+1);
  canvas.LineTo(aRect.Left+(aRect.Right-d),aRect.Top+1);

  canvas.MoveTo(aRect.Left,aRect.Top+aRect.Bottom);
  canvas.LineTo(aRect.Left+aRect.Right,aRect.Top+aRect.Bottom);

  canvas.MoveTo(aRect.Left+(d),aRect.Top+1);
  canvas.LineTo(aRect.Left,aRect.Top+aRect.Bottom+1);

  canvas.MoveTo(aRect.Left+(aRect.Right-d),aRect.Top+1);
  canvas.LineTo(aRect.Left+aRect.Right,aRect.Top+aRect.Bottom+1);
end; // PaintObj1
Ich habe eine Bitte: Bitte Bombardiert mich NICHT mit Mathematischen ausrücken oder Fachbegriffe. Wenn Möglich. Ich habe schon selbst gesucht mit Goole und FireBall und auch in Verschiedenen Foren. Jedoch habe ich nichts gefunden, was mir weiter geholfen hätte. Eine Seite möchte ich noch angeben:
http://www.gorenfeld.net/lou/pseudo/#basics
Die wurde mir im DelphiGL Chanel genannt. Jedoch auf Englisch. Aber vielleicht hilft es es euch weiter....

Ich würde gerne das Prinzip verstehen, was dahinter steckt. Sonst könnte ich auch einfach GLSCene oder Direkt OpenGL verwenden. Das wäre jedoch Langweilig. Gut, wenn ich direkt mit OpenGL arbeiten würde, würde es wieder Sinn machen. Aber ich möchte es gerne erst mal so versuchen.

Die Objekte sollen unterschiedlich groß sein. ich verwende hier noch Begriffe aus der 2D Welt:
X und Y sowie die Breite und Höhe. ScrollX wird von KeyDown entsprechend Verändert(Mit den Pfeiltasten hoch und Runter).
Wenn ich es richtig verstanden habe, kann ScrollX auch als Kamera bzw als Z Variable bezeichnet werden.
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat