Reckteck mit gerundeten Ecken zeichnen

Anfängerfragen zum Programmieren mit PureBasic.
PMTheQuick
Beiträge: 630
Registriert: 05.05.2005 19:06

Reckteck mit gerundeten Ecken zeichnen

Beitrag von PMTheQuick »

Hi,

wie kann ich am besten ein Rechteck mit gerundeten Ecken zeichnen? Habe irgendwie nichts gefunden. Sorry, falls ich irgendetwas übersehen habe. (Suche oder so ;) ) Danke im vorraus für eure Antwort,

Gruss
PMTheQuick ;)
Riacon
Beiträge: 61
Registriert: 21.01.2008 09:40

Beitrag von Riacon »

marco2007
Beiträge: 906
Registriert: 26.10.2006 13:19
Kontaktdaten:

Beitrag von marco2007 »

Irgendwie so:

Code: Alles auswählen

InitSprite()


Procedure rr(x.l, y.l, l.l, b.l, r.l)
If StartDrawing(ScreenOutput())
Line(x+r, y, l-2*r, 0, RGB(255,0,0))
Line(x+r, y+b, l-2*r, 0, RGB(255,255,255))
Line(x, y+r, 0, b-2*r, RGB(0,255,0))
Line(x+l, y+r, 0, b-2*r, RGB(0,0,255))

For i=0 To 90
Plot((x+r)-r*Cos(i/180*#PI), (y+r)-r*Sin(i/180*#PI), RGB(255,255,0))
Plot((x+l-r)+r*Cos(i/180*#PI), (y+r)-r*Sin(i/180*#PI), RGB(255,255,0))
Plot((x+r)-r*Cos(i/180*#PI), (y+b-r)+r*Sin(i/180*#PI), RGB(255,255,0))
Plot((x+l-r)+r*Cos(i/180*#PI), (y+b-r)+r*Sin(i/180*#PI), RGB(255,255,0))
Next
StopDrawing()
EndIf
EndProcedure


If OpenWindow(0, 200, 200, 400, 400, "Rechteck")
  If OpenWindowedScreen(WindowID(0), 0, 0, 400, 400, 0,0,0)
EndIf
EndIf

rr(50, 80, 200, 300, 10)

Repeat: Until WindowEvent()=#PB_Event_CloseWindow 
x&y = Versatz im Fenster
l, b, r =Länge, Breite und Eckenradius

...geht aber sicher noch besser.

lg
Marco
Windows 11 - PB 6.03 x64
_________________________________
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Zu Ostern passt Riacons Link zum "Super-Ei" natürlich glänzend :D !
Die Win-Api bietet z.B. die Möglichkeit, mit "Regionen" zu arbeiten, den Aufwand dafür muß man selbst einschätzen. Hier eine Möglichkeit mit reinem PB (mit "optischer" Herleitung):

Code: Alles auswählen

Width=200
Height=150
PosX=100
PosY=50
Radius=25
  
If OpenWindow(0, 0, 0, 400, 300, "Rechteck mit abgerundeten Ecken 1", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If StartDrawing(WindowOutput(0))
    DrawingMode(#PB_2DDrawing_Outlined)
      
    Box(PosX, PosY, Width, Height, 0)
     
    Circle(PosX+Radius, PosY+Radius, Radius, 0)                           ;links oben
    Circle(PosX+Radius, PosY+Height-Radius, Radius, 0)                    ;links unten
    Circle(PosX+Width-Radius, PosY+Radius, Radius, 0)                     ;rechts oben
    Circle(PosX+Width-Radius, PosY+Height-Radius, Radius, 0)              ;rechts unten
   
    Delay(1000)      
    StopDrawing()
  EndIf
CloseWindow(0)
EndIf

Delay(1) ;zur "Stabilität"

If OpenWindow(0, 0, 0, 400, 300, "Rechteck mit abgerundeten Ecken 2", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If StartDrawing(WindowOutput(0))
    DrawingMode(#PB_2DDrawing_Outlined)
      
    LineXY(PosX+Radius, PosY, PosX+Width-Radius, PosY, 0)                 ;oben
    LineXY(PosX+Radius, PosY+Height, PosX+Width-Radius, PosY+Height, 0)   ;unten
    LineXY(PosX, PosY+Radius, PosX, PosY+Height-Radius, 0)                ;links
    LineXY(PosX+Width, PosY+Radius, PosX+Width, PosY+Height-Radius, 0)    ;rechts      
 
    Circle(PosX+Radius, PosY+Radius, Radius, 0)                           ;links oben
    Circle(PosX+Radius, PosY+Height-Radius, Radius, 0)                    ;links unten
    Circle(PosX+Width-Radius, PosY+Radius, Radius, 0)                     ;rechts oben
    Circle(PosX+Width-Radius, PosY+Height-Radius, Radius, 0)              ;rechts unten
    
    Delay(1000) 
    StopDrawing()
  EndIf
CloseWindow(0)
EndIf

Delay(1)

If OpenWindow(0, 0, 0, 400, 300, "Rechteck mit abgerundeten Ecken 3", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If StartDrawing(WindowOutput(0))
    DrawingMode(#PB_2DDrawing_Outlined)
      
    LineXY(PosX+Radius, PosY, PosX+Width-Radius, PosY, 0)                 ;oben
    LineXY(PosX+Radius, PosY+Height, PosX+Width-Radius, PosY+Height, 0)   ;unten
    LineXY(PosX, PosY+Radius, PosX, PosY+Height-Radius, 0)                ;links
    LineXY(PosX+Width, PosY+Radius, PosX+Width, PosY+Height-Radius, 0)    ;rechts      
  
    ;Viertelkreis rechts oben
    P1XB.d=PosX+Width
    P1YB.d=Height
    Winkel =89
    For i=1 To Winkel
      P2YB.d = PosY+Radius - Sin(i/180*#PI)*Radius 
      P2XB.d = PosX+Width-Radius + Cos(i/180*#PI)*Radius
      LineXY(P1XB, P1YB, P2XB, P2YB, 0)                                   ;Viertelkreis
      P1XB = P2XB 
      P1YB = P2YB
    Next 

    ;Viertelkreis links oben
    P1XB.d=PosX+Radius
    P1YB.d=PosY
    Winkel =179
    For i=91 To Winkel
      P2YB.d = PosY+Radius - Sin(i/180*#PI)*Radius 
      P2XB.d = PosX+Radius + Cos(i/180*#PI)*Radius
      LineXY(P1XB, P1YB, P2XB, P2YB, 0)                                   ;Viertelkreis
      P1XB = P2XB 
      P1YB = P2YB
    Next 

    ;Viertelkreis links unten
    P1XB.d=PosX
    P1YB.d=PosY+Height-Radius
    Winkel =269
    For i=181 To Winkel
      P2YB.d = PosY+Height-Radius - Sin(i/180*#PI)*Radius 
      P2XB.d = PosX+Radius + Cos(i/180*#PI)*Radius
      LineXY(P1XB, P1YB, P2XB, P2YB, 0)                                   ;Viertelkreis
      P1XB = P2XB 
      P1YB = P2YB
    Next 

    ;Viertelkreis rechts unten
    P1XB.d=PosX+Width-Radius
    P1YB.d=PosY+Height
    Winkel =359
    For i=271 To Winkel
      P2YB.d = PosY+Height-Radius - Sin(i/180*#PI)*Radius 
      P2XB.d = PosX+Width-Radius + Cos(i/180*#PI)*Radius
      LineXY(P1XB, P1YB, P2XB, P2YB, 0)                                   ;Viertelkreis
      P1XB = P2XB 
      P1YB = P2YB
    Next 

    StopDrawing()
  EndIf
 
  Repeat : Event = WaitWindowEvent() : Until  Event = #PB_Event_CloseWindow

CloseWindow(0)
EndIf
Gruß
Helle
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

Vielleicht so ?

Code: Alles auswählen

flag = #PB_Window_SystemMenu|1
hwnd = OpenWindow(0,0,0,400,400,"Test",flag) 
       CreateGadgetList(hwnd)
              
       dc1 = StartDrawing(WindowOutput(0))
            
              SelectObject_(dc1, GetStockObject_(#BLACK_PEN))
              SelectObject_(dc1, GetStockObject_(#GRAY_BRUSH))
              RoundRect_(dc1,10,10,150,140,25,25)
                        
             StopDrawing()
       
Repeat: event = WaitWindowEvent() 
Until event = #PB_Event_CloseWindow 

End 
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Diese Funktion hätte ich auch als erstes vorgeschlagen aber ich finde es nicht gut immer gleich mit API um sich zu werfen vorausgesetzt es ist erwünscht.
Windows 10 Pro, 64-Bit / Outtakes | Derek
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

da hast du recht, aber das klassische gerundete windows-rechteck wie in paint ist nunmal über API zugänglich.
ich vermute mal, dass das auf Linux einfach so sehr anders läuft,
dass Fred keinen zugriff auf den Pen und das gerundete Rechteck eingebaut hat.
denn eigentlich könnte man das in die standard 2DDrawing befehle aufnehmen.
genauso wie gefüllte ellipsen/rechtecke.
unter Win sind das Basis-Drawing-Funktionen, aber k.P. wie das unter Linux und Mac ist.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
bembulak
Beiträge: 228
Registriert: 13.12.2005 16:34
Wohnort: Österreich

Beitrag von bembulak »

:oops:

Der einfältige Programmierer würde sich wahrscheinlich so helfen:

Code: Alles auswählen

CreateImage(2, 150,150, 32)
StartDrawing(ImageOutput(2))
FillArea(0,0,RGB(0,0,255), RGB(0,0,255))
;-------------------------------------
Circle(50,50, 10, RGB(255,0,0))
Circle(50,100,10, RGB(255,0,0))
Circle(100,50, 10, RGB(255,0,0))
Circle(100,100,10, RGB(255,0,0))
Box(50,40, 50, 70, RGB(255,0,0))
Box(40, 50, 70, 50, RGB(255,0,0))
;--------------------------------------
StopDrawing()

OpenWindow(0, 0,0, 200,200, "Radius im Eck...", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
CreateGadgetList(WindowID(0))
ImageGadget(1, 0, 0, 150, 150, ImageID(2))



Repeat
  Delay(0)
Until WaitWindowEvent() = #PB_Event_CloseWindow
End
Antworten