Fläche in Dreiecke aufteilen
Übersicht

![]() |
TheShadowModeratorBetreff: Fläche in Dreiecke aufteilen |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ein altes Problem: man hat eine Fläche und diese möchte man in Dreiecke aufteilen - z.B. um dann Flächeninhalt zu berechnen oder um zu Prüfen ob ein Punkt in der Fläche liegt...
Hier habe ich so ein Programm. Einfach paar Punkte aufmalen und es berechnet die ganzen Dreiecke. Linienkreuzungen oder Punkte die übereinander liegen erzeugen noch eine "fehlerhafte" Fläche (weil ich es nicht einprogrammiert habe) testet mal ob es sonst gut funzt... Code: [AUSKLAPPEN] Type area
Field i Field x Field y End Type Graphics 640,480,0,2 SetBuffer BackBuffer() bank1=CreateBank(0) While Not KeyHit(1) If MouseHit(1)=1 Then x=MouseX() y=MouseY() area_add(bank1,x,y) bank2=area_split(bank1) Cls area_draw(bank1,bank2) Flip If bank2<>0 Then FreeBank bank2 EndIf Wend ;--------------------------------------------------------------------- ;bank: area bank handle ;x: new area point x ;y: new area point y ;--------------------------------------------------------------------- Function area_add(bank,x,y) If bank=0 Then Return size=BankSize(bank) ResizeBank bank,size+8 PokeInt bank,size+0,x PokeInt bank,size+4,y End Function ;--------------------------------------------------------------------- ;x1,y1: point 1 ;x2,y2: point 2 ;x3,y3: point 3 ;RETURN: <0=anticlockwise ; >0=clockwise ;--------------------------------------------------------------------- Function area_clockwise(x1,y1,x2,y2,x3,y3) Return (x2-x1)*(y3-y2)-(x3-x2)*(y2-y1) End Function ;--------------------------------------------------------------------- ;bank1: bank handle with area points ;bank2: bank handle with trangle list ;--------------------------------------------------------------------- Function area_draw(bank1,bank2) If bank2<>0 Then Color 160,160,160 count=BankSize(bank2)/24 For i=1 To count x1=PeekInt(bank2,i*24-24) y1=PeekInt(bank2,i*24-20) x2=PeekInt(bank2,i*24-16) y2=PeekInt(bank2,i*24-12) x3=PeekInt(bank2,i*24-08) y3=PeekInt(bank2,i*24-04) Line x1,y1,x2,y2 Line x2,y2,x3,y3 Line x3,y3,x1,y1 Next EndIf If bank1<>0 Then Color 255,255,255 count=BankSize(bank1)/8 For i=1 To count If i=count Then j=1 Else j=i+1 x1=PeekInt(bank1,i*8-8) y1=PeekInt(bank1,i*8-4) x2=PeekInt(bank1,j*8-8) y2=PeekInt(bank1,j*8-4) Line x1,y1,x2,y2 Next EndIf End Function ;--------------------------------------------------------------------- ;px,py: point ;x1,y1: point 1 ;x2,y2: point 2 ;x3,y3: point 3 ;RETURN: 1=point in triangle ;NOTE: only for clockwise triangle ;--------------------------------------------------------------------- Function area_pointintri(px,py,x1,y1,x2,y2,x3,y3) If area_clockwise(x1,y1,x2,y2,px,py)=>0 Then If area_clockwise(x2,y2,x3,y3,px,py)=>0 Then If area_clockwise(x3,y3,x1,y1,px,py)=>0 Then Return 1 EndIf EndIf End Function ;--------------------------------------------------------------------- ;bank: area bank handle ;RETURN: new bank handle with trangle list ;--------------------------------------------------------------------- Function area_split(bank) If bank=0 Then Return value=area_split_left(bank) If value<>0 Then Return value value=area_split_right(bank) If value<>0 Then Return value End Function ;--------------------------------------------------------------------- ;bank: area bank handle ;RETURN: new bank handle with trangle list ;--------------------------------------------------------------------- Function area_split_left(bank) Local area.area Local area1.area Local area2.area Local area3.area count=BankSize(bank)/8 If count<3 Then Return Delete Each area For i=1 To count area=New area area\i=i area\x=PeekInt(bank,i*8-8) area\y=PeekInt(bank,i*8-4) Next area1=First area tri=CreateBank(0) Repeat area1=After area1 If area1=Null Then area1=First area area2=After area1 If area2=Null Then area2=First area area3=After area2 If area3=Null Then area3=First area If area1=area2 Or area1=area3 Or area2=area3 Then Return tri If area_clockwise(area1\x,area1\y,area3\x,area3\y,area2\x,area2\y)>0 Then For area=Each area If area\i<>area1\i And area\i<>area2\i And area\i<>area3\i Then If area_pointintri(area\x,area\y,area1\x,area1\y,area3\x,area3\y,area2\x,area2\y)=1 Then Goto skip EndIf Next size=BankSize(tri) ResizeBank tri,size+24 PokeInt tri,size+00,area1\x PokeInt tri,size+04,area1\y PokeInt tri,size+08,area2\x PokeInt tri,size+12,area2\y PokeInt tri,size+16,area3\x PokeInt tri,size+20,area3\y Delete area2 lasti=0 Else .skip If lasti=area1\i Then FreeBank tri : Return If lasti=0 Then lasti=area1\i EndIf Forever End Function ;--------------------------------------------------------------------- ;bank: area bank handle ;RETURN: new bank handle with trangle list ;--------------------------------------------------------------------- Function area_split_right(bank) Local area.area Local area1.area Local area2.area Local area3.area count=BankSize(bank)/8 If count<3 Then Return Delete Each area For i=1 To count area=New area area\i=i area\x=PeekInt(bank,i*8-8) area\y=PeekInt(bank,i*8-4) Next area1=First area tri=CreateBank(0) Repeat area1=After area1 If area1=Null Then area1=First area area2=After area1 If area2=Null Then area2=First area area3=After area2 If area3=Null Then area3=First area If area1=area2 Or area1=area3 Or area2=area3 Then Return tri If area_clockwise(area1\x,area1\y,area2\x,area2\y,area3\x,area3\y)>0 Then For area=Each area If area\i<>area1\i And area\i<>area2\i And area\i<>area3\i Then If area_pointintri(area\x,area\y,area1\x,area1\y,area2\x,area2\y,area3\x,area3\y)=1 Then Goto skip EndIf Next size=BankSize(tri) ResizeBank tri,size+24 PokeInt tri,size+00,area1\x PokeInt tri,size+04,area1\y PokeInt tri,size+08,area2\x PokeInt tri,size+12,area2\y PokeInt tri,size+16,area3\x PokeInt tri,size+20,area3\y Delete area2 lasti=0 Else .skip If lasti=area1\i Then FreeBank tri : Return If lasti=0 Then lasti=area1\i EndIf Forever End Function |
||
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2 |
![]() |
Triton |
![]() Antworten mit Zitat ![]() |
---|---|---|
bei einfachen, konvexen Objekten funktioniert es einwandfrei, konkav macht allerdings probleme.
Wenn man neue Punkte auf einer Kurve setzt und die kurvenrichtung ändert, gibts manchmal auch probleme. Hm, lässt sich schwer beschreiben, wann es probleme gibt und wann nciht, auf jeden Fall ein interessantes Programm.. ![]() |
||
![]() |
TheShadowModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
kannst du mal screenshot machen oder so.... | ||
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2 |
![]() |
TheShadowModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
also bei mir geht es ganz gut: Wie gesagt darf es keine Überschneidung geben oder Punktüberlagerung...
![]() |
||
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2 |
![]() |
ChrisAttack |
![]() Antworten mit Zitat ![]() |
---|---|---|
wow, nicht schlecht shadow. ich krieg das nicht hin ![]() |
||
B3D
MSVC++ DX9SDK |
![]() |
Triton |
![]() Antworten mit Zitat ![]() |
---|---|---|
TheShadow hat Folgendes geschrieben: also bei mir geht es ganz gut: Wie gesagt darf es keine Überschneidung geben oder Punktüberlagerung...
hmm, dann hab ich das wohl nicht genau beachtet, funktioniert sonst einwandfrei.. |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group