gefülltes Dreieck inklusive clipping

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
SoS
Beiträge: 340
Registriert: 29.08.2004 09:31
Kontaktdaten:

gefülltes Dreieck inklusive clipping

Beitrag von SoS »

Da ich hier soetwas noch nicht gefunden habe ,poste ich es einfach mal.
Sollte auch unter Linux und MacOS laufen.

Code: Alles auswählen

Structure clip
  X1.l
  Y1.l
  X2.l
  Y2.l
EndStructure

Global Clip.clip

Procedure fill_triangle(X1.l, Y1.l, X2.l, Y2.l, X3.l, Y3.l, C.l)

  Define.l X, Y, XA, XB


  If Y1 > Y2
    fill_triangle(X2, Y2, X1, Y1, X3, Y3, C)
    ProcedureReturn
  EndIf

  If Y2 > Y3
    fill_triangle(X1, Y1, X3, Y3, X2, Y2, C)
    ProcedureReturn
  EndIf

  X1 << 3
  X2 << 3
  X3 << 3

  If Y1 < Clip\Y1:Y1 = Clip\Y1:EndIf
  If Y3 > Clip\Y2:Y3 = Clip\Y2:EndIf
  
  For Y = Y1 To Y3

    If Y <= Y2

      If (Y1 = Y2): XA = X2 : Else :XA = X1 + (X2 - X1) * (Y - Y1) / (Y2 - Y1):EndIf
      If (Y1 = Y3): XB = X3 : Else :XB = X1 + (X3 - X1) * (Y - Y1) / (Y3 - Y1):EndIf

    Else

      If (Y3 = Y2) :XA = X2 :Else : XA = X3 + (X2 - X3) * (Y - Y3) / (Y2 - Y3):EndIf
      If (Y3 = Y1) :XB = X1 :Else : XB = X3 + (X1 - X3) * (Y - Y3) / (Y1 - Y3):EndIf
      
    EndIf

    If(XB < XA)
      Swap XB, XA
    EndIf
    

    XA = (XA + 2) >> 3
    XB = (XB - 2) >> 3

    If(XB < Clip\X1) Or (XA > Clip\X2): Continue:EndIf
    If(XA < Clip\X1): XA = Clip\X1:EndIf
    If(XB > Clip\X2): XB = Clip\X2:EndIf

    For X = XA To XB
      Plot(X, Y, C)
    Next
    
  Next
EndProcedure



OpenWindow(0, 0, 0, 640, 480, "fill_triangle", #PB_Window_SystemMenu)

CreateImage(0, 640, 480)

ImageGadget(0, 0, 0, 640, 480, ImageID(0))

Clip\X1 = 50
Clip\Y1 = 50
Clip\X2 = 589
Clip\Y2 = 429

Ende    = #False

Repeat

  Event = WaitWindowEvent(20)

  StartDrawing(ImageOutput(0))
  fill_triangle(Random(840) - 100, Random(680) - 100, Random(840) - 100, Random(680) - 100, Random(840) - 100, Random(680) - 100, Random(#White))
  StopDrawing()
  
  SetGadgetState(0, ImageID(0))
  
  Select Event
    Case #PB_Event_CloseWindow
      Ende = #True
  EndSelect
Until Ende
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: gefülltes Dreieck inklusive clipping

Beitrag von NicTheQuick »

Funktioniert wunderbar. Aber damit es auch unter Linux läuft, musst du die Konstante #White durch $FFFFFF ersetzen, da dies eine Windows-API-Konstante ist.
Benutzeravatar
Vera
Beiträge: 928
Registriert: 18.03.2009 14:47
Computerausstattung: Win XP SP2, Suse 11.1
Wohnort: Essen

Re: gefülltes Dreieck inklusive clipping

Beitrag von Vera »

ja wie g**l ist das denn :lol:

siehe aktuell im engischen Forum: All OS Filled Polygon

Darf ich Dein Beispiel dort auch verlinken ?

Danke ~ Vera
°
<°)))o><
~~~~~~~~~
echo "Don't worry"
echo "Keep quiet"
@echo off
format forum:\
Benutzeravatar
SoS
Beiträge: 340
Registriert: 29.08.2004 09:31
Kontaktdaten:

Re: gefülltes Dreieck inklusive clipping

Beitrag von SoS »

NicTheQuick hat geschrieben:Funktioniert wunderbar. Aber damit es auch unter Linux läuft, musst du die Konstante #White durch $FFFFFF ersetzen, da dies eine Windows-API-Konstante ist.
Sorry,war schreibfaul und hab auf RGB() verzichtet. :mrgreen:
Vera hat geschrieben:Darf ich Dein Beispiel dort auch verlinken ?
Hab nix dagegen
Benutzeravatar
Hyper
Beiträge: 194
Registriert: 19.04.2005 19:14

Re: gefülltes Dreieck inklusive clipping

Beitrag von Hyper »

Ja super, so etwas hatte ich schon mal gebraucht, hab mir dann selbst was geschrieben, aber Deines ist viel besser!
PB 5.72
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: gefülltes Dreieck inklusive clipping

Beitrag von STARGÅTE »

Wenn es nur um zu füllende Dreiecke geht (also konvexe Polygone), dann würde doch das Zeichnen von 3 Lines mit anschließendem FillArea() reichen oder ?
Selbst wenn man mehrere gleichfarbige Dreicke übereinander zeichnet, könnte man diese erst mit einer Temp-Farbe konstruieren, füllen und dann die echten Lines ziehen (damit es kein Rand-Farben-Konflikt gibt)

Ich weiß allerdings nicht wie schnell das FillArea() im verlgeich zum Pixeln ist.
Da du ja keine Randfarbe überprüfst, ist deins vermutlich schneller...
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
SoS
Beiträge: 340
Registriert: 29.08.2004 09:31
Kontaktdaten:

Re: gefülltes Dreieck inklusive clipping

Beitrag von SoS »

STARGÅTE hat geschrieben:Wenn es nur um zu füllende Dreiecke geht (also konvexe Polygone), dann würde doch das Zeichnen von 3 Lines mit anschließendem FillArea() reichen oder ?
Nein,mir gehts hier um Flexibilität.
In meinem Programm schreibe ich z.b. den Pixel direkt in den Speicher und da hilft mir FillArea() nicht weiter.
Weiterhin kann jeder die Prozedur erweitern um z.b. jedem Pixel eine eigene Farbe zuweisen oder Texturen oder...
Antworten