drawPolygon() vs. contains() -> komisch!

Status
Nicht offen für weitere Antworten.
G

Guest

Gast
hallo,

in meinem mittlerweile ausschweifenden thread über kollision von sechsecken blickt denk ich mal keiner mehr durch,
was ich auch nachvollziehen kann :p

ich will hier keine doppel-posts machen, aber das hier ist eher ne allgemeine frage, die ich hier nochmal klar stellen will, weil ich denke dass sie eher untergeht oder falsch verstanden wird im anderen thread:

Und zwar hab ich hier ein (für mich) extrem mysteriöses problem:

Ich hab 3 polygone (sechsecke). diese sind teil eines panels, dessen paintcomponent-methode nix anderes macht als
jedes dieser polygone zu zeichnen, mit der funktion: g.drawPolygon()

dann hat mein panel noch nen mouseListener. die mouseClicked-methode ist wie folgt implementiert:

für jedes der drei polygone auf dem panel wird aufgerufen:
Code:
if (currentPolygon.contains(geklickterPunkt)){
         System.out.println("clicked: "+currentPolygon.getID);
}

so, die polygone werden zufällig generiert. in 80% der fälle passt alles: man kann in die polygone reinklicken
und enthält die entsprechende System.out-print anweisung.

allerdings machnmal, da kommt keine Meldung, obwohl man ins Polygon klickt.

Manchmal heisst nicht, dass es z.B. bei jedem 3.Klick funktioniert, sondern es hängt vom Polygon ab:
wenns einmal nicht geht, wird es nie gehen, auch wenn man 50 mal klickt.

Spontan würde man nun denken, dass ich halt logische Fehler in der Erstellung der Polygone hab.

Und hier ist das, was mir so suspekt ist: es werden IMMER alle 3 polygone schön gezeichnet, ich erinnere:
mit der funktion drawPolygon()

aber die contains()-methode liefert bei machnen Polygonen halt kein true.

Für mich kann das jetzt nur heißen: Die drawPolygon methode verwendet zum zeichnen andere Informationen aus dem Polygon, als es contains() tut. Aber gemalt wird ja (denk ich) nach den 6 Eckpunkten meines Polygons.
Halt die 6 Punkte und dann Verbindungslinien, oder?

Also enthält das Polygon in seinen Variablen xpoints[] und ypoints[] die korrekten Daten.
Daraus folgt: Wenn ich im Panel auf einen Punkt klicke, der rein grafisch innerhalb des Polygons liegt, dann
muss ein contains() mit diesem Punkt auf dem Polygon auch ein true ergeben.

Tut es eben machnmal nicht.

Noch lustiger: MAchnmal funktioniert nur "ein Teil" des Polygons: z.B. wenn ich innerhalb des Polygons klicke, aber eher am unteren Rand des Inhalts, dann kommt ne Meldung. Wenn ich weiter oben (aber auch innen) klicke, dann wieder nicht.

Also meine Frage: Wieso zeichnet ein drawPolygon() das Ding korrekt, aber wenn ich reinklicke checkt die contains()-methode das nicht? Und vorallem: Wieso passiert das nur manchmal?
MEine logischen Implementierungen müssten ja da egal sein oder? KAnn ja sein dass da was falsch ist, aber dann würde er es auch falsch zeichnen. Er zeichnet es aber immer schön als Sechseck.

Bitte um Aufklärung, das wird doch wohl kein "Bug" in der API sein?

Vielen Dank.
 

0x7F800000

Top Contributor
naja, bugs 100% ausschließen kann man bei so riesigen sachen wie ganz Java eigentlich nicht...
könnte ja sein dass die contains methode zwar die richtigen daten erhält (da bin ich recht sicher) aber trotzdem in irgendwelchen ausnahmefällen falsch funktioniert...

aber bist du dir so sicher, dass es am polygon und nicht am lstener liegt? hast du schonmal im listener selbst überprüft, dass die klicks überhaupt ausgewertet werden?

Könntest du vielleicht einen kurzen funktionsfähigen code ausschnitt posten, bei dem das genannte problem auftritt?

merkwürdig ist das alles schon... ???:L
 
G

Guest

Gast
also dass es wohl nicht am listener liegt, denke ich mir daher, weil die generierung manchmal falsch war.
deshalb bin ich ja erst draufgekommen : er hat oftmals nicht erkannt, dass es eine kollision gibt, der listener übergibt ja auch nur nen punkt wie meine logischen operationen zur vermeidung von kollision.

aber habs trotzdem getestet. grad wieder der fall:
ein teil des polygons wird erkannt, wenn ich weiter links im polygon klick dann nicht mehr.
der mouseListener reagiert aber immer.

naja, um nicht auszuschließen, dass es an meinem code liegt, kann ich eigentlich nur mein komplettes programm geben.
rauskapseln kann ich da schlecht was, da der fehler überall liegen kann, weil er eben so unintuitiv ist.

ich häng hier mal n archiv aller source dateien an:

http://rapidshare.com/files/97610953/risiko.zip.html

damit ihr nicht ewig zeit mit suchen verbringt:

Sector.java , Methode Zeile 116, die das polygon erstellt, und Zeile 80 die paint-funktion, die das Polygon malt.

ihr könnt es ja probieren. immer wieder "neues spiel", auf jedes polygon klicken und unten in der console sehen,
ob er eben ausdruckt: ID clicked x (lasst euch von den anderen meldungen am anfang nicht irritieren)

Ihr müsst schätz ich so 5- 10 neue spiele machen bis es mal passiert dass ein polygon nicht reagiert..

achso: der mouseListener ist in GamePanel.java, Zeile 59. und funktioniert wie gesagt immer, hab ich schon getestet.

Dank euch!
 

0x7F800000

Top Contributor
öhm... habs eben kompiliert und versucht zu starten...
also, ich weiß nicht wie es auf deinem rechner aussieht, oder warum es auf deinem rechner irgendwie anders aussieht, aber wenn ich auf "neues spiel starten" im menu drücke, da erscheinen bei mir nur zerstreute punkte, die auf einem verzerrten sechseckigen gitter zu liegen scheinen. ???:L da ist also kaum irgendwas zu erkennen.
Kann das sein, dass sich da ein paar threads gegenseitig in den arsch beißen? die ganze sache mit swing ist allgemein nicht so wirklich threadsicher, und du hast da so einige threads in den code reingepackt, deren sinn mir momentan nicht direkt ersichtlich ist...

Also, bei mir scheitert schon alles an der zeichenfunktion. Könnte es auf deinem rechner vielleicht daran liegen, dass die threads irgendwie unerwünscht verzahnt werden?
 
G

Guest

Gast
was für threads? es gibt keinen einzigen thread. es gibt zwar eine Instanz einer Thread-Klasse, aber diese wird nie gestartet.
Was meinst du denn? Ansonsten gibt es halt lediglich den Thread, der am Anfang in der main-Methode auf den AWT Event Dispatcher geladen wird.
Sonst nix.

Das is sehr merkwürdig, bei mir zeichnet er Sechsecke. Kanns doch nich sein..
 
G

Guest

Gast
edit

also nicht dass wir uns falsch verstehen: "verzerrte" sechsecke ist schon richtig ja, also kann ich jetzt nicht beschreiben aber wenn das teil 6 eckpunkte hat und die mit linien verbunden sind, dann ist das schon so richtig.

ist jetzt kein grafikhammer das alles ^^

aber du solltest ein rotes, blaues und schwarzes sechseck sehen können.
 

Quaxli

Top Contributor
Ich komme hier an Deinen Code leider nicht ran. Aber wie wäre es, wenn Du grundsätzlich mal ein kleines lauffähiges Programm bastelst, daß Deinen Fehler demonstriert, bzw. erkennst du daran dann, was Du falsch gemacht hast.
 

0x7F800000

Top Contributor
nur damit wir uns nicht falsch verstehen, bei mir ist hier sowas zu sehen, wenn ich ein neues spiel starte:



ich hab keinen Schimmer Ahnung woran es liegen soll, dass hier nix läuft... Alles was mir aufgefallen ist: in dem was ich von rapidshare gezogen hab, hat eclipse am anfang eine stelle in der main methode rot markiert, so wie ich das momentan ausführe sieht die main so aus:
Code:
public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
        	public void run() {	
                new Main("Random RISK", 800, 600).setVisible(true);
               Logger.log("Started, ready.");
            }
        });
}
aber das war auch genau so gedacht, daran wirds nicht liegen oder... ???:L (was der Sinn dieser Konstruktion sein soll=kA^^)
ich weiß echt nich, was da schiefläuft :oops:

[edit]
@quaxli: ah ja, ich hab auch auf so einen minimalen fehlerhaften code gehofft, aber hier glaube ich ehrlichgesagt, dass der fehler ganz woanders verstreut sein könnte...
 
G

Guest

Gast
@andrey:

also das ist absolut nicht das, was du sehen solltest, aber der screenshot bringt mich weiter!
warum auch immer du soviele punkte siehst (es müssten ja nur 3*6 sein),
scheinbar läuft da bei der generierung der polygone etwas falsch. er entzieht den polygonen scheinbar koordinaten, die er nicht haben sollte. das sind dann die ganzen punkte, die du siehst.

ich caste die nämlich, und eine andre quelle hat mir nun auch gesagt dass es wohl probleme mit den bounding rectangles gibt. extrem seltsam wieso das programm bei dir was total anderes macht als bei mir...

was sagt denn deine paint-methode in der klasse "sector"? steht da denn nicht g.drawPolygon(this) ?
und die methode "castToPoly()" ?
die müsste npoints, xpoints[] und ypoints[] initialisieren..

nun, wie gesagt es liegt scheinbar daran, dass ich den super-konstruktor nie aufrufe, das polygon wird falsch erstellt, weil
meine castToPoly()-methode wohl nicht alles macht, was der konstruktor der polygon-klasse macht (den ich nie aufrufe)
ich krieg demnächst nen korrigierten code, dann sag ich auch hier bescheid.

trotzdem extrem seltsam, wieso das proramm bei dir sowas komplett anderes macht...
nur der vollständigkeit halber, bei mir sieht das nämlich so aus:

 
G

Guest

Gast
edit:

achso und audrey:

dein code ausschnitt zeigt nur die main-methode, also auch nur deren klammerung oder?
da fehlt nämlich eigentlich noch ein "}", das die klasse abschließt.

denke aber das war nur n tipp fehler oder so.

und an der konstruktion liegt es übrigens nicht. das hab ich ausm swing forum gelernt, das mach ich bei jedem programm so: man sollte swing anwendungen immer auf dem AWT Event Dispatcher starten.
dazu erstellt man n Runnable und legt es auf die EventQueue. Ich weiss auch nicht warum genau das so toll ist, aber das ist es scheinbar ;) ich kann nur sagen, was mir beigebracht wurde hier. Zumindest ist das sicherlich nicht der Fehler.

Dann hab ich noch ne Frage: Dein Eclipse benutzt nicht zufällig irgendwelche Toolkits oder sonst was?
Es sieht nämlich bei dir so aus, als würde er schon die punkte während der Generierung malen.

das kann aber eigentlich nur sein wenn du den Source Code verändert hast, denn ein repaint() wird nur EIN mal ausgeführt, und zwar NACH der generierung der Polygone. Oder eben wenn dein Eclipse ein wenig rumzaubert ;)

packs mal bitte in ein jar-archiv und führ es aus, ohne eclipse sondern direkt mit der java-runtime.
wenn du noch immer solche ergebnisse kriegst versteh ich die welt nicht mehr... source code is doch der gleiche, wie kann sowas sein :bahnhof:
 
G

Guest

Gast
Eclipse führt lediglich Programm X mit der angegebenen JVM aus. Da ist kein Zauber im Spiel.

sicher? ;)

nein quatsch schon klar, was ich meinte: ich habe eclipse, in den 5 minuten die ich es benutzt habe, so erfahren, dass ein unscheinbarer klick gleich mal 100 zeilen source code ändern kann, z.T. läuft das alles vollautomatisch ab, je nach einstellungen. ich finde das programm etwas übermächtig, bei falscher anwendung kann es einem auch code unterjubeln, den man nie geschriebne hat, was aber vllt erst 10 stunden nachher auffällt.

ich hab das bloss gesagt weil er meinte, eclipse hat nen fehler gemeldet. ich frag mich halt:
was hat er (oder eclipse) gemacht, dass dieser fehler verschwunden ist? irgendwas muss ja anscheinend geändert worden sein, aber die main-methode ist die gleiche. also evtl an anderer stelle..

und source code == source code, oder nicht? wie kann es sein dass seine anwendung ganz andere punkte auf dem panel malt als meine? und im zweifelsfall ist immer eclipse schuld :gaen: ... ;)
 

lotus

Mitglied
Veränderst du direkt xpoints[] oder ypoints[] ?
Also so etwas wie xpoints[0] = 3;

Dann hat bei mir auch nichts mehr geklappt - musste dann ein neues Polygon erstellen und die Punkte kopieren...
 
G

Guest

Gast
jop. warum auch immer es bei mir ging, habe nun erfahren:

in der tat wurde das polygon so nicht (immer) richtig erstellt. grund: meine methode hat nur
npoints, xpoints und ypoints initialisiert. nicht aber das protected Rectangle bounds, was auch Attribut der Klasse
Polygon ist.
wenn man per new-Operator ein neues erstellt, dann kümmert er sich darum, auch das bounding rectangle zu erstellen.
wenn man's weglässt, wie ich, dann kann das probleme geben...

der fehler war also so extrem simpel..

genau das, was lotus gerade meinte! und über 3 seiten hinweg konnten wir das im andren thread nicht lösen!
(obwohl ich im anderen thread die castToPoly() methode gepostet hab, und auch meinte es liegt wohl daran.. schämt euch :wink:)

danke an alle, und andrey: dein fehler ist trotzdem komisch. aber ersetz mal in der castToPoly() das ganze so, wie lotus meinte:

nicht xpoints = ..., ypoints = ...

sondern

this = new Polygon(thisNPoints, thisXPoints, thisYpoints);

dann muss es klappen.

mfg
 

0x7F800000

Top Contributor
Anonymous hat gesagt.:
this = new Polygon(thisNPoints, thisXPoints, thisYpoints);

ist syntaktisch unzulässig... du kannst nicht einfach so einem "this" vom Typ "Sector extends Polygon" einfach ein Polygon zuordnen. Ich blick in deinem code ehrlichgsagt sowieso nicht wirklich durch, wenn es jetzt funzt, dann ist alles gut ;)

aber an dieser stelle würde ich den allgemeinen tipp aus dem letzten thread gerne wiederholen: du hättest dir von anfang an eine klasse schreiben sollen, die ein manipulierbares polygon darstellt, und zwar eine, bei der du sicher weisst wie die funktioniert, statt einfach polygon zu nehmen, und an dem rumzufummeln ohne zu wissen was es für konsequenzen hat... :wink:
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben