![]() |
Delphi-Version: 10.2 Tokyo
Seltsames Verhalten einer Funktion
Liste der Anhänge anzeigen (Anzahl: 2)
Hey,
ich bin es mal wieder, langsam verzweifle ich an Delphi :( Bei meinem Programm werden Boxplots dargestellt/gezeichnet, prinzipiell funktioniert das auch. Nun habe ich mich daran versucht 2 unterschiedliche Boxplots darzustellen und bin auf ein sehr großes Problem gestoßen: Wenn beide Boxplots den gleichen Datensatz haben werden sie Normal dargestellt, sofern aber einer der Boxplots einen anderen Datensatz besitzt wird der erste nicht mehr korrekt dargestellt (siehe Anhang). Ich habe bereits einiges getestet und bin zu folgendem Entschluss gekommen:
Dementsprechend hier die Funktion (bitte schlagt mich nicht für den schlechten Stil):
Delphi-Quellcode:
Findet ihr einen Fehler? Langsam verzweifle ich daran und kann mir nicht erklären woran es liegen kann :/ :(
var
zahlen : array of array of Double; namen : TStrings; quartils : array[0..1] of Double; median : Double; bereiche: array[0..3] of array of Double; ... procedure drawLine(PaintBox:TPaintBox; color: TColor; minX, minY, maxX, maxY:integer); begin PaintBox.Canvas.Pen.Color := color; PaintBox.Canvas.MoveTo(minX, minY); PaintBox.Canvas.LineTo(maxX, maxY); end; procedure zeichnen(PaintBox : TPaintBox; Boxplot : real; FHeight, FWidth: Integer); var i, xWert, Height, index: integer; eineLaengeneinheit : Double; getHeight : array[0..9] of integer; begin if Length(zahlen) > 0 then begin xWert := 40; Height := round(FHeight * 0.4); index := Round(Boxplot); eineLaengeneinheit := (FWidth-120) / round(zahlen[index][Length(zahlen[index])-1] - zahlen[index][0]); getHeight[0] := round(FHeight * 0.31919 + Height * Boxplot); getHeight[1] := round(FHeight * 0.13214 + Height * Boxplot); getHeight[2] := round(FHeight * 0.18379 + Height * Boxplot); getHeight[3] := round(FHeight * 0.04839 + Height * Boxplot); getHeight[4] := round(FHeight * 0.09839 + Height * Boxplot); getHeight[5] := round(FHeight * 0.21839 + Height * Boxplot); getHeight[6] := round(FHeight * 0.15839 + Height * Boxplot); getHeight[7] := round(FHeight * 0.26839 + Height * Boxplot); getHeight[8] := round(FHeight * 0.28839 + Height * Boxplot); getHeight[9] := round(FHeight * 0.27839 + Height * Boxplot); // Name des Boxplots PaintBox.Canvas.TextOut(xWert-30, getHeight[3]-20, namen[index] + ':'); // Einteilung/Markierung // Minimum PaintBox.Canvas.TextOut(xWert-3, getHeight[0], FloatToStr(zahlen[index][0])); drawLine(PaintBox, clRed, xWert, getHeight[1], xWert, getHeight[2]); // Maximum PaintBox.Canvas.TextOut(FWidth - 80, getHeight[0], FloatToStr(zahlen[index][Length(zahlen[index]) - 1])); drawLine(PaintBox, clRed, FWidth-80, getHeight[1], FWidth-80, getHeight[2]); // unteres Quartil PaintBox.Canvas.TextOut(round(xWert - 3 + (quartils[0] - zahlen[index][0]) * eineLaengenEinheit), getHeight[3], FloatToStr(quartils[0])); drawLine(PaintBox, clRed, round(xWert + (quartils[0] - zahlen[index][0])*eineLaengenEinheit), getHeight[4], round(xWert + (quartils[0] - zahlen[index][0])*eineLaengenEinheit), getHeight[5]); // median PaintBox.Canvas.TextOut(round(xWert - 3 + (median - zahlen[index][0]) * eineLaengenEinheit), getHeight[3], FloatToStr(median)); drawLine(PaintBox, clRed, round(xWert + (median - zahlen[index][0])*eineLaengenEinheit), getHeight[4], round(xWert + (median - zahlen[index][0])*eineLaengenEinheit), getHeight[5]); // oberes Quartil PaintBox.Canvas.TextOut(round(xWert - 3 + (quartils[1] - zahlen[index][0]) * eineLaengenEinheit), getHeight[3], FloatToStr(quartils[1])); drawLine(PaintBox, clRed, round(xWert + (quartils[1] - zahlen[index][0]) * eineLaengenEinheit), getHeight[4], round(xWert + (quartils[1] - zahlen[index][0]) * eineLaengenEinheit), getHeight[5]); //Boxplot an sich drawLine(PaintBox, clBlack, xWert, getHeight[6], round(xWert + (quartils[0] - zahlen[index][0]) * eineLaengenEinheit), getHeight[6]); drawLine(PaintBox, clBlack, round(xWert + (quartils[0] - zahlen[index][0]) * eineLaengenEinheit), getHeight[4], round(xWert + (quartils[1] - zahlen[index][0]) * eineLaengenEinheit), getHeight[4]); drawLine(PaintBox, clBlack, round(xWert + (quartils[0] - zahlen[index][0]) * eineLaengenEinheit), getHeight[5], round(xWert + (quartils[1] - zahlen[index][0]) * eineLaengenEinheit), getHeight[5]); drawLine(PaintBox, clBlack, round(xWert + (quartils[1] - zahlen[index][0]) * eineLaengenEinheit), getHeight[6], FWidth - 80, getHeight[6]); //Skala for i := 0 to round(zahlen[index][Length(zahlen[index])-1]-zahlen[index][0]) do drawLine(PaintBox, clBlack, round(xWert + i * eineLaengenEinheit), getHeight[7], round(xWert + i * eineLaengenEinheit), getHeight[8]); drawLine(PaintBox, clBlack, xWert, getHeight[9], FWidth-80, getHeight[9]); end; end; |
AW: Seltsames Verhalten einer Funktion
Hallo,
OK, für den schlechten Stil hast Du dich schon entschuldigt ;) Aber: for i := 0 to round(zahlen[index][Length(zahlen[index])-1]-zahlen[index][0]) do und round(xWert + i * eineLaengenEinheit), getHeight[8 Wer soll das verstehen? Bitte benutze eine lokale Variablen und F5/F7/F8 und Strg+F5. Ich kenne dieses Boxplots erst mal gar nicht. Und einen Datensatz habe ich auch nicht gefunden. Woran erkennt man, dass die Boxplots einen gleichen/unterschiedlichen Datensatz haben? Du hattest ja geschrieben, dass es in C++ bereits funktionierte. Gehe doch den C++ und den Delphi-Code schrittweise durch und vergleiche die Variableninhalte. |
AW: Seltsames Verhalten einer Funktion
Du rundest Gleitkommawerte auf Ganzzahlen, da kann es schon mal passieren, dass zwei Werte, die in der Dezimaldarstelllung gleich aussehen und als Nachkommateil .5 haben in der Binärdarstellung leicht unterschiedlich sind, so das einer nach oben und einer nach unten gerundet wird. Vielleicht ist das dein Problem...
|
AW: Seltsames Verhalten einer Funktion
Zitat:
Deine Methode ist viel zu lang und komplex. Mache mehrere kleinere daraus, z.B. trenne die Berechnung und das Malen. Und dann wie hoika schon schrieb debugge. |
AW: Seltsames Verhalten einer Funktion
Ohne den Source im Einzelnen angesehen zu haben, habe ich folgenden Verdacht:
Es gibt globale Variablen. Die Prozeduren gehören zu keinem Objekt und es wird in den Prozeduren auf die globalen Variablen zugegriffen. Bei jedem Repaint besteht die Gefahr, dass Werte aus den globalen Variablen verwendet werden, die zum anderen "Datensatz" gehören. Die Folge ist, dass mit falschen Werten gezeichnet wird. |
AW: Seltsames Verhalten einer Funktion
Zitat:
Zitat:
Die Datensätze sind in
Delphi-Quellcode:
gespeichert und sie werden durch den Nutzer eingeben oben in meinem Fall waren die Datensätze:
zahlen
Delphi-Quellcode:
Der unterschied war hierbei die 5 bzw. 6 sprich das Maximum.
zahlen[0] := [0,1,2,3,4,5]
zahlen[1] := [0,1,2,3,4,6] Im oberen Bild sieht man, dass beide Boxplots richtig dargestellt werden sofern die Datensätze gleich sind aber bei unterschiedlichen Datensätzen der obere Boxplot "verkrüppelt" ist. Zitat:
Zitat:
Delphi-Quellcode:
durch
round
Delphi-Quellcode:
ersetz, da somit dieser Fehler ja nicht mehr auftreten dürfte.
trunc
Allerdings tritt er immer noch auf und es hat sich nichts verändert. Aber prinzipiell ist die Idee mit trunc statt round gar nicht so schlecht. Zitat:
Zitat:
In der Zeichnen Funktion werden ausschließlich lokale Variablen verwendet bzw. überschrieben, es werden nur aus den globalen Variablen gelesen, demnach dürften die globalen Variablen nicht verändert worden sein. Ich habe die Datensätze auch mehrfach kontrolliert und getestet ob diese verändert werden o.ä. und das wurden sie nicht, daher wundert mich das ganze ja so sehr, dass die Darstellung einmal mit gleichen Datensätzen geht und das andere mal mit unterschiedlichen nicht mehr. Werde jetzt mal debuggen und mich später nochmal melden :D |
AW: Seltsames Verhalten einer Funktion
Ich habe jetzt noch nicht gedebuggt aber mir ist folgende aufgefallen:
Bisher waren die Datensätze immer
Delphi-Quellcode:
Dabei war dann der erste Boxplot verkrüppelt.
zahlen[0] := [1,2,3,4,5]
zahlen[1] := [1,2,3,4,6] Nun habe ich die Datensätze einfach mal getauscht:
Delphi-Quellcode:
Und so werden beide ganz normal angezeigt.
zahlen[0] := [1,2,3,4,6]
zahlen[1] := [1,2,3,4,5] Das wundert mich jetzt noch viel mehr Edit: Zitat:
Habe meinen Fehler gefunden und jetzt fühle ich mich ziemlich dumm -_- Habe vergessen die Variablen für Quartils und Median auch auf mehrere Boxplots auszulegen. Werde das jetzt mal ändern aber daran liegt es vermutlich. Edit2: Es lag tatsächlich an den Variablen, jetzt fühle ich mich wirklich dumm -_- |
AW: Seltsames Verhalten einer Funktion
Hallo,
geht doch. die Quartils und Median sahen für mich eh schon etwas komisch aus, die hatte ich auch im Verdacht ... ;) Der Debugger ist Dein bester Freund. |
AW: Seltsames Verhalten einer Funktion
Zitat:
Sherlock |
AW: Seltsames Verhalten einer Funktion
Zitat:
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:33 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 by Thomas Breitkreuz