Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Mathematisches problem: Achsenkreuz (https://www.delphipraxis.net/26375-mathematisches-problem-achsenkreuz.html)

theomega 22. Jul 2004 21:39


Mathematisches problem: Achsenkreuz
 
Hallo leute,
habe da ein kleines problem, aber ich steh total auf dem Schlauch ich bekomms nicht raus, wie ich das richtig berechne.

Ich will Punkte in ein Achsenkreuz einzeichnen. Das problem ist, das:
1. Das Achsenkreuz erst mal unbekannt ist, also nur durch variablen festgelegt (siehe unten)
2. Der Masstab variabel ist (auch nicht festgelegt)

Also, was ich über das Achsenkreuz weiß (weil es der User einstellen kann) ist:
- fromx (start des Achsenkreuzes auf der X-Achse)
- tox (ende es Achsenkreuzes auf der X-Achese)
- fromy
- toy (sollte logisch sein, das gleiche auf der y achse)

außerdem weiß ich die größe meines Zeichenbereiches (paintbox1.width, height) nenen wir das mal cwidth und cheight.

Jetzt hätte ich gerne eine Funktion gehabt, die mir, wenn ich als koordinate sagen wir mal (1/1) angebe, den Punkt richtig ins Koordinaten System einzeichnet.
Ich sitze an dieser Funktion schon den ganzen Abend und komm nicht drauf wie ich das allgemein berechnen kann.
Wer kann mir helfen?

Danke
TO

fkerber 22. Jul 2004 21:41

Re: Mathematisches problem: Achsenkreuz
 
Hi!

Könntest du evtl. ne Zeichnung zur Verdeutliochung machen?
Sollten fromx und fromy nicht eigentlich 0 sein?
Oder verstehe ich da was falsch?

Ciao fkerber

theomega 22. Jul 2004 21:50

Re: Mathematisches problem: Achsenkreuz
 
Liste der Anhänge anzeigen (Anzahl: 1)
siehe bild im anhang. In dem Fall wäre

fromx:-5
tox:1
fromy:-5
toy:1

ich will jetzt
1. Diese Achsenkreuz auf eine paintbox zeichnen (bekomm ich evtl noch bin
2. In dieses Achsenkreuz was eintragen (z.b. den Punkt -3|0.5)

es geht hier um die Brechnung nicht um die Delphi-Befehle (die kenne ich natürlich)

fkerber 22. Jul 2004 22:25

Re: Mathematisches problem: Achsenkreuz
 
Hi!

Ich habe hier mal einen Ansatz, er ist sehr Quick'n'Dirty und zeichnet bisher auch nur das Achsenkreuz, aber vielleiht hilft er dir etwas.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var lx, ly, fromy, toy,fromx,tox, einheity, einheitx: integer;
begin
fromy:=strtoint(edit3.Text);
fromx:=strtoint(edit1.Text);
tox:=strtoint(edit2.text);
toy:=strtoint(edit4.text);
lx:=strtoint(edit2.text)-strtoint(edit1.text);
ly:=strtoint(edit4.text)-fromy;
einheity:=paintbox1.Height div ly;
einheitx:=paintbox1.width div lx;

Paintbox1.Canvas.MoveTo(0,(abs(toy)*einheity));
Paintbox1.Canvas.LineTo(PaintBox1.Width,(abs(toy)*einheity));
Paintbox1.Canvas.MoveTo(paintbox1.Width-(einheitx*(abs(tox))),0);
Paintbox1.Canvas.LineTo(paintbox1.Width-(einheitx*(abs(tox))),Paintbox1.Height);



end;
Er passt auf dein Beispiel, ist aber wohl nicht (!) allgemeingültig ...


Ciao fkerber

theomega 22. Jul 2004 22:29

Re: Mathematisches problem: Achsenkreuz
 
wie gesagt, der zweite teil mit dem einzeichen der punkte ist mir wichtiger! Aber danke schonmal!

fkerber 22. Jul 2004 22:34

Re: Mathematisches problem: Achsenkreuz
 
HI!

Naja, mal einen theoretischen Ansatz:
Du suchst dir raus, wo der Punkt (0|0) ist und seine "echten" Koordinaten.
Dann gehst du von dort deine gewünschte X-Koordinate*Einheitx und das selbe nach y und dann hast du doch deinen Punkt, oder?

Ciao fkerber

fkerber 22. Jul 2004 22:42

Re: Mathematisches problem: Achsenkreuz
 
Hi!

Und nochmal als Code:

Delphi-Quellcode:
punkt0x:=abs(fromx*einheitx);
punkt0y:=abs(toy*einheity);

Paintbox1.Canvas.Moveto(punkt0x+(-3*einheitx),punkt0y+abs((-2*einheity)));
Paintbox1.Canvas.Lineto(10+punkt0x+(-3*einheitx),10+punkt0y+abs((-2*einheity)));
Bei allen Codes gilt, du musst immer auf die Vorzeichen achten, um es allgemeingültig zu halten.

Ciao fkerber

theomega 22. Jul 2004 22:50

Re: Mathematisches problem: Achsenkreuz
 
hey, danke, werde ich morgen sofort mal ausprobieren!

Luckie 22. Jul 2004 23:20

Re: Mathematisches problem: Achsenkreuz
 
Liste der Anhänge anzeigen (Anzahl: 1)
So habe dir mal eben was schnell gemacht. Sollte so ziemlich von allen unabhängig sein.

Der Knackpunkt ist der, dass du deine logischen Koordinaten des Koordinatenkreuzes in "physische" Pixel zum Eintragen umrechnen musst. Und das macht diese Funktion:
Delphi-Quellcode:
function Coordinates2Pixel(Origin, cords: TPoint; Interval: Integer): TPoint;
begin
  result.X := Origin.X + (cords.X * Interval);
  result.Y := Origin.Y - (cords.Y * Interval);
end;
Ich habe es so programmiert, dass du den Maßstab (SCALE) beliebig verändern kannst, ohne sonst irgend etwas am Code ändern zu müssen.

Das ganze Projekt im Anhang.

Nachtrag: Ich habe das ganze erstmal auf ganzzahlige Einträge beschränkt.

fkerber 22. Jul 2004 23:37

Re: Mathematisches problem: Achsenkreuz
 
Hi!

Fehlt da nicht an sich ein Teil seiner Aufgabenstellung?
Das fromx, tox und demenstprechend für y?

Ciao fkerber

Luckie 22. Jul 2004 23:39

Re: Mathematisches problem: Achsenkreuz
 
Nö. ORG_X, ORG_Y und LEN_X, LEN_Y kann er ja beliebig wählen. Ich habe es nur eben der übersichtlichkeithalber als Konstanten deklariert.

fkerber 22. Jul 2004 23:48

Re: Mathematisches problem: Achsenkreuz
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi!

Wenn ich Orgx und Orgy auf beidemale 100 setze, kommt da was komisches raus.
Und der Punkt ließ sich auch nicht mehr einzeichnen.

Ciao fkerber

Luckie 22. Jul 2004 23:57

Re: Mathematisches problem: Achsenkreuz
 
Liste der Anhänge anzeigen (Anzahl: 2)
Moment habe es gleiche, da habe ich irgendwo vergessen mit den Konstanten zu arbeiten.
Delphi-Quellcode:
DrawHorzMarker(Bmp.Canvas, pt, Origin.X+10); // so stimmt es
Und:
Delphi-Quellcode:
cntVerMarkers := (LEN_X - ORG_X) div SCALE;
Es lag also nicht an den Prozeduren, sondern wie ich sie benutzt habe, ich habe ihnen falsche Werte übergeben.

Und das mit dem Punkt ist logisch. Du musst ja auch den Punkt in den Einheiten des Koordinatenkreuzes angeben. Und deins geht eben nicht bis 250 und 250, sondern nur bis beides male 18 oder so - habe die Striche jetzt nicht gezählt.


Im Anhang die korrigierte Version.

Nachtrag 1: Ich habe die Achsen jetzt noch beschriftet, siehe Screenshot.
Nachtrag 2: Jetzt haben die Achsen noch Pfeile und man kann Achsen- , Pfeil-, Hintergrund-, Schrift- und Punktfarbe definieren.

Luckie 23. Jul 2004 16:59

Re: Mathematisches problem: Achsenkreuz
 
Falls es der Threadersteller übersehen hat, will ich es noch mal nach oben holen. ;)

theomega 23. Jul 2004 17:05

Re: Mathematisches problem: Achsenkreuz
 
nicht dass ich es übersehen hätte. habe es jetzt alles zusammen in eine Klasse gepackt (TAchsenKreuz abgeleitet von Paintbox), aber es gehen manche sache einfach immer noch nicht!

Luckie 23. Jul 2004 17:06

Re: Mathematisches problem: Achsenkreuz
 
Was geht nicht? Also mein Code erfüllt alle deine Wünsche, so wie ich sie verstanden habe.

theomega 23. Jul 2004 17:14

Re: Mathematisches problem: Achsenkreuz
 
wenn ich das wüsste, was nicht geht, der code spinnt manchmal einfach rum!
aber ich poste ihn hier mal:
Delphi-Quellcode:
unit AchsenKreuz;

interface

uses
  SysUtils, Classes, Controls, ExtCtrls,Dialogs,Graphics;


type TEPoint=record
  x,y:extended;
end;

type TEPixel=record
  x,y:integer;
  col:TColor;
end;

type
  TAchsenKreuz = class(TPaintBox)
  private
    { Private-Deklarationen }

    Ffrom_x: extended;
    Fto_y: extended;
    Fto_x: extended;
    Ffrom_y: extended;

    t_width,t_height:extended;


    Fdraw_axes: boolean;

    td_pixels:array of TEPixel;
    Faxes_color: TColor;

    procedure Setfrom_x(const Value: extended);
    procedure Setfrom_y(const Value: extended);
    procedure Setto_x(const Value: extended);
    procedure Setto_y(const Value: extended);

    procedure init_values();
    procedure Setdraw_axes(const Value: boolean);
    procedure Setaxes_color(const Value: TColor);
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    //Public zu Debug-Zwecken
    x_scale,y_scale:extended;
    org:TEPoint;

    constructor Create(AOwner: TComponent); override;
    procedure Paint; override;
    procedure draw_point(x,y:extended;col:TColor);
    function pix2point(px,py:integer):TEPoint;
    procedure loschen;
  published
    { Published-Deklarationen }
    property from_x:extended read Ffrom_x write Setfrom_x;
    property to_x:extended read Fto_x write Setto_x;
    property from_y:extended read Ffrom_y write Setfrom_y;
    property to_y:extended read Fto_y write Setto_y;
    property draw_axes:boolean read Fdraw_axes write Setdraw_axes;
    property axes_color:TColor read Faxes_color write Setaxes_color;

  end;

procedure Register;

implementation


constructor TAchsenKreuz.Create(AOwner: TComponent);
begin;
//Bis jetzt noch unütz
setlength(td_pixels,0);
inherited Create(AOwner);
end;


procedure TAchsenKreuz.Paint;
var i:integer;
begin;
init_values;

//Bis jetz noch unütz
for i:= low(td_pixels) to high(td_pixels) do begin;
  canvas.Pixels[td_pixels[i].x,td_pixels[i].y] := td_pixels[i].col;
end;

if (Fdraw_axes) then begin;
  Canvas.Pen.Color := Faxes_color;
  canvas.Pen.Style := psSolid;
  Canvas.MoveTo(round(org.X),0);
  Canvas.LineTo(round(org.X),height);

  Canvas.MoveTo(0,round(org.y));
  Canvas.LineTo(width,round(org.y));
end;


end;

procedure TAchsenKreuz.draw_point(x,y:extended;col:TColor);
begin;
//Bis jetzt noch unütz
{setlength(td_pixels,length(td_pixels)+1);
td_pixels[high(td_pixels)].x := round(org.x + x*x_scale);
td_pixels[high(td_pixels)].y := round(org.y - y*y_scale);
td_pixels[high(td_pixels)].col := col;
}
canvas.Pixels[round(org.x + x*x_scale),round(org.y - y*y_scale)] := col;
paint;
end;

//Wandelt Delphi Pixel in Achsenkreu Koordinaten um
function TAchsenKreuz.pix2point(px,py:integer):TEPoint;
begin;
if ((x_scale>0) AND (y_scale>0)) then begin;
result.x := (px-org.x)/x_scale;
result.y := (-py+org.y)/y_scale;
end
else begin;
  result.x := 99999;
  result.y := 99999;
end
end;

//löscht die paintbox
procedure TAchsenKreuz.loschen;
begin;
canvas.Brush.Color := color;
canvas.Pen.Style := psClear;
canvas.Rectangle(0,0,width,height);
end;

procedure Register;
begin
  RegisterComponents('Beispiele', [TAchsenKreuz]);
end;

//Berechnungen
procedure TAchsenKreuz.init_values;
begin
  t_width := abs(ffrom_x)+abs(fto_x);
  t_height:= abs(ffrom_y)+abs(fto_y);

  if ((t_width>0) AND (t_height>0)) then begin;
    try
      x_scale:=Width / t_width;
    except
      on E: Exception do
        messagedlg('XScale '+floattostr(x_scale)+'/'+floattostr(t_width)+' '+ E.Message,mterror,[mbok],0);
    end;

    try
      y_scale:=self.Height / t_height;
    except
      on E: Exception do
        messagedlg('YScale '+floattostr(Y_scale)+'/'+floattostr(t_height)+' '+ E.Message,mterror,[mbok],0);
    end;
    org.X := ffrom_x*(-1)*x_scale;
    org.y := fto_y*y_scale;
  end;

end;

procedure TAchsenKreuz.Setdraw_axes(const Value: boolean);
begin
  Fdraw_axes := Value;
  init_values;
end;

procedure TAchsenKreuz.Setfrom_x(const Value: extended);
begin
  Ffrom_x := Value;
  init_values;
end;

procedure TAchsenKreuz.Setfrom_y(const Value: extended);
begin
  Ffrom_y := Value;
  init_values;
end;

procedure TAchsenKreuz.Setto_x(const Value: extended);
begin
  Fto_x := Value;
  init_values;
end;

procedure TAchsenKreuz.Setto_y(const Value: extended);
begin
  Fto_y := Value;
  init_values;
end;

procedure TAchsenKreuz.Setaxes_color(const Value: TColor);
begin
  Faxes_color := Value;
end;

end.
irgendwie scheinen manche ausschnitte probleme zu bereiten, ich kann aber das nicht näher bestimmen welche!
Ich bezweifle auch, dass jemand meinen (sicher schlecht geschriebenen) code versteht!

Grüße und Danke
TO


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:42 Uhr.

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