Entwickler-Ecke

Multimedia / Grafik - PaintBox eine Skala einrichten(ähnlich Lineal)


ALF - Sa 03.07.10 11:59
Titel: PaintBox eine Skala einrichten(ähnlich Lineal)
Ja ich bins mal wieder mit den blöden logik Problemen bei so was!
Kurz erklärt ist das ganze an Hand des Bildes was ich machen möchte! Im Prinzip funct es ja schon
aber leider nicht sehr genau(Pixelgenauigkeit)
Habe ich entlich, z.B. die 50ziger Werte richtig funcen die 25 oder 75 nicht mehr sauber!
oder die Posetivwerte stimmen, dann stimmen die negativwerte nicht mehr
Habe zwar schon ne fertige Lösung, ist aber bei ändereungen im Programm sehr umständlich alles zu korregieren!

Anmerkung: die Trennlinie, Null_Linien, und die 100/-100 Markierungen funcen korrect!

Was brauche ich also! Die richtige MatheLogik für die anderen Werte. Leider scheitert es da immer an der Umsetzung!
skahla

Gruss Alf


elundril - Sa 03.07.10 15:05

wie schaut denn dein derzeitiges Konzept aus? Aber wenns einfach nur darum geht die Paintbox in "100 Teile einzuteilen", dann könntest du ja eigentlich mit der Prozentformel arbeiten. Also


Delphi-Quelltext
1:
  MarkierungY := Round((Paintbox1.Height / 100) * Aktuelle_Position);                    


Oder versteh ich da was nicht ganz?

lg elundril


ALF - Sa 03.07.10 15:56

hi,
Im Prinzip ist es ja richtig, danach Arbeite ich ja auch!
nur ne Aktuelleposition gibt es ja nicht in diesem Sinne, den auch die müsste ja errechnet werden
um die Marke zusetzen!
Hier mal der Code für die 50Marken!

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
y1:= round(y* 63 /100)+3;
peakbuf.Canvas.MoveTo(x - 5, y1); //+50 linie  rechtkanal
peakbuf.Canvas.LineTo(x, y1 );
peakBuf.Canvas.TextOut(x-16, y1 - 5'50');
y1:= y- round(y* 63 / 100 )-3;
peakbuf.Canvas.MoveTo(x - 5, y1);  //-50 linie linkerkanal
peakbuf.Canvas.LineTo(x, y1 );
peakBuf.Canvas.TextOut(x - 19, y1 - 5'-50');
y1:= round(y* 12 /100)+3;
peakbuf.Canvas.MoveTo(x - 5, y1); //+50 linie  linkerkanal
peakbuf.Canvas.LineTo(x, y1 );
peakBuf.Canvas.TextOut(x-16, y1 - 5'50');
y1:= y- round(y* 12 / 100 )-3;
peakbuf.Canvas.MoveTo(x - 5, y1);  //-50 linie rechtkanal
peakbuf.Canvas.LineTo(x, y1 );
peakBuf.Canvas.TextOut(x - 19, y1 - 5'-50');
Funct!!!
Die Zahlen 63 und 12 habe ich, sagen wir mal, durch ausprobieren rausbekommen 8)
Aber normaler weise müsste dies ja, sagen wir mal so, 1/12tel oder 1/64tel der höhe ausmachen.
Aber genau an diesem Punkt funct alles nicht mehr!! Zumindestens wenn ich versuche dies in einer Formel zu packen.
An dieser stelle treten dann sogenannte Pixeldiferrenzen auf beim verändern der grösse der Form bzw der PaintBox!
Schlimmer wird es dann sogar bei den 25/75ziger Marken!

Ich weiss, im Prinzip ganz einfach, aber wenn man die Logik der simplen Mathematik nicht mehr behercht :peinlich: und :duck:
dann klemmt es halt an sowas!
Vielleicht habe ich auch ein falschen Ansatz für die Berechnung. Aber nach fast 3 Tagen Versuche es richtig zu machen......
Gruss Alf


elundril - Sa 03.07.10 18:44

also, ich hab mal was kleines getestet:

Hier werden die linien gezeichnet (wert gibt den prozentwert bei einem kanal an):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
var y1, w: extended;
begin
  w := PaintBox1.height / 4;
  y1 := (w / 100) * ( (wert*-1) + 100);
  PaintBox1.Canvas.Pen.Color := clBlack;
  PaintBox1.Canvas.MoveTo(0,round(y1));
  PaintBox1.Canvas.LineTo(5,round(y1));
  PaintBox1.Canvas.MoveTo(0,round(y1+(w*2)));
  PaintBox1.Canvas.LineTo(5,round(y1+(w*2)));



aufgerufen wird das ganze hier (die ersten zwei zeilen machen die trennlinie zwischen linkem kanal und rechtem kanal:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
PaintBox1.Canvas.MoveTo(0,round((PaintBox1.Height) / 2));
  PaintBox1.Canvas.LineTo(PaintBox1.Width,round((PaintBox1.Height) / 2));
  drawlines(0);
  drawlines(50);
  drawlines(-50);
  drawlines(100);
  drawlines(-100);
  drawlines(25);
  drawlines(-25);
  drawlines(75);
  drawlines(-75);


ich hab das ganze mal in einem testprogramm getestet (sollte funktionieren so wie du es willst). siehe anhang.

lg elundril

//edit: rounds verschoben & anhang upgedated


Delete - Sa 03.07.10 19:02

Dieses "Round" stört mich gewaltig! Mach Deine Berechnungen mit Real-Zahlen und wandle sie danach mit RealToInt. Das ist besser.

Warum? Bei y1+(w*2) treffen 2 Rundungsfehler aufeinander.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
function realtoint(r:real):integer;
 var v:variant;
 begin
   v:=r;
   result:=v;
 end;


elundril - Sa 03.07.10 19:17

das macht RealToInt. Es wandelt eine Kommazahl in eine ganzzahl um (Kaufmännisches Runden). Ich könnte dir Ceil für zwangsweise aufrunden und floor für zwangsweises abrunden anbieten. RealToInt gibt in Delphi aber nicht. ;)

edit:// oder ich könnte mit div arbeiten statt /, dann bekomme ich keine Kommazahlen.

lg elundril


jaenicke - Sa 03.07.10 19:26

user profile iconhathor hat folgendes geschrieben Zum zitierten Posting springen:
Dieses "Round" stört mich gewaltig! Mach Deine Berechnungen mit Real-Zahlen und wandle sie danach mit RealToInt. Das ist besser.
Aber auch extrem viel langsamer. Variant ist eher eine Notlösung für COM denn für sinnvolle Nutzung gedacht. Zudem macht dein RealToInt auch nix anderes als zu runden.

user profile iconhathor hat folgendes geschrieben Zum zitierten Posting springen:
Warum? Bei y1+(w*2) treffen 2 Rundungsfehler aufeinander.
Das kommt aber einfach nur daher, dass eben zu früh gerundet wird. Deshalb braucht man trotzdem nicht ausgerechnet Variant benutzen.

Wir sind doch nicht bei Visual Basic. :mrgreen:


elundril - Sa 03.07.10 19:30

gut, dann verschieben wir das runden einfach in den draws. :) ich lass ja mit mir reden. :mrgreen:


ALF - Sa 03.07.10 21:00

sorry: irgenwie will es nicht optisch richtig sein! Beim Starten ja, sobald die Form kleiner/grösser gemacht wird ist die 25/75 Marke nicht mehr in der mitte zwischen 0 zu 50 und 50 zu 100;
25 linie tendiert zur 0, die 75 zur 100
habe jetzt alles so gemacht aber:
50 ok, bleibt in der mitte zwischen 0 und 100 marke
25 und 75 leider nicht wenn ich es so übernehme!

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
y1:=round(((y/4) /100)*((75*-1)+100))+3;  //+75 linie linkerkanal
peakbuf.Canvas.MoveTo(x - 5, y1);
peakbuf.Canvas.LineTo(x, y1 );

y1:=round(((y/4) /100)*((50*-1)+100))+3;  //+50 linie  linkerkanal
peakbuf.Canvas.MoveTo(x - 5, y1); 
peakbuf.Canvas.LineTo(x, y1 );

y1:=round(((y/4) /100)*((25*-1)+100))+3;  //+25 linie linkerkanal
peakbuf.Canvas.MoveTo(x - 5, y1);  
peakbuf.Canvas.LineTo(x, y1);
//als test------------------------------
y1:=round(((y/4) /100)*((-50*-1)+100))+3;  //-50 linie  linkerkanal
peakbuf.Canvas.MoveTo(x - 5, y1); 
peakbuf.Canvas.LineTo(x, y1 );

als test mal mit -50*-1 oder 50 und *-1 weggelassen ist beim start in der Mitte aber dann verschiebt sich dies
Oder sollte ich die Formel missverstanden haben!?

Gruss Alf


elundril - Sa 03.07.10 21:05

warum nimmst du nicht meine Procedure einfach mittels Copy und paste und setzt im OnPaint nur mehr die werte ein. Wenn du dir die beispielanwendung mal ansiehst, passt das so wie du es willst?

wenn ja, dann nimm einfach das per copy und paste. außerdem hast du dann redundanten code zusammengefasst. ;) weil du ja manchen code öfters ausführst.

lg elundril


ALF - Sa 03.07.10 21:55

Sorry hab vergessen zu erwähnen, dass ich das ganze erst mit bitmap vorzeichne und dann mit ner PBPaint procdure in die Paintbox übernehme!
Darum auch nur der Versuch die Formel zu übernehmen! Was natürlich schief geht wenn man es nicht versteht!?
Warum ich nicht mit Painbox direkt arbeite liegt einfach daran das beim Zeichnen von sich gegenüliegenden Paintboxen es immer wieder zu störungen kommt(zu mindestens bei mir, selbst wenn ich sie auf ein Panel lege) darum auch zuerst BitMap!

Wenn es also noch ne Lösung für BitMap gäbe ??????

Denn jetzt bin ich ganz konfus! Formel machts leider nicht und mit Paintbox direkt wollte ich nicht Arbeiten!
aus den oben genannten Gründen, würde auch einiges durch einander bringen das eine so das andere so!?
Nicht sauer sein das ich nicht Copy&Paste gemacht habe!!!
Gruss Alf


jaenicke - Sa 03.07.10 21:57

PaintBox oder OffScreenBitmap macht da keinen Unterschied. Eine OffScreenBitmap ist schon sinnvoll, damit der Hintergrund mit der Skala nicht immer neu gezeichnet werden muss.

Worauf du zeichnest macht aber wirklich keinen Unterschied, wenn du die Bitmap danach einfach kopierst. :nixweiss:


ALF - Sa 03.07.10 22:13

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Worauf du zeichnest macht aber wirklich keinen Unterschied,.....

In diesem Fall schon würde ich sagen!? Sonst hätte ich ja user profile iconelundril seins übernommen!
Würde aber gerne vermeiden das einmal so, Paintbox direkt zeichen und Anderes wieder mit BitMap zu machen! So bleibe ich mir einer Linie treu und muss bei Fehlern nicht mal da oder da suchen! Glaube, dass ihr das auch so seht :wink:
Gruss ALf


elundril - Sa 03.07.10 22:19

du kannst ja einfach statt dem Paintbox1 immer dein Offscreen-Bitmap verwenden. sollte ja auf gleiche hinauskommen ob du jetzt schreibst paintbox1.Heigth / 2 oder bitmap1.height / 2. ;)

lg elundril


Hidden - Sa 03.07.10 22:27

user profile iconelundril hat folgendes geschrieben Zum zitierten Posting springen:
du kannst ja einfach statt dem Paintbox1 immer dein Offscreen-Bitmap verwenden. sollte ja auf gleiche hinauskommen ob du jetzt schreibst paintbox1.Heigth / 2 oder bitmap1.height / 2. ;)
Das würde ich auf jeden Fall tun. Besonders in diesem Fall, denn nur so kannst du das Erstellen des eigentlichen Bildes und der Skalierungshilfe/was es ist sauber trennen.

lg,


ALF - Sa 03.07.10 22:36

Bitt macht mich jetzt nicht noch mehr :?!?:
Ich weiss das man das optische von rechnerrischen trennen soll oder so ähnlich!
Was aber nicht erklärt warum die Formel, als solches, wie ich sie versucht habe einzusetzen, nicht das selbe Ergbinis liefert!!!!!

Gruss Alf


jaenicke - Sa 03.07.10 22:51

Wie wäre es mit nem kleinen Demoprojekt? ;-)
Ich bin mir sicher, dass dann schnell klar ist, was da passiert.


elundril - Sa 03.07.10 22:53

weil ich keine ahnung hab was du mit dem "y" machst bevor das programm zu dem von dir gezeigten code kommt. außerdem hab ich keine ahnung warum du da ein +3 dann noch dazuschmeißt.


ALF - Sa 03.07.10 23:15

ok problem erkannt!!! Hänge trotzdem mal das Project mit an!
Fehler von mir, besser gesagt!!!Die TrennLinie, die 100/-100Markierungen und die Null_Linien sind fix!!!!!
Müssen auch so bleiben!!!!!
So das also die Formel richtig ist, aber ich dies ander nicht mit angesagt habe :oops:
Die Berechnung muss also dies berücksichtigen!????

jetzt gibts haue :duck:
Gruss Alf


elundril - Sa 03.07.10 23:38

hier mal als nachtrag wie man die procedure von oben in ein off-screen-bitmap einbauen kann. das ganze diesmal als anhang.

lg elundril


ALF - So 04.07.10 14:50

ok ich hab mal meine Variante hochgeschoben(oben im DL [http://www.delphi-forum.de/download.php?id=12882] ), damit man sieht was ich kongret meine!!!
Ist zwar nicht vollständig, aber sie zeigt es, um Missverständnisse auszuräumen!!
Sorry user profile iconelundril aber es ist nicht das was ich suche! Leider ist es nicht so einfach dies zu erklären :?
Gruss Alf