Delphi-PRAXiS
Seite 2 von 8     12 34     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Probleme mit Sinus Darstellung (https://www.delphipraxis.net/184076-probleme-mit-sinus-darstellung.html)

Bjoerk 25. Feb 2015 10:34

AW: Probleme mit Sinus Darstellung
 
Möchtest du eine stehende Welle zeichnen oder eine simple Sinuskurve? Vom Graph her sieht die Kurve am besten aus wenn man je Pixel X einen Y-Wert berechnet und zeichnet (for I := 0 to Width -1 do). Man braucht Skalierungsfunctions die Pixel in Funktionswerte umrechnen und umgekehrt. Üblicherweise gibt man bei einem Mouse Move über die Grafik die entsprechenden Werte in z.B. einer Statusbar numerisch aus (X = .. / Y = ..).

Chris211183 26. Feb 2015 09:30

AW: Probleme mit Sinus Darstellung
 
Hi, ich möchte eine stehende Welle zeichnen !

Dein Vorschlag klingt sehr gut, jedoch übersteigt das meine Programmierkenntnisse bei weitem.

Chris211183 26. Feb 2015 11:05

AW: Probleme mit Sinus Darstellung
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier mal mein Code, im Anhang ein Screenshot:

Prinzipiell das, was es machen soll, sieht bloß ekelig aus :duck:

Delphi-Quellcode:
FPoints                  : Array[0..144] of TPoint;
.
.
.
procedure THixHistoGraph.DrawGridScale;

var
XRangePixels, YRangePixels: Double;
Start: TPoint;
Radian, Interval: Double;
i : Integer;

begin
   XRangePixels := (Width - GapLeft- GapRight) / (FXScale.ValGap);
   YRangePixels := (Height - GapTop - GapBottom) / (FYScale.ValGap);
   Start := Point(GapLeft, Height - GapBottom);
   Radian :=  (FXScale.ValMin) * PI;
   Interval := (FXScale.ValMax + FXScale.ValMin) * PI / 144;

   for i:= 0 to High(FPoints) do
   begin
     FPoints[i].X := Start.X + round(Radian * xRangePixels / Pi);
     FPoints[i].Y := Start.Y - round(sin(Radian) * yRangePixels);
     Radian := Radian + Interval;
   end;
   Canvas.Pen.Color := cllime;
   Canvas.Polyline(FPoints);
end;

Caps 26. Feb 2015 11:40

AW: Probleme mit Sinus Darstellung
 
Hi,

ich glaube es wäre sinnvoll, die Mathematik von der Darstellung zu trennen.

In den Zeilen
Code:
FPoints[i].X := Start.X + round(Radian * xRangePixels / Pi);
FPoints[i].Y := Start.Y - round(sin(Radian) * yRangePixels);
verwendest Du Darstellungskoordinaten (xRangePixels, yRangePixels) und "mathematische" Koordinaten (Radian, FPoints[i].X, FPoints[i].Y).
Meiner Ansicht nach wäre es besser, zuerst die 144 Samples der Funktion zu berechnen. D.h. "mathematisches" Argument wird auf "mathematischen" Funktionswert abgebildet. Du hättest dann ein Array of Float o.ä.
Danach nimmst Du dieses Array von Float-Werten, skalierst die Werte, bis sie groß genug sind, um in Pixeln sinnvoll dargestellt zu werden und rundest sie, so dass Integers rauskommen.
Im dritten Schritt transformierst Du diese Werte in das Koordinatensystem Deiner Darstellungskomponente.
Dann kannst Du Polyline drauf loslassen.

lg Caps

Chris211183 26. Feb 2015 11:54

AW: Probleme mit Sinus Darstellung
 
oha :pale:

das alles zu berechnen ist ja nicht das schwierigste, aber wie zur Hölle programmiert man sowas...

In solchen Sachen bin ich noch Jungfrau...

Caps 26. Feb 2015 12:26

AW: Probleme mit Sinus Darstellung
 
Aber nicht doch ;-).

Du hast doch alles schon gemacht. Ein bisschen Addieren, Multiplizieren, mehr ist es doch nicht.
Und die Darstellung machst Du doch auch schon.
Was ist jetzt noch das schwere?

lg Caps

Chris211183 26. Feb 2015 12:56

AW: Probleme mit Sinus Darstellung
 
:glaskugel: ich habe mein Source jetzt bestimmt schon 4 mal geändert und es wird immer übler in der Darstellung :roteyes:

ich check grad garnüscht mehr...

Zeichnet über die Ränder find die sch... Fehler aber nicht.

Der Soll einfach ne stehende Welle von X-Achse-Anfang bis X-Achse Ende machen über die Höhe Y, das ist doch nicht so schwer..., ich bekomm das einfach nicht gebacken...

Caps 26. Feb 2015 14:30

AW: Probleme mit Sinus Darstellung
 
Hast Du's denn probiert wie ich schrieb, Mathematik und Darstellung zu trennen?
Wenn Du die Samples von der Sinusfunktion berechnet hast, ist die halbe Miete drin.
Dann brauchst Du die Werte nur noch mit einer großen Zahl multiplizieren (z.B. 100), runden (mit round()) und fertig sind Pixelwerte. Dat is doch nu nix schlimmes mehr :-D.

Blup 26. Feb 2015 16:09

AW: Probleme mit Sinus Darstellung
 
An der Sinusfunktion is ja erst mal nichts besonderes:

y := f(x)

Dann haben wir ein Rechteck als Zeichenfläche:

R: TRect

Den Wert von X für die erste linke Pixelspalte und Y für die oberste Pixelzeile auf der Zeichenfläche:

x0: Double
y0: Double

Die Breite und Höhe eines Pixels in unserem skalliertem Koordinatensystem:

dx: Double
dy: Double

Die verallgemeinerte Aufgabe ist die Berechnung der Punkte für die Darstellung einer beliebigen f(x)-Funktion:
Delphi-Quellcode:
type
  TFxFuntion = function(const x: Extended): Extended;
  TPointDynArray = array of TPoint;

function BerechnePunkteDarstellung(AFunc: TFxFuntion; const ARect: TRect; x0, y0, dx, dy: Double): TPointDynArray;
var
  x, y: Double;
  i: Integer;
begin
  {für jede Spalte einen Punkt}
  SetLength(Result, ARect.Right - ARect.Left + 1);
  {Punkte berechnen}
  x := x0;
  for i := Low(Result) to High(Result) do
  begin
    y := AFunc(x);
    {unser Koordinatensystem steht auf dem Kopf}
    y := -y;
    {oberen Rand addieren}
    y := y0 + y;
    {skallieren}
    y := y / dy;
    {runden}
    Result[i].x := ARect.Left + i;
    Result[i].y := ARect.Top + Round(y);
    {nächster Punkt}
    x := x + dx;
  end;
end;

procedure ZeichnePunkteDarstellung(ACanvas: TCanvas; const ARect: TRect; const APoints: TPointDynArray);
var
  h: THandle;
begin
  h := SaveDC(ACanvas.Handle);
  try
    {Zeichenfläche einschränken}
    IntersectClipRect(ACanvas.Handle, ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
    Polyline(ACanvas.Handle, APoints[0], Length(APoints));
  finally
    RestoreDC(ACanvas.Handle, h);
  end;
end;

procedure TFTest.PaintBox1Paint(Sender: TObject);
var
  R: TRect;
  x0, y0, dx, dy: Double;
  P: TPointDynArray;
begin
  with TPaintBox(Sender) do
  begin
    R := ClientRect;
    {Hintergrund}
    Canvas.Brush.Color := clGray;
    Canvas.Brush.Style := bsSolid;
    Canvas.FillRect(R);
    Canvas.Brush.Style := bsClear;
    {ein Rechteck}
    InflateRect(R, -10, -10);
    Canvas.Pen.Color := clBlack;
    Canvas.Pen.Width := 1;
    Canvas.Rectangle(R);
    {darin der Graph}
    InflateRect(R, -1, -1);
    {Parameter initialisieren}
    x0 := 0;
    y0 := 3;
    dx := 0.05;
    dy := 0.05;
    P := BerechnePunkteDarstellung(sin, R, x0, y0, dx, dy);
    Canvas.Pen.Color := clLime;
    ZeichnePunkteDarstellung(Canvas, R, P);
  end;
end;

Chris211183 27. Feb 2015 07:45

AW: Probleme mit Sinus Darstellung
 
Ihr seid die Besten !

Vielen Dank an euch, jetzt funzt es so wie das soll:thumb: !

Schick schönes Wochenende euch !!!

:cheers:


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:32 Uhr.
Seite 2 von 8     12 34     Letzte »    

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