Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi In Koordinatensystem auf Punkt "zuzoomen" (https://www.delphipraxis.net/155294-koordinatensystem-auf-punkt-zuzoomen.html)

Fussball-Robby 16. Okt 2010 22:37

In Koordinatensystem auf Punkt "zuzoomen"
 
Hey,
ich programmiere gerade ein dynamisches Koordinatensystem zur Darstellung von Funktionsgraphen. Man soll auch zoomen können. Das Fenster ist begrenzt durch einen Start-/Endwert von X bzw. Y (sprich: X-Werte gehen von StartX bis EndX, y-Werte von StartY bis EndY).
Das Zoomen ohne Verschieben des Koordinatenursprungs ist kein Problem, dazu versehe ich einfach alle 4 Grenzwerte mit einem Faktor, beispielsweise 1,1.

Nun will ich aber auf einen Punkt "zuzoomen". Wenn man also die Maus auf eine bestimmte Stelle des Graphen hält und hochscrollt, soll das Fenster sich nach und auf diesen Punkt zentrieren. Die 4 Grenzwerte StartX, EndX, StartY und EndY müssen also verschieden verändert werden. Aber wie? Koordinaten des Cursors sind natürlich bekannt. Hat jemand Ideen?

[Edit]Habs selbst gelöst. Musste für den x-Zoom beispielsweise die relative x-Position (also in Prozent) ausrechnen. Die linke Grenze wird dann um diese "X" Prozent größer, die rechte Grenze um (1-X) Prozent kleiner. Grüße

[Edit2] Igrendwie will das doch noch nicht so recht.. Denn wenn eine Grenze bei 0 ist, bringt eine prozentuale Veränderung nichts mehr.. Ich probiere gerade eigentlich nur rum. Ideen sind immer noch willkommen!

Sir Rufo 16. Okt 2010 23:29

AW: In Koordinatensystem auf Punkt "zuzoomen"
 
Du musst zunächst die Cursor-Position auf deine Koordinatenposition (x,y) umrechnen.
Dann kannst du die neuen min,max Werte wie folgt berechnen
Code:
Ymaxneu = (Ymax + y) / Zoom
Yminneu = (Ymin + y) / Zoom
Xmaxneu = (Xmax + x) / Zoom
Xminneu = (Xmin + x) / Zoom

Bummi 17. Okt 2010 09:10

AW: In Koordinatensystem auf Punkt "zuzoomen"
 
und wenn Du die Zeichenroutinen/Berechnungen unangetastet lässt und nur das Rendering anpasst?
Delphi-Quellcode:
unit ExCanvasTools;
// 20100915 by Thomas Wassermann
interface
uses
  Windows, SysUtils, Classes, Graphics;

  Function Grad2Rad(w:Double):Double;
  Procedure PaintGraphic(ACanvas:TCanvas;x,y:Integer;AGraphic:TGraphic;Faktor,Winkel:Double;PosIsCenter:Boolean=false);
  Procedure PaintText(ACanvas:TCanvas;Const s:String;x,y:Integer;Faktor,Winkel:Double;PosIsCenter:Boolean=false);
  Procedure ResetCanvas(ACanvas:TCanvas);
  procedure SetCanvasZoomAndRotation(ACanvas: TCanvas;Zoom:Double;Angle:Double;CenterpointX,CenterpointY:Double);

implementation

Function Grad2Rad(w:Double):Double;
  begin
     Result := w / 360 * PI *2;
  end;

Procedure PaintText(ACanvas:TCanvas;Const s:String;x,y:Integer;Faktor,Winkel:Double;PosIsCenter:Boolean=false);
var
  px,py:Integer;
begin
     SetCanvasZoomAndRotation(ACanvas , Faktor, Winkel, x,y);
     if PosIsCenter then
        begin
          px := Round( ACanvas.TextWidth(s) / 2 );
          py := Round( ACanvas.TextHeight(s) / 2 );
        end
     else
        begin
          px := 0;
          py := 0;
        end;

     ACanvas.TextOut(-px ,-py ,s);
     ResetCanvas(ACanvas);
end;




Procedure PaintGraphic(ACanvas:TCanvas;x,y:Integer;AGraphic:TGraphic;Faktor,Winkel:Double;PosIsCenter:Boolean=false);
var
  px,py:Integer;
begin
     if PosIsCenter then
        begin
          px := Round( AGraphic.Width / 2 );
          py := Round( AGraphic.Height / 2 );
        end
     else
        begin
          px := 0;
          py := 0;
        end;
     SetCanvasZoomAndRotation(ACanvas , Faktor, Winkel, x , y );
     ACanvas.Draw(-px ,-py ,AGraphic);
     ResetCanvas(ACanvas);
end;





Procedure ResetCanvas(ACanvas:TCanvas);
begin
   SetCanvasZoomAndRotation(ACanvas , 1, 0, 0,0);
end;

Procedure SetCanvasZoomAndRotation(ACanvas:TCanvas;Zoom:Double;Angle:Double;CenterpointX,CenterpointY:Double);
var
    form : tagXFORM;
    Winkel:Double;

begin
      Winkel := Grad2Rad(Angle);
      SetGraphicsMode(ACanvas.Handle, GM_ADVANCED);
      SetMapMode(ACanvas.Handle,MM_ANISOTROPIC);
      form.eM11 := Zoom * cos( Winkel);
      form.eM12 := Zoom *Sin( Winkel) ;
      form.eM21 := Zoom * (-sin( Winkel));
      form.eM22 := Zoom * cos( Winkel) ;
      form.eDx := CenterpointX;
      form.eDy := CenterpointY;
      SetWorldTransform(ACanvas.Handle,form);
end;

end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz