PDA

View Full Version : [Frage] Was machen wenn gesamtes Polyon auszerhalb liegt?


tschurlo
24-10-2002, 09:48
Hi!

Schoen und gut, das Programm mal mir jetzt huebsche Figuren, die auch nett geklippt werden, aber....

... bei den Bemerkungen steht, dass auch ein Polygon, das zur Gaenze auszerhalb liegt (sie meinen ws. das Feld umschlieszt, ansonsten waers ja wurscht) auch richtig geklippt werden soll. Das muesste dann ja ein Rechteck sein, dass gerade noch sichtbar ist, oder?

Wie mache ich das? Ich habe mir ueberlegt, ich ueberpruefe, ob die Liste mit den Punkten, die sichtbar sind, leer ist, wenn das der Fall ist, denn mal ich ein Rechteck von 0-512.

Wie klingt das? Ich mein, ich probiers sowieso aus, aber klingt das wie ein guter Ansatz?

Lg,

gck
24-10-2002, 16:25
hmm, das ist eine gute Frage...

Vorallem, wie kann man üeberpeüfen, ob ein Polygon das Sichtfenster "einschließt", weil man sich ja auch so wirklich "böse" Polygone ausdenken kann, die zwar das Fenster nach allen Grenzen einschließen, aber es doch auch wieder außerhalb liegt, z.b.: ein Rahmen um das Fenster, der aber eine kleine Lücke irgendwo hat...

Nach welchem Kriterium kann man also erkennen, dass das Polygon das Fenster tatsächlich so umschließt, das es, wenn das Polygon solide gezeichnet wird, solide ausgefüllt wäre?

PS: dass das Polygon komplett "wegclippt" wird, heißt nicht, dass das es auch das Fenster umschließt -> es kann ja auch "ganz links" oder "ganz oben" liegen, sodass es einfach verschwindet... Nur, wenn das Polygon wirklich um das Fenster herumliegt, muss man ein Viereck an der äußersten Pixelline des Fensters zeichenen...

gck
24-10-2002, 16:38
Weitere Frage wegen dem vermeintlichen Viereck ums Fenster, wenn das Polygon rumherumgeht:

da spieltv doch dann auch dieses Inside-Outside Problem bei Polygonen, die sich selbst schneiden, eine Rolle: zb: wenn das Sichtfenster genau in dieser kleinen Schnittfläche des Polygons auf Seite 125 im Buch liegt, dann wäre das Sichtfenster nach Odd-Even rule innerhalb, nach Non-Zero Winding Number rule aber außerhalb!! Was dann?

Kann vielleicht der Moderator da ein bissl klarheit bringen, er ist doch vom cg institut, oder?

Shade
26-10-2002, 23:11
ich glaub das in/outside problem wird erst bei der nächsten aufgabe (polygon filling) relevant sein.
was das mit den polygonen ganz ausserhalb ist weiss ich nicht.
da gäbs ja auch noch ein problem:
obs polygon ausserhalb das fenster umschließt oder nicht.
im ersten fall müßte man ja noch ein rechteck ums canvas zeichnen im 2. fall nicht...

Filz
27-10-2002, 22:09
Wenn das Polygon ausserhalb das Fenster umschließt, müßte man ja noch ein rechteck ums canvas zeichnen, sonst (im 2. fall) nicht...



Ich glaub es gibt noch weitere Fälle -> das wird ziemlich kompliziert zu berechnen werden. Zum Beispiel, wenn alle Punkte außerhalb des Canvas liegen, aber trotzdem eine Kante das Canvas-Fenster schneidet:

Das sollte zum Beispiel die linke obere Ecke (ab)schneiden:



ATOFF
4 1 1 0 1

-20.0 200.0 0.0 # vertices
-20.0 520.0 0.0
520.0 520.0 0.0
520.0 -20.0 0.0

0.0 0.0 1.0 # normal

255 255 0 # color

4 0 1 2 3 0 -1 0


Wie schaut das bei euch aus? Zeichnet er auch nichts?

Jeff_Mills
27-10-2002, 22:20
mit deinen vektoren wird bei mir auch nichts angezeigt


habt ihr schon eine lsg für das viereck, welches den canvas umrandet, gefunden ?

Filz
27-10-2002, 22:21
So sollte es dann "richtig" ausschauen :coolsmile:, bei mir ist allerdings alles schwarz. Hoff', ich hab mich nicht verprogrammiert.
http://stud4.tuwien.ac.at/~e0125924/test.jpg

Shade
27-10-2002, 22:32
bei mir klappts perfekt...
hab auch nicht irgendwelche zusätzlichen abfragen zum buch eingebaut...
http://stud3.tuwien.ac.at/~e0102853/Untitled.jpg

gck
27-10-2002, 23:43
@alle, bei denen filz sein atoff file nichts zeichnet:

vermutlich liegt euer "Fehler" bei der Vermeidung der NullPointerExcept. in closeClip(): wenn ihr versucht, die mit

if (cnt > 0) closeClip();

zu verhindern, kommt es bei filz seinem atoff zu einer ungünstigen Abarbeitungsreihenfolge der Vertices und ihr kriegt garnix raus (einfach am Papier ausprobieren, dann sehts ihr auch, weshalb: die ersten beiden Punkte, die betrachtet werden, sind (-20, 200), dann (-20, 520))

Lösung: statt der obigen Zeile die NullPointerExcep. mittels (if first[edge] != null) in closeClip() direkt abfangen... jetzt schaut es bei mir genauso aus wie beim Shade...

@einschließendes Polygon:
mit obigem "hack" klappt auch das natürlich!! (Ebenfalls am Papier ausprobieren, damit ihrs checkt!). Ich habe filz' atoff für so ein "einschließendes" Polygon zum Testen modifiziert, es sollte bei euch ein Rechteck um den Fensterrand zeichnen:

ATOFF
4 1 1 0 1

-20.0 -20.0 0.0 # vertices
-20.0 520.0 0.0
520.0 520.0 0.0
520.0 -20.0 0.0

0.0 0.0 1.0 # normal

255 255 0 # color

4 0 1 2 3 0 -1 0


hoffentlich passt jetzt so alles!

Jeff_Mills
28-10-2002, 00:13
wie meinst du das ?etwa so?

void closeclip(){

if(first[edge]!=null){

rest der proedur}

}

Shade
28-10-2002, 00:20
hmm,komisch bei klappen beide sachen (einschließendes&schneidendes polygon) auch mit dem normalen code...
beim einschließenden soll doch ein rand ums ganze canvas gezeichnet werden,oder?

Shade
28-10-2002, 00:21
klappt aber nicht wenn alle punkte ausserhalb sind.brauch doch ne abfrage...
aber reicht
if(first[edge]!=null)
da wird ja immer was ungleich "null" drinnen sein,oder?

Filz
28-10-2002, 00:28
Ich habs erst später einfach zum anderen IF dazugegeben...


for (int edge=0; edge<=3; edge++)
{
if ((first[edge] != null) && (cross(s[edge],first[edge],edge)))
{
iPt=intersect(.....................

gck
28-10-2002, 00:48
ja sorry, missverständlich ausgedrückt: es gehört natürlich genau so, wie es Filz gemacht hab, so hab ichs gemeint: die Schleife in closeClip muss ja trotzdem für alle edges laufen!

@Shade: nein, da muss nicht unbedingt was ungleich null drin sein: am Anfang ist bestimmt überall in first[edge] null drin: "aufgefüllt" wird das nur durch die rekursiven Aufrufe von clipPoint(): ganz am Anfang wird auf jeden Fall first[LEFT] auf den ersten Punkt gesetzt, aber angenommen, alle Punkte liegen schon außerhalb von LEFT, dann wird clipPoint nicht rekursiv erneut aufgerufen und first[RIGHT-BOTTOM] bleiben null!! D.h. wenn eine Kante gar nicht mehr betrachtet werden muss, weil schon alle Punkte an den vorherigen ausgeschieden sind, bleibt first[edge] für diese edge eben null... deshalb ist diese Abfrage nötig!

btw: falls es wem unklar sein sollte, warum man die abfrage unbedingt LINKS von dem cross() schreiben muss, ist deshalb, weil && nach dem Kurzschluss Verfahren arbeitet: wenn du a && b verwendest, und a schon false ist, wird b gar nicht mehr ausgewertet...
wenn ihr das first[edge] != 0 RECHTS von dem cross() Aufruf schreibt, bringt das genau nichts, weil ja a zuerst angeschaut wird und dann trotzdem die NullPointerException eintritt, die ihr vermeiden wolltet!!

Also unbedingt LINKS hinschreiben, genau wie in Filz' code!

Filz
28-10-2002, 00:54
(aus der Angabe)

Achtung: Im Buch wird, aus welchem Grund auch immer, davon ausgegangen, daß das Polygon zumindest teilweise sichtbar ist. Deswegen fehlt vor dem Aufruf von CloseClip() in der Methode clipPolygon() eine Abfrage. Wir wollen allerdings, daß auch komplett außerhalb des sichtbaren Bereichs liegende Polygone richtig geclippt werden.


Naja, selber schuld, wenn man sich zu sehr auf die Angabe verläßt - ich hab einen Tag lang nach diesem besch...euerten Fehler gesucht.:bounce:

Shade
28-10-2002, 01:01
ich steh wohl grad auf der leitung,aber WIESO funktioniert die abfrage : first[edge] != null; :confused:
ich mein es sthet doch deutlich in clipPoint:
if (first[edge]==null)
{first[edge] = point;}
damit sollte doch first[edge]nicht null werden können... theorethisch...

//edit:
habs dank erklärung verstanden :idea:

Bruno
28-10-2002, 01:02
Jepp, jetzt klappts! Herzlichen Dank!

Filz
28-10-2002, 01:45
Und zum Abschluss noch ein bisserl mehr Verwirrung... :eek2:

So ein Polygon sollte doch theoretisch ein leeres, absolut schwarzes Zeichenfenster ergeben? Macht es aber (zumindest bei mir) nicht -> der rechte Rand (511/0 bis 511/511) wird komplett durchgezeichnet.

Scheinbar muss man, wenn man den Stutherland ganz korrekt implementieren will, noch ein bisserl genauer arbeiten.

http://stud4.tuwien.ac.at/~e0125924/rundherum.jpg
Schwarz=Canvas; Orange=Außenbereich; Schweinchenrosa=Polygon


ATOFF
10 1 1 0 1

-50 -50 0
560 -50 0
560 560 0
-50 560 0
-50 0 0
-30 0 0
-30 530 0
530 530 0
530 -30 0
-50 -30 0


0.0 0.0 1.0 # normal

255 1 175 # color

10 0 1 2 3 4 5 6 7 8 9 0 -1 0


Wer sich damit rumärgern will, bitteschön, mir selbst reicht es jetzt langsam. :awake:

Bis zum BSP3!
Florian

dose
28-10-2002, 02:00
Wir wollen allerding, daß auch komplett außerhalb des sichtbaren Bereichs liegende Polygone richtig geclippt werden.

Doch was ist richtig, was ist falsch ? Du dachtest, alles wäre klar, Du hast viel zu spät gemerkt, daß es nur eine Lüge waaaar... :P

Ne, mich würd langsam echt mal interessieren, wie diese Spezialfälle "richtig" geclippt werden...

Jeff_Mills
28-10-2002, 08:39
@gck


obwohl ich die abfrage first[edge]!=null eingebaut habe passiert es: ArrayIndexOutofBound

und zwar bei der setPixen()methode

Jeff_Mills
28-10-2002, 08:58
protected void closeClip()
{

double[] temp = new double[2];
int edge=0;

for (edge = 0; edge <= TOP; edge++)
{
if (first[edge] != null&&cross(s[edge], first[edge], edge))
{
temp = intersect(s[edge], first[edge], edge);
if (edge < 3)
{
clipPoint(temp, (edge+1));
}
else
{
clipped[cnt][X] = (int)temp[0];
clipped[cnt][Y] = (int)temp[1];
cnt++;
}
}
}
}

wo versteckt sich der fehler?

wolk
28-10-2002, 10:11
in diesem code glaub ich nicht, dass der fehler steckt

sieh dir doch mal das array clipped an, wenn clip() fertig abgearbeitet wurde
wenns bei setpixel ein arrayoutofbounds kommt, dann steht im feld ein zu großer wert !!

mfg

MichiK
28-10-2002, 17:06
polygone, die das sichtfenster komplett umschließen, sollten vom algorithmus richtig behandelt werden, d.h. dieser fall braucht nicht gesondert behandelt zu werden.

gck
28-10-2002, 18:06
@MichiK:

Ja, die umschließenden Polygone sind jetzt kein Problem mehr, aber das, was der Filz da jetzt noch fabriziert hat, ist schon was anderes: meiner Meinung nach liegt der "Fehler" irgendwie im Algorithmus:

Das erste Mal, das es der Algorithmus zur edge 2 = BOTTOM schafft, fliegt dort (511,-50) raus und wird aber in s[edge] gespeichert....

Das nächste Mal kommen wir mit (511,560) bis zu BOTTOM, jetzt checkt der Algorithmus brav, dass BOTTOM zwischen den beiden Punkten geschnitten wird und reicht den Schnittpunkt (511,0) an den nächsten Clipper (TOP) weiter, wo (511,0) auch drinnen liegt und deshalb in die geclippte Vertexlist übernommen wird...

Meiner Meinung liegt deshalb der Fehler im Algorithmus, zumindest so, wie er im Buch ist... ich kann auch noch nicht mit dem Finger draufzeigen, was genau der Fehler ist, vielleicht weisst du es ja...

tschurlo
28-10-2002, 19:09
Ja, aber wieso wird dann bei der Aufgabenbeschreibung extra darauf hingewiesen, den Fall, dass das Polygon komplett auszerhalb liegt, zu beruecksichtigen, da er ihm Buch nicht behandelt wurde.

Lg,

gck
28-10-2002, 19:15
damit meinen sie aber die Nullpointer, die in first[edge] sein können und in closeClip eine Nullpointerexception werfen können... sie schreiben auch, wir sollen VOR closeClip Aufruf eine Abfrage schreiben, was nicht gut ist, weil ja selbst wenn alle Punkte außerhalb liegen, dennoch eine Kante durch das Window gehen kann....

Das atoff vom filz löst da einen anderen Fehler aus, der tiefer im Algorithmus liegt (hat auch nix mit closeClip zu tun!!)

Deep Thought
29-10-2002, 01:06
Ich glaube der Fehler hängt damit zusammen, dass ein Polygon, das primär draußen liegt, aber an zwei Stellen ins Fenster zeigt, mit einer Verbindungslinie geklippt wird (ich glaube mich an das erinnern zu können). In diesem Fall sind die zwei Austrittsstellen zwar nicht sichtbar, die Verbindungslinie wird aber trotzdem gezeichnet. Was eigentlich zu erwarten war.
Nur frage ich mich, warum dann die Linie unten nicht gezeichnet wird, für die nämlich dasselbe zutreffen würde.
Nun jetzt ist es sowieso schon zu spät für Änderungen...