Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Grafiken (https://www.delphipraxis.net/145240-grafiken.html)

MiniMax 27. Dez 2009 14:45


Grafiken
 
Hallo Zusammen,
Ich möchte gerne so ne Art Autotacho nachbilden! Wie kann ich das Machen, sodass ich die Position des Zeigers ändern Kann?
In etwa so

Ich hoffe ihr könnt mir Helfen

Wolfgang Mix 27. Dez 2009 14:48

Re: Grafiken
 
Dein Suchwort heißt Canvas

Gruß

Wolfgang

patti 27. Dez 2009 15:38

Re: Grafiken
 
Woran hängst du denn im Moment? Liegt es am Zeichnen überhaupt oder am Berechnen des Winkels etc.? Einpaar zusätzliche Informationen wären hilfreich...

mfg

MiniMax 27. Dez 2009 16:17

Re: Grafiken
 
Hi,
thx für deine Antwort! Es hapert an allem! Ich dachte, man könnte den Tacho Hintergrund einladen, darüber den Zeiger als 2. Image und den dan I-wie drehen? Es kommen über den Serialport Zeichenketten mit Werten rein! Die müssen halt Zelegt werden und dann auf dem "Tacho" ausgegeben werden. Reicht das an Informatinionen? Wenn noch mehr Infos gebraucht werden, einfach schreiben welche --> Ich freue mich auf eine Antwort!

markus5766h 27. Dez 2009 16:31

Re: Grafiken
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

anbei 'mal ein Demo mit VU-Metern,
der Zeiger wird auf dem Canvas gezeichnet.

vielleicht hilft's

MiniMax 27. Dez 2009 16:36

Re: Grafiken
 
Hi, Danke für deine Schnelle Antwort! Wie bringe ich denn den Zeiger zum Auschlagen? Ich blick da nicht durch!

markus5766h 27. Dez 2009 16:44

Re: Grafiken
 
... durch verändern der Trackbars - alles andere ist bur einfache Mathematik
und sollte leicht anzupassen sein.

MiniMax 27. Dez 2009 16:47

Re: Grafiken
 
Hi, nee das meine Ich net! Ich habe halt nur Lazarus und blicke somit nicht so ganz durch den Code! Kannst du nicht mal einbeispielcode Einstellen womit ich die Zeiger Position festlegen kann? Also Inetwa so: Zeiger:='50' oder so ähnlich halt so dass 50 genau die Mitte ist und 0 ganz lins und 100 Ganz rechts! Vielen Dank im Voraus

markus5766h 27. Dez 2009 17:05

Re: Grafiken
 
... also :
Beispiel :
Dein Zeigerinstrument soll ein kreis sein mit einem Durchmesser von 120 Pixeln,
dann ist der Mittelpunkt an den Koordinaten : X=60, Y=60,
Dein Canvas hat eine Fläche von 120 mal 120 Pixeln.

Beispiel zum Zeichnen der Position 0 (links)
Delphi-Quellcode:
with Image1.Canvas do
 begin
  Pen.Width := 1;        // Breite Deines Striches (=Zeiger)
  Pen.Color := clBlack;  // Zeigerfarbe
  MoveTo(60,60)          // Zeigerbeginn im Mittelpunkt
  LineTo(10,60)          // zeichne einen 50-pixel langen Zeiger nach links
 end;
wenn Du jetzt eine Bitmap als Zeigerinstrument lädst, musst Du vorher den Bereich unter dem zu zeichnenden Zeiger speichern, da die durch den überzeichneten Zeiger veränderten Pixel nach dem Verändern der Zeigerposition wieder zurückgeschrieben werden müssen.

Delphi-Quellcode:
oldPixels : array[0..49] of TColor; // array für 50 Pixel (Zeigerlänge) bereitstellen
                                     // im Abschnitt Private declaration

var
 i : Integer;

for i := 0 to 49 do
 oldPixels[i] := Image1.Canvas.Pixels[i+10, 60]; // Speichern der orginal-Pixel
nach dem Zeichnen des Zeigers (außer beim ersten Zeichnen des Zeigers)
muss das alte Pixelbild unter dem Zeiger wieder hergestellt werden :

Delphi-Quellcode:
var
 i : Integer;

for i := 0 to 49 do
 Image1.Canvas.Pixels[i+10, 60].Pixels := oldPixels[i];
dieses Beispiel gilt nur für die waagerechte Position, für andere Zeigerpositionen
müssen Vektoren gespeichert werden, da der Zeiger ja auch in Vektoren dargestellt
werden soll, die nicht auf 0, 90, 180 oder 270 Grad liegen.

.. ja, und die Skalierung musst Du eben per Winkelfunktionen berechnen.

patti 27. Dez 2009 17:36

Re: Grafiken
 
Liste der Anhänge anzeigen (Anzahl: 2)
Obwohl schon eine mögliche Lösung gepostet wurde, hab ich gerade mal kurz was zusammengetippt, das funktionieren sollte. Habe für die grafische Ausgabe eine PaintBox verwendet. Die Konstante "cMaxValue" regelt, bei welchem Wert für "Value" der Zeiger voll ausschlägt, sich also ganz rechts befindet. In dem Beispiel wird der Wert von "Value" per Timer geändert, damit man sieht, wie sich der Zeiger bewegt. Zur Berechnung der Koordinaten hab ich ganz einfach die Winkelfunktionen Sinus und Cosinus verwendet. Dabei darfst du nicht vergessen, dass das "Koordinatensystem" für die grafische Ausgabe am PC oben links und nicht unten links beginnt, deshalb die verschiedenen Umrechnungen!

Die Grafik lässt sich natürlich noch anpassen, beispielsweise indem du unter den Zeiger noch ein Bitmap per Draw-Befehl aufs Canvas zeichnen lässt. Das hängt jetzt aber von dir ab.

Vielleicht hilft dir das schonmal weiter. Bei Fragen kannst du sie hier einfach stellen.

mfg

lbccaleb 27. Dez 2009 18:07

Re: Grafiken
 
Zitat:

Zitat von markus5766h
Hallo,

anbei 'mal ein Demo mit VU-Metern,
der Zeiger wird auf dem Canvas gezeichnet.

vielleicht hilft's

Nett, Danke :thumb:

markus5766h 27. Dez 2009 18:40

Re: Grafiken
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

@ lbccaleb :

hab' noch eins, keine lineare Teilung, Positionen als Konstanten gespeichert,
0..100

MiniMax 28. Dez 2009 11:29

Re: Grafiken
 
Danke an euch alle! :thumb:
Ich werde mir mal die Beispiele anschauen und wenn ich Fragen habe, werde ich sie hier Posten!

Ich wollte einfach nur den Zeiger Zeichnen und den Rest per Image Einladen! Kann ich dann den/die gleichen Code/s nehmen?

lbccaleb 28. Dez 2009 11:45

Re: Grafiken
 
Naja du musst das ganze event. schon deinen Bedürfnissen anpassen, aber hier wurden ja gute Bsp. gepostet mit welchen die Umsetzung für dich kein Problem sein sollte.

patti 28. Dez 2009 11:45

Re: Grafiken
 
Zitat:

Zitat von MiniMax
Ich wollte einfach nur den Zeiger Zeichnen und den Rest per Image Einladen! Kann ich dann den/die gleichen Code/s nehmen?

Das ist generell schon möglich. Ich kenne jetzt den Quelltext und die Arbeitsweise von markus5766h nicht, aber so wie ich es gemacht habe (siehe oben) musst du dir den Hintergrund erstmal nur in ein Bitmap laden, welches am besten genauso groß ist, wie deine Zeichenfläche. Laden kannst du ein Bild per

Delphi-Quellcode:
Bitmap.LoadFromFile({...});
aus einer Datei auf der Festplatte. Des Weiteren könntest du die Grafik aus einer Ressource laden oder per TImage-Komponente fest in dein Programm mit einbinden.
In der Zeichenroutine kannst du dieses Hintergrund-Bitmap dann per

Delphi-Quellcode:
Canvas.Draw({..});
auf die Zeichenfläche malen. Anschließend musst du dann natürlich noch den Zeiger malen. Lösungen dafür hast du ja bereits bekommen.

mfg

Edit: Der Rote Kasten macht Weihnachtsurlaub? ;-)

MiniMax 28. Dez 2009 13:02

Re: Grafiken
 
Hi,
ich danke euch rechtherzlich! Ich werde es jetzt mal ausprobieren und bei Fragen - Post hier im Forum!

Falls ich nicht noch was bis Silvester schreibe, wünsche ich euch einen

Guten Rutsch ins Neue Jahr, und vorallem Gesundheit und Erfolg!

markus5766h 28. Dez 2009 17:40

Re: Grafiken
 
Zitat:

Zitat von patti
... und die Arbeitsweise von markus5766h nicht

hab's nicht anders gemacht :
Hintergrund ist eine Bitmap (in einem TImage),
der Zeiger wird entsprechend der Umrechnung / Skalierung
auf dem Canvas gezeichnet.

patti 29. Dez 2009 16:06

Re: Grafiken
 
Ok, war mir bloß nicht ganz sicher, weil ich deinen Beitrag mehr oder weniger nur überflogen hatte und mich das oldPixels-Array etwas verwundert hat ;-)

MiniMax 30. Dez 2009 12:14

Re: Grafiken
 
Hallo,
@Patti: Wie meinst du das mit Bitmap.LoadFromFile? Und wie soll ich das Bild dann aufs Canvas Malen?
Kannst du nen Beispiel Schreiben? (Bitmap: test.bmp/ Canvasfläche TPaintbox oder Timage)??? Ich blick da net durch :wall: :wall:
Vielen Dank im Voraus

patti 30. Dez 2009 12:48

Re: Grafiken
 
Liste der Anhänge anzeigen (Anzahl: 1)
Das ist kein Problem. Eigentlich hatte ich dir oben schon einpaar Stichworte genannt, die dir dank Hilfe und Suche schonmal weiterhelfen hätten sollen, aber gut: Hier ist mal eine etwas ausführlichere "Anleitung";

Zunächst deklarierts du im private-Bereich deines Formulars eine Instanz des Typs TBitmap:

Delphi-Quellcode:
  private
    { Private-Deklarationen }
    HintergrundBild : TBitmap;
    //..
Anschließend musst du das Bitmap noch im OnCreate-Ereignis deines Formulars erzeugen und das entsprechende Bild von der Festplatte laden:

Delphi-Quellcode:
var P : TFileName;
begin
     //--
     Self.DoubleBuffered := true; // damit es nicht so flackert
     //
     HintergrundBild := TBitmap.Create;
     //
     p := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName)) + 'hintergrund.bmp';
     //
     if FileExists(p) then HintergrundBild.LoadFromFile(p)
     else MessageDLG('Bild-Datei "hintergrund.bmp" im Programm-Ordner nicht gefunden!',mtError,[mbOK],0);
Außerdem solltest du das TBitmap im OnDestroy deines Formulars wieder freigeben:

Delphi-Quellcode:
HintergrundBild.Free;
Jetzt musst du das Bild in der Zeichenroutine nur noch auf die Canvas zeichnen, etwa so:

Delphi-Quellcode:
PaintBox1.Canvas.Draw(0,0,HintergrundBild);
Und dann natürlich noch den Zeiger, aber das hatten wir ja oben schon.
Das Bitmap sollte genauso groß sein wie die PaintBox, alles andere macht kaum Sinn ;-)

Wenn du das Programm weitergeben willst, musst du auch immer die Datei, welche das Hintergrundbild beinhaltet, mitliefern und sie muss sich im Ordner der EXE-Datei befinden. Dies könntest du umgehen, indem du das Bild in eine unsichtbare TImage-Komponente lädst oder aus einer Ressource holst. Wenn du Fragen hast, dann kannst du in der DP mal nach diesen Stichwörtern suchen oder hier einfach noch mal nachfragen.

Hab das Programm inklusive Bild-Datei und Quelltext mal in den Anhang.

Viel Spaß ;-)

MiniMax 30. Dez 2009 13:21

Re: Grafiken
 
Hi Patti,
das ist echt nett von dir! Ich hatte nämlich schonmal rumexperementiert, aber Irgendwie war das Bitmap immer Vordergrund und der Zeiger war weg! Allerdings hatte ich es mit Image1.picture.LoadfromFile() gemacht. Allerdings Habe ich noch eine Frage: Wie kann ich in deinem Beispiel den Radius Ändern? oder Auch die Länge des Zeigers? (Kannst du das eventuell (wenn du Lust hast) in Constanten Speichern? In etwa so: Radius = xxx oder Zeigerl = xxx ???) Ich blicke da zwar mittlerweile so halbwegs durch, aber Irgendwie Habe ich das mal mit Cos und Sin gemacht! Aber halt ohne Hintergrund! Wenn du das Machen könntest wäre das richtig nett! :?: :?: Viele Dank im Voraus

patti 30. Dez 2009 15:20

Re: Grafiken
 
Im Moment bestimmt die Breite der PaintBox die Länge des Zeigers, da dieser immer die halbe Breite lang sein sollte. Du musst dann dementsprechend nur diese beiden Zeilen anpassen:

Delphi-Quellcode:
x := (pbVUMeter.Width div 2) + Round(cos(d)*(pbVUMeter.Width div 2));
//
y := pbVUMeter.Height - Round(sin(d)*(pbVUMeter.Width div 2));
Denn dort werden ja die "End-Koordinaten" für den Zeiger bestimmt. Das "pbVUMeter.Width div 2" kannst du durch die von dir gewünschte Länge ersetzen. Tipp: Mach dir auf einem Stück Papier eine kleine Skizze, dann siehst du relativ schnell, wie die Koordinaten berechnet werden müssen und wie die Formeln zu Stande kommen.

Ich verstehe nicht ganz, was du mit dem Radius meinst. Wenn du den Radius des Kreises meinst: Der wird ja durch das Hintergrund-Bild bestimmt. Er wird ja nicht vom Programm aus gezeichnet, sondern ist "in der Bitmap drin" :gruebel:

mfg

mb1996 30. Dez 2009 15:50

Re: Grafiken
 
Es giebt auch ein Tacho bei TMS.
Ich weiß nicht ob du TMS kennst, aber ich würde es dir empfelen.
Das ist ein Erweiterungspaket, das super objekte mit sehr guter Grafik, wie Windows 7 hat. :-D
Geh mal unter http://www.tmssoftware.com/site/advsmoothcontrols.asp
An der Seite kannst du dein Delphi auswählen und downloaden.
In der zip-Datei ist eine Datei, die du mit Delphi öffnest und insterlierst und complimierst.
Falls die Objekte noch nicht gehen und eine Fehlermeldung kommt: ... nicht gefunden, musst du alle Datein der Zip-Datei in den Ordner: '...Borland\Delphi7\lib' kopieren.
Auf der Seite kann man auch noch mehr Erweiterungspakete downlaoden.


Viele Grüße und guten Rutsch :-D

Miguel

MiniMax 30. Dez 2009 16:07

Re: Grafiken
 
Mit dem Radius meine ich den Radius der den Zeiger beschreibt! Ich könnte ja auch einen ganz kleinen Radius wählen um einen Vollkreis(wie beim Tacho) zu beschreiben.

@mb1696 Ich besitzte leider bis jetzt kein Delphi! Ich überlege mir ob ich mir vielleicht Delphi 7 hole. Die Demo für Delphi 2010 habe ich nur der Will bei der Installation was Downloaden, nur ich habe kein I-Net an dem Rechner --> hat jemand eine Überbrückungs Idee? :?: :!: :?:

patti 30. Dez 2009 17:05

Re: Grafiken
 
Ich versteh leider immer noch nicht genau, worauf du hinaus willst.

Zitat:

Zitat von MiniMax
Mit dem Radius meine ich den Radius der den Zeiger beschreibt! Ich könnte ja auch einen ganz kleinen Radius wählen um einen Vollkreis(wie beim Tacho) zu beschreiben.

Der Radius des Kreises entspricht doch der Länge des Zeigers :gruebel:

Kann es sein, dass du den Winkel meinst, den der Zeiger überstreicht? Im Moment wären das ja 180°, von links bis rechts. Das könnte man natürlich auch noch ändern und auf einen anderen Wert setzen, allerdings müsste der Zeiger-Ursprung natürlich dementsprechend mittig im Bild liegen und nicht am unteren Rand, so wie es im Moment der Fall ist.

Einfach noch mal genauer erklären, um was es geht...

mfg

MiniMax 30. Dez 2009 17:41

Re: Grafiken
 
ja genau das meine ich! :thumb:
Der Nullpunkt soll nun nicht mehr in der Waagerechten liegen! Also es Solle ein Kreis von 270° oder behr beschrieben werden! Und dass soll per Constante festgelegt werden

patti 31. Dez 2009 11:56

Re: Grafiken
 
Hast du schon selber etwas versucht? Verstehst du zumindest den Quelltext, den du bisher bekommen hast? Der nächste Schritt ist programmiertechnisch nicht mehr allzu schwer, nur musst du halt etwas mehr berechnen und dich etwas mit Sinus und Cosinus auskennen, dann sollte auch das machbar sein. Hast du dir schonmal Gedanken gemacht?

mfg

MiniMax 31. Dez 2009 12:47

Re: Grafiken
 
Gedanken ja und den Quelltext Verstehe ich auch!
Kannst du mir denn nicht die Entsprechende Quelltext Zeile eben umändern? Bitte :?: :cry:

Ich habe noch den Folgenden Quelltext zum Zeichnen:

Delphi-Quellcode:
procedure anaShowDisplay(dsp: TPaintBox; aWert: Integer);
const
kStrich = 5; lStrich = 8; anzStriche = 21; sWinkel = 1.05; iRadius = 75;
zRadius = 40; zStrich = 48; zBereich = 1000; zTeilung = 250;

var
dWinkel, aWinkel: Single; sWert: Integer; dText: string;
x, y: Integer; x1, y1, x2, y2: Single;
i: LongInt;

function xD(x: Single): Integer;
begin
Result := Round(dsp.ClientWidth * (x / 100) + dsp.ClientWidth / 2);
end;

function yD(y: Single): Integer;
begin
Result := dsp.ClientHeight - Round(dsp.ClientHeight * ((y-20) / 80));
end;

dsp.Canvas.Pen.Color := clRed;
aWinkel := sWinkel + ((zBereich-aWert) / zBereich) * sWinkel;
x1 := Cos(aWinkel) * zRadius;
y1 := Sin(aWinkel) * zRadius;
x2 := x1 + Cos(aWinkel) * zStrich;
y2 := y1 + Sin(aWinkel) * zStrich;
dsp.Canvas.MoveTo(xD(x1),yD(y1));
dsp.Canvas.LineTo(xd(x2),yD(y2));
Kann ich den einfach gegen dein Zeiger Zeichnen Austauschen? Nur weis ich hier Net wie Ich den Zeiger um Mehr als 180° Laufen lassen kann, und wie ich die Position bestimmen kann! Vielleicht ist dein Umändern doch besser!

patti 31. Dez 2009 13:26

Re: Grafiken
 
Liste der Anhänge anzeigen (Anzahl: 2)
OK, ausnahmsweise :)

Wenn der Code, den du gepostet hast, funtkioniert, dann kannst du ihn natürlich genauso verwenden.

Ich hab meinen Code mal angepasst, man kann jetzt per Konstanten festlegen, bei welchem Winkel der Zeiger startet (wo also "0" ist) und welchen Winkel er maximal überstreicht. Außerdem hab ich dem Zeiger und der "Tacho-Scheibe" ein kleines Antialiasing verpasst, damit es "smooth" ausschaut (kann man per Konstante an- und ausschalten). Allerdings wird die Tacho-Scheibe jetzt wieder vom Programm gezeichnet, befindet sich also nicht in der Hintergrund-Bitmap. Das solltest du jedoch auch wieder ändern können, wenn du dir einbisschen Zeit nimmst um den Quelltext wirklich zu verstehen.

Eine Sache noch: Ich hoffe, dir ist bewusst, dass du das jetzt nicht wirklich selber programmiert hast und du so vermutlich auch nicht viel lernen wirst. Daher mein dringender Tipp: schau dir den Quelltext an und nimm dir etwas Zeit, um ihn zu verstehen. Normalerweise bekommst du hier in der DP nicht immer einen kompletten Quelltext von anderen geschrieben :!:

MiniMax 31. Dez 2009 13:38

Re: Grafiken
 
Hi Patti,
du bist der Beste (wie das Gesamte Forum)!! :thumb: :thumb: :thumb: :thumb: :thumb:
Ich weis dass ich net Selber Programmiert habe aber der Quelltext weird mir Helfen das Später selber zu machen! :!: Ich bin z.Z noch in der Lernphase von Delphi!
Ich danke dir rechtherzlich und wünsche dir und dem Gesamtem Forum einen Guten Rutsch --> echt nettes Forum :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:05 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-2025 by Thomas Breitkreuz