Polygon Füller [Erledigt, Code im Anhang]

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

darth

Betreff: Polygon Füller [Erledigt, Code im Anhang]

BeitragSo, Jan 03, 2010 19:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ich brauche gerade eine Methode um Polygone (konkave und konvexe) zu füllen. Ich dachte mir ich schreibe einen Scanline-Algorithmus, das Prinzip ist so:

Code: [AUSKLAPPEN]
für jede Bildzeile:
   suche Schnittpunkte mit den Polygonkanten
   sortiere Schnittpunkte nach X Wert (aufsteigend, kleinster zuerst)

   füllen=false
   für jede Bildzeile:
      Schnittpunkt erreicht?
         füllen=!füllen (switch)
      füllen?
         zeichne Punkt


Funktioniert soweit prächtig, gibt allerdings Probleme, wenn nicht das ganze Polygon im Bildschirm ist, aber da kann man das Polygon "clippen" (mir fällt kein schönes Wort auf deutsch dazu ein) - das ist ein anderes Thema.

Mein Problem liegt hier (Erklärungsbild):
user posted image

Bei jedem Eckpunkt des Polygons habe ich immer zwei Schnittpunkte (einer von jeder Gerade). Das Problem hierbei ist, dass bei Punkt 0 und 1 brauche ich beide dieser Schnittpunkte (da das fill bei 0 von false zu false und bei 1 von true zu true wechseln muss, also einmal hin und einmal her). Bei 5 allerdings brauche ich nur einen, da dort das fill von false zu true wechseln muss.
Die Punkte 2, 3, 4 sind trivial, da nachher nichtsmehr kommt und der Algorithmus sowieso mit füllen aufhört.

Ich brauche jetzt eine Möglichkeit zu entscheiden, wann ich einen und wann ich zwei Schnittpunkte brauche. :/

Eine kleine Anmerkung: Die Durchgehensreihenfolge der Linien ist folgendermassen:
Code: [AUSKLAPPEN]
j=count
for i=0 to count
   line i,j
   j=i
next

Das bedeutet, der zweite Schnittpunkt für 1 wird bei i=2 (der erste bei i=1) gefunden und für 5 bei i=5 (der erste bei i=0). Es bringt also nichts, zu sehen ob der mittlere Punkt höhenmässig unter (bzw über) den beiden anderen liegt (weil der mittlere Punkt in beiden Fällen verschieden ist), das habe ich schon versucht.

Was ebenfalls nichts bringt ist, bei jedem doppelten Punkt fill einfach auf true zu setzen, das funktioniert zwar für 1 und 5, schlägt aber bei 0 fehl.

Was auch fehl schlägt ist, die Grenze der Linien für die Schnittpunkte zu "verkleinern", sprich, für:
Code: [AUSKLAPPEN]
Start + k * Vektor = Ziel

statt (k>=0 and k<=1) einfach (k>=0 and k<1) zu fordern funktioniert nicht.

Viel mehr Ideen sind mir bisher nicht eingefallen, ich hoffe jemand anderes hat eine Idee und kann mir weiterhelfen. Ich freue mich auf überlegte Vorschläge (wildes Raten bringt nichts, das habe ich schon selber probiert Razz).

MfG,
Darth
Diese Signatur ist leer.
  • Zuletzt bearbeitet von darth am Mo, Jan 04, 2010 15:07, insgesamt einmal bearbeitet

Holzchopf

Meisterpacker

BeitragSo, Jan 03, 2010 20:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Es bringt also nichts, zu sehen ob der mittlere Punkt höhenmässig unter (bzw über) den beiden anderen liegt (weil der mittlere Punkt in beiden Fällen verschieden ist), das habe ich schon versucht.
Das verstehe ich jetzt nicht, zugegebenermassen Confused Es wird doch wohl möglich sein, einen Punkt zu erkennen (also quasi die Berührung des Scans mit dem Linienende) und auch noch, zu welchen beiden Linien dieser Punkt gehört. Dann solltest du doch auch die jeweils anderen Endpunkte dieser Linien ermitteln können. Wenn beide dieser Endpunkte höhenmässig auf der selben Seite liegen, ist's ein Punkt, wo nicht umgeschaltet wird, andernfalls schon.
Das sollte doch klappen?
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm

darth

BeitragSo, Jan 03, 2010 21:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Scheint wohl missverständlich formuliert zu sein.
Das Problem ist zu eruieren, welcher der mittlere Punkt ist.

Man betrachte das Bild im ersten Post, die Scanlinie sei auf der Höhe von Punkt 1. Es gibt folgende Schnittpunkt Resultate (nach Reihenfolge der Entdeckung):
Code: [AUSKLAPPEN]
0-5
1-0
2-1
3-2

Die Punkte 1-0 und 2-1 sind die gleichen, man hat also einen Punkt in der Liste (1-0) und findet einen zweiten, der auf derselben Position ist (2-1), das geschieht also, bei i=2.
Der mittlere Punkt ist hier also 1, links ist 0 und rechts ist 2. Das bedeutet: Mitte = i-1

Sei nun die Scalinie auf Höhe von Punkt 5. Dann gibt es folgende Schnittpunkte (nach Reihenfolge der Entdeckung):
Code: [AUSKLAPPEN]
0-5
3-2
5-4

Hier sind die Punkte 0-5 und 5-4 die selben. Man hat den Punkt (0-5) in der Liste und findet nun (5-4) der an der selben Position ist, das ist bei i=5 der Fall.
Der mittlere Punkt ist hier 5, links ist 4, rechts ist 0. Das bedeutet: Mitte = i

Es zeigt sich also, dass der mittlere Punkt nicht immer nach dem selben Schema ermittelt werden kann, und das ist das Problem.
Ich speichere in den Schnittpunkten nicht, woher sie kommen, also kann ich nicht ermitteln, welcher Punkt in der Mitte liegt, und kann von daher den Ansatz mit der Höhe nicht weiterverfolgen.

Ich könnte natürlich dazu übergehen, die beiden Linienpunkte im Schnittpunkt zu speichern (und wenn alle Stricke reissen, werd ich das wohl tun müssen) - aber ich hoffe auf eine elegantere Lösung.

MfG,
Darth
Diese Signatur ist leer.

hectic

Sieger des IS Talentwettbewerb 2006

BeitragSo, Jan 03, 2010 22:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab überhaupt nicht ganz verstanden was du genau willst. Vielleicht würde ein Bild das zeigt wie es sein soll besser zur Verständlichkeit führen, als die ganzen Linien und Beschriftungen.

Aber eventuell ist eine Linienkollision das was du suchst. In so einem Fall nach Line Intersect suchen.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D
 

Kruemelator

BeitragSo, Jan 03, 2010 23:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich weis nich genau was du erreichen willst. Möchtest du aus den Punkten des konkaven Polygons einen konvexen Polygon erstellen welcher den konkaven umschließt?

Edit:
Ich glaube ich habe es jetzt verstanden! Very Happy
Es geht um soetwas wie Rect oder Oval.
Du könntest auch dein Polygon in mehrere Dreiecke unterteilen, das dürfte dann einfach gehen.

Midimaster

BeitragSo, Jan 03, 2010 23:41
Antworten mit Zitat
Benutzer-Profile anzeigen
ich hab das schon mal für ein ausmalspiel gebraucht. sieh mal unter floodfill in der blitzbasic.com nach.


Diese Routine läuft perfekt:

'Fill Routines
' Written By Paul Snart (Snarty) - Converted to BMax by klepto2 in Oct 2005
Link: http://www.blitzbasic.com/code...?code=1509

Silver_Knee

BeitragSo, Jan 03, 2010 23:47
Antworten mit Zitat
Benutzer-Profile anzeigen
wenn beide Linien eines Eckpunktes über ihm liegen fällt ein Schnittpunktpaar weg, liegen beide unter ihm kommt eins hinzu und liegt eins darüber und eins darunter gibts nix neues.

Bei waagerechten Linien kommt auch keins dazu.

Eingeproggt

BeitragSo, Jan 03, 2010 23:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmm... Ich glaub ihr unterschätzt darth alle ein wenig - ist ja nicht so dass er es nicht hinkriegen würde Dreiecke zu zeichnen... Er hat da seine eigene Füllmethode wie im ersten Post beschrieben und dort steht er vor dem Problem was er machen soll wenn sein Füllalgo genau auf einen Eckpunkt trifft - wo ja 2 Linien aufeinander treffen.
Da würde seine Methode 2 mal "anschlagen" - den fillmode von False auf true und sofort wieder auf false ändern obwohl er im Falle des Punkt 5 in seiner Skizze ja dann innerhalb des polygons wäre und eigentlich füllen müsste.

So hab ichs verstanden - ne Lösung hab ich dafür leider nicht, Sorry Darth Sad
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

Silver_Knee

BeitragSo, Jan 03, 2010 23:54
Antworten mit Zitat
Benutzer-Profile anzeigen
achso zeichne doch einfach durch wenn du genau auf nen punkt triffst... dh du gehst alle punkte durch und wenn du einen punkt in der aktuellen zeile erwischt musst du einfach alle lienien die von diesem unkt ausgehen ignorieren (die enden ja eh dort), dann passiert auch nix mit an aus usw

Goodjee

BeitragSo, Jan 03, 2010 23:55
Antworten mit Zitat
Benutzer-Profile anzeigen
könnte es helfen, die scanlines um 0.5 pixel nach oben/unten zu verschieben, wenn die punkte alle genau auf einem pixel liegen?

dann wird kein punkt mehr getroffen sondern nurnoch linien
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/

darth

BeitragMo, Jan 04, 2010 0:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

danke für die vielen Vorschläge. Hier meine Antworten Razz:

@Hectic:
user posted image
Siehst du die kleine schwarze Linie im weissen Bereich? Die müsste weg. Ich habe dort zwei Schnittpunkte, darum wird von nicht füllen zu nicht füllen gewechselt. Wäre da nur einer (und dazu bräuchte ich ein Auswahlkriterium, wann nehm ich einen, wann nehm ich zwei), würde es funktionieren.
Den Lineintersect habe ich bereits implementiert, der ist nicht das Problem, das Problem ist eher: WELCHE Schnittpunkte akzeptiere ich für meine Liste?

@Kruemelator:
Ich habe eine Routine um das ganze in Dreiecke zu zerlegen. Ich habe sogar eine Routine, um das Ding in konvexe Polygone zu unterteilen, bei denen würde der Algorithmus übrigens wunderbar funktionieren.
Das Problem ist, dass ich das nicht unbedingt möchte.. Ich suche einen Algorithmus, der für beliebige Polygone funktioniert, ohne irgendwelche Zerteilungen (Geschwindigkeitsfrage).

@Midimaster:
Danke für die Empfehlung. Einen Floodfill habe ich bereits ausprobiert. Das Problem dabei ist die Geschwindigkeit. Floodfill ist enorm aufwändig und eigentlich ein ziemlich schlechter Algorithmus. Der Linesearch Ansatz ist ziemlich viel schneller, deshalb möchte ich diesen verwenden.

@Silver_Knee:
Ich verstehe nicht ganz was du meinst, tut mir leid. Wie können Linien über einem Punkt sein? Meinst du, dass die Endpunkte der Linien die in diesem Schnittpunkt münden über dem Punkt sein müssten (oder untendran?)
Falls ja, dann muss ich leider sagen, dass das so nicht funktioniert (jedenfalls nicht in der jetzigen Implementation), Grund dazu ist die fehlende Speicherung der Linienkomponenten im Schnittpunkt, siehe meinen 2. Post als Antwort auf Holzchopf.

@Eingeproggt:
Ja, du hast das Prinzip verstanden Smile Schade dass du keine Lösung weisst.

@Silver_Knee:
Wenn ich bei Eckpunkten einfach weiterzeichne, dann zeichne ich auch bei der Ecke 0 weiter, und ich habe eine Linie die durch die Leere führt, das funktioniert leider auch nicht.

@Goodjee:
Ich rechne wenn ich mit Pixeln arbeite eigentlich generell mit Integern, da hat es keine Auswirkung (ausser einem ++) den Punkt um 0.5 zu verschieben. Selbst wenn es funktionieren würde, wüsste ich nicht, wo ich jetzt zeichnen soll.. zwischen Pixeln kann man keine Pixel setzen.

Wie die Dinge stehen habe ich immernoch keine Ahnung wie ich meine Füllroutine korrigieren soll Very Happy
Ich hoffe immernoch auf eine Lösung,

MfG,
Darth
Diese Signatur ist leer.

Midimaster

BeitragMo, Jan 04, 2010 0:14
Antworten mit Zitat
Benutzer-Profile anzeigen
du schreibst "einen floodfill..." Diesen? Wir verwenden ihn in unseren kommerziellen Produkten, er hatte uns echt überzeugt.

Ich kann dir jetzt aber nicht mehr über die Performance sagen, is schon zu lang her.

Hier kannst du ihn beim Arbeiten zuschauen:

http://www.midimaster.de/downl...smalen.exe

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMo, Jan 04, 2010 0:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Nur eine Idee.

Eventuell könnte man eine jede Polygonposition mit ~+0.1 berechnen. Wenn die Eckpunkte dann mit der Füllinie schneiden, käme es zu solchen ''Fehlberechnungen'' nicht mehr. Hängt aber auch davon ab, wie das ganze berechnet wird.

Edit1: Ok, Goodjee hat das gleiche Beispiel gebracht. Aber trotz Integer kann man Floatwerte zur Berechnung einbeziehen. Und soweit mir bekannt ist, kommen auch Divisionen in einer LinesIntersecs-Funktion vor, von daher hast su schon zwagsweise eine Float-Berechnung.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D
  • Zuletzt bearbeitet von hectic am Mo, Jan 04, 2010 0:22, insgesamt einmal bearbeitet

darth

BeitragMo, Jan 04, 2010 0:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Midimaster,

ich habe einen Floodfill programmiert. Wie ich sehe ist die von dir gepostete Methode nicht rekursiv wie meine, das macht sie schon einmal schneller (und besser) als meine Version. Das Problem ist, dass Floodfill generell den Befehl Readpixel benötigt, der nicht der schnellste ist.
Zum Füllen muss ich schon Writepixel verwenden (bzw WPFast), was mir auch schon nicht gefällt - aber unumgänglich ist (weil es keine andere Alternative gibt Pixel zu setzen :> ), aber zusätzlich zu dem noch überall Readpixel (oder RPFast) zu benutzen macht das ganze System nicht schneller.

Zusätzlich kann ich bei meiner Routine leere Stücke überspringen. Floodfill hat das Problem nicht, da fängt man irgendwo in der Mitte an, aber man muss trotzdem sukzessiv durchsuchen, wo man setzen soll. Mit meinem Scanline Ansatz kann ich BERECHNEN wo ich setzen muss und dann muss ich die nur noch durchgehen.

Floodfill kann zwar gut genug für die Benutzung implementiert werden, es bleibt aber ein eher langsamer, schlechter Ansatz den man nicht unbedingt verwenden sollte, wenn man die Geschwindigkeit optimieren möchte.

MfG,
Darth

[EDIT:]

Hallo nochmal,

ich schulde dem lieben Goodjee eine Entschuldigung. Entschuldigung!
Wenn ich den Y-Wert für meine Schnittberechnung nicht direkt aus dem Y-Wert des Punktes wähle, sondern PY=Polygon\Punkt[i]\Y-0.1 dann tritt das Problem nicht auf.

Danke auch an Noobody der mich darauf aufmerksam gemacht hat dass ich doch nicht durchgehend mit Integern arbeite und es so funktioniert.

Somit wäre das Problem gelöst, Thema beendet, Darth glücklich.

MfG,
Darth
Diese Signatur ist leer.

Silver_Knee

BeitragMo, Jan 04, 2010 12:24
Antworten mit Zitat
Benutzer-Profile anzeigen
also zumindest writepiel kannste umgehen
du zeichnest ja nur lienien. Also kannst du Rect x,y,xend-x,1 nutzen, das dürfte schneller sein... Ich glaub wenn das unausgefüllt (bei einem Pixel eh egal) isses glaub noch schneller.. Vor allem bei langen Linien.

darth

BeitragMo, Jan 04, 2010 14:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Silver_Knee,

im Lockbuffer Modus ist Line wesentlich schneller als Rect soweit ich weiss. Aber die Pixel durch Linien zu ersetzen wäre eine gute Idee, mal sehn ob das schneller kommt als die einzelnen Punkte.

MfG,
Darth

[Edit:]

Begründet darauf:
BlitzBasic: [AUSKLAPPEN]
Graphics 800,600,0,2
SetBuffer BackBuffer()

Function FillScreen1()
LockBuffer BackBuffer()

For x=0 To GraphicsWidth()-1
For y=0 To GraphicsHeight()-1
WritePixelFast x,y,$ffffff
Next
Next

UnlockBuffer BackBuffer()
End Function

Function FillScreen2()
LockBuffer BackBuffer()

width=GraphicsWidth()-1
For y=0 To GraphicsHeight()-1
Line 0,y,width,y
Next

UnlockBuffer BackBuffer()
End Function

While Not KeyHit(1)
If MouseHit(1)
mode=Not mode
EndIf

If mode
FillScreen1()
Else
FillScreen2()
EndIf

Color 255,0,0
fps=fps+1
If MilliSecs()-fpstime>999
fpscur=fps
fps=0
fpstime=MilliSecs()
EndIf
Text 10,10,fpscur
If mode
Text 10,30,"WPF"
Else
Text 10,30,"Line"
EndIf
Color 255,255,255

Flip 0
Cls
Wend
End

Habe ich das Ding auf Line umgestellt, läuft jetzt nochmal schneller \o/
  • Zuletzt bearbeitet von darth am Mo, Jan 04, 2010 15:00, insgesamt einmal bearbeitet
 

Kruemelator

BeitragMo, Jan 04, 2010 14:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn der vorherige und der folgende Punkt jeweils beide über oder unter dem zu prüfenden Punkt liegen, dann dann bleibt es so wie es ist.

Gruß Kruemelator

darth

BeitragMo, Jan 04, 2010 15:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Kruemelator,

Deine Antwort funktioniert in der Theorie, ist aber praktisch nicht umsetzbar, weil ich in den Punkten nicht speicher woher sie kommen.
Das Problem lässt sich aber lösen, wenn ich die Punkte um 0.1 verschiebe, dann liegen sie nicht direkt auf der Scanlinie und ich hab das Problem mit dem doppelten Schnittpunkt gar nicht.

---

Um weitere Unklarheiten zu vermeiden, stelle ich mal kurzerhand den fertigen Code hier rein (und werde wahrscheinlich den Threadtitel editieren):
BlitzBasic: [AUSKLAPPEN]
Type Vector
Field X#
Field Y#

Field used
End Type

Type Polygon
Field P.Vector[64]
Field count
End Type

Function cVector.Vector(x#, y#)
Local V.Vector

V=New Vector
V\X=x
V\Y=y

Return V
End Function

Function ClipPoly(P.Polygon)
Local Width, Vnew.Vector, PX#, PY#, DX#, DY#, k#, PnewY

Width=GraphicsWidth()

j=P\count-1
For i=0 To P\count-1
If Not (P\P[i]\X<0 And P\P[j]\X<0)
PX=P\P[i]\X
PY=P\P[i]\Y

DX=P\P[j]\X-P\P[i]\X
DY=P\P[j]\Y-P\P[i]\Y

k=-PX/DX
If k>0 And k<1
PnewY=PY+k*DY

Vnew=cVector(1,PnewY)

InsertPointToPoly(P, Vnew, j+1)

If i<>0
i=i+1
EndIf
EndIf

k=(Width-PX)/DX
If k>0 And k<1
PnewX=PX+k*DX
PnewY=PY+k*DY

Vnew=cVector(Width-1,PnewY)

InsertPointToPoly(P, Vnew, j+1)

If i<>0
i=i+1
EndIf
EndIf
EndIf

j=i
Next

For i=0 To P\count-1
If P\P[i]\X<0 Or P\P[i]\X>Width
RemovePointFromPoly(P, i)
i=i-1
EndIf
Next
End Function

Function InsertPointToPoly(P.Polygon, V.Vector, i)
If P\count=64
Return ;error!
EndIf

For j=P\count-1 To i Step -1
P\P[j+1]=P\P[j]
Next
P\P[i]=V

P\count=P\count+1
End Function

Function RemovePointFromPoly(P.Polygon, i)
If P\count=0
Return ;error!
EndIf

For j=i+1 To P\count-1
P\P[j-1]=P\P[j]
Next
P\P[P\count-1]=Null

P\count=P\count-1
End Function

Type LList
Field X

Field Succ.LList
End Type

Function FillPoly(P.Polygon, RGB)
Local MinX#, MinY#, MaxX#, MaxY#, SX#, SY#, DX#, PX#, PY#, VX#, VY#, k#, CX#, Fill
Local LStart.LList, LIter.LList, Tmp.LList

r=(RGB And $FF0000)/$10000
g=(RGB And $FF00)/$100
b=RGB And $FF
Color r,g,b

MinX=GraphicsWidth()
MinY=GraphicsHeight()
MaxX=0
MaxY=0

For i=0 To P\count-1
If P\P[i]\X<MinX
MinX=P\P[i]\X
EndIf
If P\P[i]\X>MaxX
MaxX=P\P[i]\X
EndIf

If P\P[i]\Y<MinY
MinY=P\P[i]\Y
EndIf
If P\P[i]\Y>MaxY
MaxY=P\P[i]\Y
EndIf
Next

MaxX=Min(GraphicsWidth(),MaxX)
MaxY=Min(GraphicsHeight(),MaxY)

MinX=Max(0,MinX)
MinY=Max(0,MinY)

For SY=MinY+1 To MaxY
Delete Each LList
Fill=0

SX=MinX

DX=MaxX-MinX

j=P\count-1
For i=0 To P\count-1
PX=P\P[i]\X
PY=P\P[i]\Y+0.1

VX=P\P[j]\X-P\P[i]\X
VY=P\P[j]\Y-P\P[i]\Y

If VY<>0
k=(SY-PY)/VY
If k>=0 And k<=1
CX=PX+k*VX

k=(CX-SX)/DX
If k>=0 And k<=1
CX=Int(CX)

If LStart=Null
LStart=New LList
LStart\X=CX
Else
If CX<LStart\X
Tmp=LStart

LStart=New LList
LStart\X=CX
LStart\Succ=Tmp
Else
LIter=LStart
While LIter<>Null
If Int(CX)=LIter\X
Tmp=LIter\Succ

LIter\Succ=New LList
LIter\Succ\X=CX
LIter\Succ\Succ=Tmp

Exit
Else
If CX>LIter\X
If LIter\Succ<>Null
If CX<LIter\Succ\X
Tmp=LIter\Succ

LIter\Succ=New LList
LIter\Succ\X=CX
LIter\Succ\Succ=Tmp

Exit
EndIf
Else
LIter\Succ=New LList
LIter\Succ\X=CX

Exit
EndIf
EndIf
EndIf

LIter=LIter\Succ
Wend
EndIf
EndIf
EndIf
EndIf
EndIf

j=i
Next

LIter=LStart
If LIter<>Null
While LIter\Succ<>Null
Line LIter\X,SY,LIter\Succ\X,SY
LIter=LIter\Succ\Succ

If LIter=Null
Exit
EndIf
Wend
EndIf

;LIter=LStart
;If LIter<>Null
; For SX=Int(LIter\X) To MaxX
; If LIter\Succ<>Null
; If SX>LIter\X
; Fill=1-Fill
;
; LIter=LIter\Succ
;
; If LIter<>Null
; If Not Fill
; SX=LIter\X-1
; EndIf
; Else
; Exit
; EndIf
; EndIf
; Else
; If SX>LIter\X
; Exit
; EndIf
; EndIf
;
; If Fill
; WritePixelFast SX,SY,RGB
; EndIf
; Next
;EndIf
Next

Delete Each LList
End Function

Function DrawPolys()
Local P.Polygon, Tmp.Polygon

LockBuffer BackBuffer()

Color 255,0,0
For P.Polygon=Each Polygon
Tmp.Polygon=New Polygon
For i=0 To P\count-1
Tmp\P[i]=cVector(P\P[i]\X,P\P[i]\Y)
Next
Tmp\count=P\count

ClipPoly(Tmp)
FillPoly(Tmp, $ffffff)
DrawOutLine(Tmp, 255, 0, 0)

Delete Tmp
Next

UnlockBuffer BackBuffer()
End Function

Function DrawOutLine(P.Polygon, R, G, B)
Color R,G,B

j=P\count-1
For i=0 To P\count-1
Line P\P[i]\X,P\P[i]\Y,P\P[j]\X,P\P[j]\Y

j=i
Next
End Function

Function Max#(A#,B#)
If A>B
Return A
Else
Return B
EndIf
End Function

Function Min#(A#,B#)
If A<B
Return A
Else
Return B
EndIf
End Function

Graphics 800,600,0,2
SetBuffer BackBuffer()

Local Test.Polygon, DX, DY

Test.Polygon=New Polygon
Test\P[0]=cVector(300,200)
Test\P[1]=cVector(400,250)
Test\P[2]=cVector(520,160)
Test\P[3]=cVector(375,350)
Test\P[4]=cVector(200,450)
Test\P[5]=cVector(350,325)
Test\count=6

For i=0 To 5
Test\P[i]\X=Test\P[i]\X
Next

While Not KeyHit(1)
DrawPolys()

Text 100,10,Test\P[0]\X

Color 0,255,0
;Line 0,250,800,250
Color 255,255,255

DX=KeyDown(205)-KeyDown(203)
DY=KeyDown(208)-KeyDown(200)
For i=0 To Test\count-1
Test\P[i]\X=Test\P[i]\X+DX
Test\P[i]\Y=Test\P[i]\Y+DY
Next

fps=fps+1
If MilliSecs()-fpstime>999
fpscur=fps
fps=0
fpstime=MilliSecs()
EndIf
Text 10,10,fpscur

Flip 0
Cls
Wend
End

Der Code ist zur freien Verwendung freigegeben. Sollte euer Computer im Laufe der Benutzung explodieren weise ich jede Schuld von mir. Gebrauch auf eigene Gefahr!

MfG,
Darth
Diese Signatur ist leer.

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group