Forum: PC-Programmierung Zeichnen von u=u_t*cos(2*pi*f_t*t) in Delphi


von Holger (Gast)


Lesenswert?

Hallo Ihr Lieben!

Bin das erstemal hier im Forum und hoffe das ich für meine frage hier 
richtig bin

und zwar hab ich mich gerade mal an einem graph probiert, und zwar möcht 
ich die Funktion u=u_t*cos(2*pi*f_t*t) zeichnen.
kann mir jemand ein wenig auf die sprünge helfen wie ich weiter 
verfahren könnte!?

ich weiß zum beispiel nicht, wie ich die zeit definieren soll (z.B. von 
0 - 200);

Lieben Gruß
Holger


procedure TForm2.Button1Click(Sender: TObject);
var x,y,u_t,f_t: real;
begin
x:=100;
u_t:=4;  //Amplitude
f_t:=2;  //Frequenz
  while x<100 do
  begin
    x:=x+0.01;
    y:=u_t*cos(2*pi*f_t*x); //Formel
    image1.canvas.pixels[round(x+50),round(-y+100)]:=clblack;
  end;
end;

end.

von Roland Praml (Gast)


Lesenswert?

Ich würds so machen:
Angenommen dein Canvas ist 100 Pixel breit ( x= 0..100) und du möchtest 
1ms darstellen , dann entspricht x=100 = 1ms
somit
t := 1ms * x/100; bzw
t := 0.0001 * x/100;

Für x würd ich dann auch einen int-Wert nehmen und einfach von 0..100 
durch zählen.

und übrigens: mit deiner Anfangsdefinition x:=100 macht das Prog gar nix 
da die Whileschleife nicht betreten wird.

Gruß
Roland

von Holger (Gast)


Lesenswert?

Hallo Roland,

hab das mal mit einer einfachen y=x^2 Funktion probiert

var x,y: real;
begin
x:=-10;
  while x<10 do
  begin
    x:=x+0.01;
    y:=x*x;
    image1.canvas.pixels[round(x+50),round(-y+100)]:=clblack;
  end;
end;

was mir auch geglückt ist, weil es mir was anzeigt, aber irgendwie kann 
ich das nicht umsetzen in meine cosinusfunktion;

für das x von 0..100 durchzählen for-schleife benutzen?


gruß Holger

von detlef (Gast)


Lesenswert?

die frequenz ist vermutlich zu hoch und die amplitude zu klein

von Karl heinz B. (kbucheg)


Lesenswert?

Eine der Grundlagen jeder 2D Graphik ist die sog.
Window-Viewport Transformation.

Es geht darum, einen bestimmten Ausschnitt aus dem Welt
koordinatensystem (eben das Window) in einem bestimmten
Pixelbereich (eben dem Viewport) abzubilden.

Da wir uns in einem 2D Kontinuum bewegen, ist die
Window/Viewport Trafo klarerweise für x und y
getrennt aufzusetzen. Im Folgenden betrachte ich
zur Ableitung des Formalismus daher nur 1 Dimension (x).
Für y ist alles völlig analg.

Worum gehts:
Wie haben einen Ausschnitt aus der Welt, der durch seine
beiden Grenzwerte winMin und winMax gegeben sei. Diesen Bereich,
winMin bis winMax, wollen wir in einem bestimmten Pixelbereich
abbilden: viewMin bis viewMax.  Also etwa so


   winMin               winMax
    +--------------------+
   viewMin              viewMax

d.h. der Zahlenwert winMin soll nach der Umrechnung den Zahlenwert
viewMin ergeben und der Zahlenwert winMax soll zu viewMax werden.

  Die Formel für die Umrechnung lautet:

                               viewMax - viewMin
  viewX = ( winX - winMin ) * ------------------- + viewMin
                                winMax - winMin

Bsp:
Angenommen du möchtest den Bereich -10 bis +10 (zb. weil du
deine X^2 Formel eben in diesem Bereich darstellen möchtest)
abbilden. Deine Ausgabefläche sei 360 Pixel breit, wobei
links das Pixel 0 und rechts das Pixel 359 sei.

  winMin: -10
  winMax: +10
  viewMin: 0
  viewMxa: 359

Die Frage ist daher: Wenn du einen X Wert von 0.5 hast, welches
ist das entsprechende Pixel dazu.

                            359 - 0
  viewX = ( 0.5 - -10 ) * ------------   + 0
                            +10 - -10
                       359
  viewX = ( 10.5 ) * -------- + 0
                        20

  viewX = 10.5 * 17.95
  viewX = 188.475

Also, um zb auf der X Achse bei 0.5 eine Markierung zu setzen,
muss das Pixel mit der X-koordinate 188 gesetzt werden.

Völlig analog geht das auch in der Y-Achse.

D.h. du musst im Vorfeld folgendes wissen:
Wie gross ist meine Ausgabefläche in Pixel, damit du viewMinX
viewMaxX, viewMinY und viewMaxY bestimmen kannst.
Welchen Ausschnitt aus meiner Welt möchte ich auf der
Ausgabefläche sehen. Es macht einen Unterschied ob ich von
meiner Funktion den Bereich x: -10 bis +10 sehen möchte,
oder den Bereich x: 0 bis 20. Selbiges natürlich in der
Y Richtung.

Danach gehts du deine Funktion mit einer Schleife durch und
lässt dir jeweils den Funktionswert zu einem bestimmten X
ausrechnen. Du hast also das winX und das winY und zwar
in Weltkoordinaten. Um den entsprechenden Punkt zu setzen
musst du diesen Punkt in Pixel umrechnen.

Die rechnest du nach der Formel:

                                viewMaxX - viewMinX
  viewX = ( winX - winMinX ) * ------------------- + viewMinX
                                 winMaxX - winMinX

bzw.

                                viewMaxY - viewMinY
  viewY = ( winY - winMinY ) * ------------------- + viewMinY
                                winMaxY - winMinY

um und setzt zb. an die Pixelkoordinate viewX/ViewY einen
Punkt. Oder du verbindest diesen Punkt mit einer Linie mit
den Pixelkoordinaten des vorhergehenden Punktes.

von Karl heinz B. (kbucheg)


Lesenswert?

> für das x von 0..100 durchzählen for-schleife benutzen?

Was auch immer du willst.
Nur das da:

x:=100;
...
  while x<100 do

macht klarerweise nichts. Wenn x mit 100
anfängt, wird x nicht kleiner als 100 sein können
und damit wird die Schleife nie ausgeführt.


von unbekannt (Gast)


Lesenswert?

Hallo,

dir ist klar das Delphi in RAD anstatt DEG rechnet?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.