Fläche in Dreiecke aufteilen

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

TheShadow

Moderator

Betreff: Fläche in Dreiecke aufteilen

BeitragDi, Jul 06, 2004 21:49
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMi, Jul 07, 2004 15:01
Antworten mit Zitat
Benutzer-Profile anzeigen
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.. Smile

TheShadow

Moderator

BeitragMi, Jul 07, 2004 17:32
Antworten mit Zitat
Benutzer-Profile anzeigen
kannst du mal screenshot machen oder so....
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2

TheShadow

Moderator

BeitragMi, Jul 07, 2004 19:38
Antworten mit Zitat
Benutzer-Profile anzeigen
also bei mir geht es ganz gut: Wie gesagt darf es keine Überschneidung geben oder Punktüberlagerung...

user posted image
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2

ChrisAttack

BeitragMi, Jul 07, 2004 19:43
Antworten mit Zitat
Benutzer-Profile anzeigen
wow, nicht schlecht shadow. ich krieg das nicht hin Wink
B3D
MSVC++
DX9SDK

Triton

BeitragMi, Jul 07, 2004 20:32
Antworten mit Zitat
Benutzer-Profile anzeigen
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..

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group