Autor |
Beitrag |
Krefti
      
Beiträge: 164
Win XP/Vista/Win7/ubuntu
Delphi 7/2006/2009 Pro
|
Verfasst: Fr 25.08.06 09:10
guten morgen zusammen..
mein problem ist folgendes: Ich zeichne auf einem image ein Rechteck und eine Linie in der mitte als x-achse. die länge und höhe des Rechtecks kann variabel eingegeben werden.
im Ursprung dieses Koordinatensystems wird ein Sinus gezeichnet, dessen Amplitude und Periodenzahl man auch variabel eingeben kann. jetzt möchte ich den sinus je nachdem was eingegeben worden ist passend strecken oder stauchen, dass er genau in das rechteck reinpasst.
hier mal mein code den ich bis jetzt habe..schaut vielleicht ein bischen chaotisch aus, aber ich bin no am anfagn
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,Printers;
type TForm1 = class(TForm) Label1: TLabel; edLaenge: TEdit; Label2: TLabel; edHoehe: TEdit; Image1: TImage; Button1: TButton; Button2: TButton; edPeriode: TEdit; edAmplitude: TEdit; Label3: TLabel; Label4: TLabel; Button3: TButton; procedure Button1Click(Sender: TObject); procedure Malebild(Canvas1:TCanvas); procedure Button2Click(Sender: TObject); procedure edLaengeKeyPress(Sender: TObject; var Key: Char); procedure edHoeheKeyPress(Sender: TObject; var Key: Char); procedure Button3Click(Sender: TObject); procedure edPeriodeKeyPress(Sender: TObject; var Key: Char); procedure edAmplitudeKeyPress(Sender: TObject; var Key: Char);
private public end; const Pi=3.1415926535897932385; var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); begin
If (edLaenge.Text='') or (edHoehe.Text='') then begin showmessage('Sie müssen Länge und Höhe eingeben'); exit; end; image1.Picture:=nil; MaleBild(Image1.Canvas); end;
Procedure TForm1.MaleBild(Canvas1:TCanvas); var offx, pixelProZoll:Integer; pixelpromm:single; laenge,hoehe,amplitude,periode: integer;
x,y,y1,x1,dx : real; xx,yy : integer;
TheRect: TRect; begin laenge:=0; hoehe:=0; periode:=0; amplitude:=0; laenge := StrToInt(edLaenge.Text); hoehe := StrToInt(edhoehe.Text); periode := StrToInt(edPeriode.Text); amplitude := StrToInt(edAmplitude.Text);
with Canvas1 do begin PixelProZoll:=GetDeviceCaps(Canvas1.Handle, LOGPIXELSX); PixelProMM:=pixelprozoll/25.4; Offx:=GetDeviceCaps(Canvas1.Handle, PHYSICALOFFSETX);
Pen.Color:=clBlack; MoveTo(Round(100*PixelProMM),Round(100*PixelProMM)); Rectangle(Rect(Round(50*PixelProMM)-offx, Round(25*PixelProMM), Round((50+laenge)*PixelProMM-offx), Round((25+hoehe)*PixelProMM)));
MoveTo(Round(50*PixelProMM)-offx,Round((25+hoehe/2)*PixelProMM)); LineTo(Round((50+laenge)*PixelProMM-offx),Round((25+hoehe/2)*PixelProMM)); x:=0; dx:=0.001; While x<=(periode * 2 * Pi) do begin y:=amplitude * sin(-x); y1:=y*25+Round((25+hoehe/2)*PixelProMM); x1:=x*25+Round(50*PixelProMM); yy:=trunc(y1); xx:=trunc(x1); Pixels[xx,yy]:=clred; x:=x+dx; end; end; end;
procedure TForm1.Button2Click(Sender: TObject); begin Close; end;
procedure TForm1.edLaengeKeyPress(Sender: TObject; var Key: Char); begin if not (key in ['0'..'9', #8]) then begin showmessage('Sie dürfen nur Zahlen eingeben!'); key := #0; exit; end; end;
procedure TForm1.edHoeheKeyPress(Sender: TObject; var Key: Char); begin if not (key in ['0'..'9', #8]) then begin showmessage('Sie dürfen nur Zahlen eingeben!'); key := #0; exit; end; end;
procedure TForm1.edPeriodeKeyPress(Sender: TObject; var Key: Char); begin if not (key in ['0'..'9', #8]) then begin showmessage('Sie dürfen nur Zahlen eingeben!'); key := #0; exit; end; end;
procedure TForm1.edAmplitudeKeyPress(Sender: TObject; var Key: Char); begin if not (key in ['0'..'9', #8]) then begin showmessage('Sie dürfen nur Zahlen eingeben!'); key := #0; exit; end; end;
procedure TForm1.Button3Click(Sender: TObject); begin Printer.BeginDoc; with printer do begin MaleBild(Printer.Canvas); end; Printer.EndDoc; end;
end. | Moderiert von Christian S.: Topic aus VCL (Visual Component Library) verschoben am Fr 25.08.2006 um 09:16
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 27.08.06 00:15
Wenn die linke-obere Ecke des Rechtecks bei (x0,y0) ist und das Rechteck die Breite/Höhe (w,h) hat sollte die Transformation irgendwie so aussehen (inklusive auf den Kopf gestellt):
(-sin((x-x0)/w*2*pi)+1)/2*h+y0
|
|
Krefti 
      
Beiträge: 164
Win XP/Vista/Win7/ubuntu
Delphi 7/2006/2009 Pro
|
Verfasst: Mo 28.08.06 08:42
vielen dank für die antwort..des hat mir schon sehr weitergeholfen.
in y-richtung füllt der sinus das rechteck aus, aber in x-richtung wird er ganz normal gezeichnet.
im moment zeichnet er so viele Perioden, bis er das ende des rechtecks erreicht hat..wie kann ich die den sinuns in x-richtung strecken oder stauchen??
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50:
| Procedure TForm1.MaleBild(Canvas1:TCanvas); var offx, pixelProZoll:Integer; pixelpromm:single; laenge,hoehe,periode,amplitude: integer;
x,y,y1,x1,dx,x0,y0 : real; xx,yy : integer;
TheRect: TRect; begin laenge:=0; hoehe:=0; periode:=0; amplitude:=0; laenge := StrToInt(edLaenge.Text); hoehe := StrToInt(edhoehe.Text); periode := StrToInt(edPeriode.Text); amplitude := StrToInt(edAmplitude.Text);
with Canvas1 do begin PixelProZoll:=GetDeviceCaps(Canvas1.Handle, LOGPIXELSX); PixelProMM:=pixelprozoll/25.4; Offx:=GetDeviceCaps(Canvas1.Handle, PHYSICALOFFSETX);
Pen.Color:=clBlack; Rectangle(Rect(Round(0)-offx, Round(0), Round((laenge)*PixelProMM-offx), Round((hoehe)*PixelProMM)));
MoveTo(Round(0)-offx,Round((hoehe/2)*PixelProMM)); LineTo(Round((laenge)*PixelProMM-offx),Round((hoehe/2)*PixelProMM)); x:=0; dx:=0.001; x0:=0; y0:=0; While x<=(laenge*PixelProMM) do begin y:=(-sin((x-x0)/laenge*2*pi))/2*hoehe*PixelproMM+y0+hoehe/2*PixelProMM; y1:=y; x1:=x; yy:=trunc(y1); xx:=trunc(x1); Pixels[xx,yy]:=clred; x:=x+dx; end; end; end; |
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mo 28.08.06 20:42
Ich dachte der Sinus soll genau ins Rechteck passen? Ich hab dich wohl falsch verstanden.
|
|
Krefti 
      
Beiträge: 164
Win XP/Vista/Win7/ubuntu
Delphi 7/2006/2009 Pro
|
Verfasst: Di 29.08.06 08:32
der sinus soll der variabel eingegebenen größe des rechteck angepasst werden..
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Di 29.08.06 10:22
Dazu solltest Du Dir eine Abbildungsfunktionen schreiben.
Erstmal befindet sich dein Rechteck irgendwo auf dem Canvas (RX,RY) und hat irgendwelche Abmessungen (RW und RH). Das ist dein 'ViewPoint'. Dann soll die Vertikal von yMin bis yMax, und die Horizontale von Xmin bis XMax laufen. Das sind deine Achsen (oder auch 'real world').
Du brauchst also eine Funktion, die dir zu real world Koordinaten die genaue Pixelposition auf dem Canvas ausrechnet. Dann kannst Du ganz bequem zeichnen.
Mal sehen (Umrechnen P_real (X_real, Y_real) ==> P_pixel (X_pixel, Y_pixel):
Quelltext 1: 2:
| X_pixel = RX + RW*(X_real - Xmin)/(Xmax - Xmin) Y_pixel = RY + RH*(Y_real - Ymin)/(Ymax - YMin) |
Das sollte doch so funktionieren. Schreib Dir am Besten eine Klasse:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| TPlotter = Class (TCanvas) Public Procedure SetViewPort (XOffset, YOffset, XWidth, YHeight : Cardinal); Procedure Axis (Xmin, Xmax, Ymin, Ymax : Extended); Procedure Move (X,Y : Extended); Procedure Draw (X,y : Extended); End; |
Damit kannst Du dann wunderbar zeichnen.
...
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| myPlotter := TPlotter (MyPaintBox.Canvas); myPlotter.SetViewPort (10,15, 300,150); myPlotter.Axis (0,100,-1,1); For x:=0 to 1000 do if x=0 then myPlotter.move (x, sin(x)) else myPlotter.draw (x, sin(x)); ... |
Das ist doch einfach, oder? Nur die 'Move' und 'Draw' Methoden musst du Dir noch definieren.
_________________ Na denn, dann. Bis dann, denn.
|
|
Krefti 
      
Beiträge: 164
Win XP/Vista/Win7/ubuntu
Delphi 7/2006/2009 Pro
|
Verfasst: Do 09.11.06 15:32
habs inzwischen selbst gelöst..
|
|
|