Kreis Punkte setzen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Kreis Punkte setzen

Beitrag von STARGÅTE »

na dann halt so :

Code: Alles auswählen


Global teiler.l,Image0
teiler=360/12



Enumeration
  #Window_0
EndEnumeration



Enumeration
  #Image_0
EndEnumeration






Image0 = CreateImage(0,500,500)
StartDrawing(ImageOutput(0))
Box(0,0,500,500,RGB(255,255,255))
StopDrawing()

; Berechnet den Winkel
Procedure.f Winkel(x.f,y.f)
 Winkel.f
 If x = 0
  If y <  0 : Winkel = -90 : EndIf 
  If y >= 0 : Winkel =  90 : EndIf 
 Else 
  Winkel = ATan(y/x)/#PI*180
  If x < 0 : Winkel + 180 : EndIf 
 EndIf 
 ProcedureReturn Winkel
EndProcedure
Procedure.f Abstand(x1, y1, x2, y2)
 r.f = Sqr(Pow(x1-x2,2)+Pow(y1-y2,2))
 ProcedureReturn r
EndProcedure

Procedure GetMouseX(Gadget)
  GetCursorPos_(mouse.POINT)
  MapWindowPoints_(0,GadgetID(Gadget),mouse,1)
  ProcedureReturn mouse\x
EndProcedure


Procedure GetMouseY(Gadget)
  GetCursorPos_(mouse.POINT)
  MapWindowPoints_(0,GadgetID(Gadget),mouse,1)
  ProcedureReturn mouse\y
EndProcedure
Procedure Open_Window_0()
  If OpenWindow(#Window_0, 391, 283, 521, 511, "test",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
    If CreateGadgetList(WindowID(#Window_0))
      ImageGadget(#Image_0, 10, 10, 500, 500, Image0)
      
    EndIf
  EndIf
EndProcedure

Open_Window_0()

Repeat
  
  Event = WaitWindowEvent() 
  
  WindowID = EventWindow()
  
  GadgetID = EventGadget()
  
  EventType = EventType()
  
  
  If  GetAsyncKeyState_(#VK_LBUTTON)
    winkel=0
    posx= GetMouseX(#Image_0)
    posy=GetMouseY(#Image_0)
    x_mitte=250
    y_mitte=250
    Start.f = Winkel(posx-x_mitte,posy-y_mitte)
    Radius.f = Abstand(posx,posy,x_mitte,y_mitte)
    If posx>0 And posx<501
      If posy>0 And posy<501
        For n = 0 To 330 Step 30
         winkel = Start+n
         x = Radius * Cos(winkel *(2*3.1415/360)) + x_mitte ; Winkel als Bogenmaß
         y = Radius * Sin(winkel *(2*3.1415/360)) + y_mitte
         StartDrawing(ImageOutput(0))
          Box(posx,posy,4,4,RGB(0,0,0))
          Box(x,y,4,4,RGB(0,0,0))
         StopDrawing()
         SetGadgetState(#Image_0,ImageID(0))
       Next 
      EndIf
    EndIf
  EndIf
  If Event = #PB_Event_Gadget
    
    
    
  EndIf
  
Until Event = #PB_Event_CloseWindow

End
EDIT: da kann man ja richtig geile Sachen draus zauber :o
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
roherter
Beiträge: 1407
Registriert: 10.04.2005 18:58
Kontaktdaten:

Beitrag von roherter »

Jupppi Stargate mein Retter.
Ist für mein Mandala Creator willst in die Credits?
:allright: :allright: :allright: :allright:

Könntest du mir vielleicht kurz sagen wie du das gemacht hast!
Kein Durchblick
:shock: :o :shock:
Purebasic 5.0 32bit und 64 bit

I'm back from hell
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

Beitrag von NicTheQuick »

Hier noch eine alternative Winkel-Procedure und ein Winkel-Makro:

Code: Alles auswählen

Procedure.d Winkel(x.d, y.d)
 Protected Winkel.d
 Winkel = ATan(y / x) / #PI * 180
 If x < 0
   Winkel + 180
 ElseIf y < 0
   Winkel + 360
 EndIf
 ProcedureReturn Winkel
EndProcedure

Macro WinkelM(x, y)
  (ATan(y / x) / #PI * 180.0 + (x < 0.0 And 1) * 180.0 + (y < 0.0 And x > 0) * 360.0)
EndMacro

Define a.l, x.d, y.d

For a = 0 To 360 Step 5
  x = Cos(a * #PI / 180)
  y = Sin(a * #PI / 180)
  Debug WinkelM(x, y)
Next
@Stargate:
Ich weiß nicht, ob es so erwünscht ist, aber deine Winkel-Procedure gibt
auch negative Winkel aus, wenn x > 0 und y < 0 ist. Das ist mathematisch
natürlich nicht falsch, aber hinderlich, wenn man gerne im Intervall [0; 360[
arbeitet.

///Edit:
Hier übrigens noch der Code für alle Linux-Nutzer unter uns. API braucht
man hier nämlich nicht.

Code: Alles auswählen

Global teiler.l,Image0
teiler=360/12

Enumeration
  #Window_0
EndEnumeration

Enumeration
  #Image_0
EndEnumeration


Image0 = CreateImage(0,500,500)
StartDrawing(ImageOutput(0))
Box(0,0,500,500,RGB(255,255,255))
StopDrawing()

; Berechnet den Winkel
Procedure.f Winkel(x.f,y.f)
 Winkel.f
 If x = 0
  If y <  0 : Winkel = -90 : EndIf
  If y >= 0 : Winkel =  90 : EndIf
 Else
  Winkel = ATan(y/x)/#PI*180
  If x < 0 : Winkel + 180 : EndIf
 EndIf
 ProcedureReturn Winkel
EndProcedure
Procedure.f Abstand(x1, y1, x2, y2)
 r.f = Sqr(Pow(x1-x2,2)+Pow(y1-y2,2))
 ProcedureReturn r
EndProcedure

Procedure GetMouseX(Gadget)
  Protected x.l
  x = WindowMouseX(#Window_0)
  ProcedureReturn x - GadgetX(gadget)
EndProcedure
Procedure GetMouseY(Gadget)
  Protected y.l
  y = WindowMouseY(#Window_0)
  ProcedureReturn y - GadgetY(gadget)
EndProcedure

Procedure Open_Window_0()
  If OpenWindow(#Window_0, 391, 283, 521, 511, "test",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
    If CreateGadgetList(WindowID(#Window_0))
      ImageGadget(#Image_0, 10, 10, 500, 500, Image0)
     
    EndIf
  EndIf
EndProcedure

Open_Window_0()
x_mitte=250
y_mitte=250

Repeat
 
  Event = WaitWindowEvent()
 
  WindowID = EventWindow()
 
  GadgetID = EventGadget()
 
  EventType = EventType()
 
  Select Event
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      Select GadgetID
        Case #Image_0
          If EventType = #PB_EventType_LeftClick
            winkel = 0
            posx = GetMouseX(#Image_0)
            posy = GetMouseY(#Image_0)
            
            Start.f = Winkel(posx-x_mitte,posy-y_mitte)
            Radius.f = Abstand(posx,posy,x_mitte,y_mitte)
            If posx > 0 And posx < 501
              If posy > 0 And posy < 501
                For n = 0 To 359 Step 30
                  winkel = Start + n
                  x = Radius * Cos(winkel * (#PI / 360)) + x_mitte ; Winkel als Bogenmaß
                  y = Radius * Sin(winkel * (#PI / 360)) + y_mitte
                  StartDrawing(ImageOutput(0))
                    Box(posx, posy, 4, 4, RGB(0, 0, 0))
                    Box(x, y, 4, 4, RGB(0, 0, 0))
                  StopDrawing()
                  SetGadgetState(#Image_0, ImageID(0))
                Next
              EndIf
            EndIf
          EndIf
      EndSelect
  EndSelect
ForEver

End 
Benutzeravatar
roherter
Beiträge: 1407
Registriert: 10.04.2005 18:58
Kontaktdaten:

Beitrag von roherter »

Ein kurze frage habe ich noch wie machen zeichenprogramme das,das die zeichnung bei schnellen mausbewegungen trotzdem erstellt wird bei mir werden dann nähmlich nur punkte gesetzt :o ?
Purebasic 5.0 32bit und 64 bit

I'm back from hell
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

@roherter , es ist dein Programm, und somit deine entscheidung ob ich in die Credits kommen soll.

Ich habe erst mal den Winkel vom Mittelpunkt zur Maus ausgerechnet,
dann den Abstand (Radius) berechnet und dann alle 30° davon ein Punkt gemacht (also die 12 punkte im kreis)


@Nick: erst mal zum Macro, ich weiß nicht ob das so ok ist, wenn du einfach den ATAN() von y/x bildest ohne zu prüfen ob x =0 ist.

Ja es ist bei mir erwünscht das der Ergebnisraum ]270;-90] ist, aber kann kann halt noch schnell den Winkel auf die [0;360[ bringen
dafür nutze ich immer das hier :

Code: Alles auswählen

; Berichtigt den unechten Winkel zu einem echten (0°-360°) Winkel
Procedure.f Winkelkorrektur(Winkel.f)
 If Winkel < 0
  ProcedureReturn (Winkel/360-Int(Winkel/360)+1)*360
 Else
  ProcedureReturn (Winkel/360-Int(Winkel/360))*360
 EndIf
EndProcedure

EDIT @roherter : die ziehen Linien von der letzten zu aktuellen Position der Maus
Line(MouseX(), MouseY(), -MouseDeltaX(), -MouseDeltaY())
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
roherter
Beiträge: 1407
Registriert: 10.04.2005 18:58
Kontaktdaten:

Beitrag von roherter »

Weiß du auch was zu meiner letzten frage,im moment sieht das ruckelig aus habe das ganze schon in ein callback gepackt aber hatte den gleichen effekt.

Wenn ich die maus zu schnell bewege kommen zwischendurch nur punkte aber keine durchgänigen linien?

@stargate:Was macht eigentlich dein Spiel Dune oder hast du es eingestellt?
Purebasic 5.0 32bit und 64 bit

I'm back from hell
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

Hier dein Code mit Linien

Code: Alles auswählen

Global teiler.l,Image0 
teiler=360/12 



Enumeration 
  #Window_0 
EndEnumeration 



Enumeration 
  #Image_0 
EndEnumeration 






Image0 = CreateImage(0,500,500) 
StartDrawing(ImageOutput(0)) 
Box(0,0,500,500,RGB(255,255,255)) 
StopDrawing() 

; Berechnet den Winkel 
Procedure.f Winkel(x.f,y.f) 
 Winkel.f 
 If x = 0 
  If y <  0 : Winkel = -90 : EndIf 
  If y >= 0 : Winkel =  90 : EndIf 
 Else 
  Winkel = ATan(y/x)/#PI*180 
  If x < 0 : Winkel + 180 : EndIf 
 EndIf 
 ProcedureReturn Winkel 
EndProcedure 
Procedure.f Abstand(x1, y1, x2, y2) 
 r.f = Sqr(Pow(x1-x2,2)+Pow(y1-y2,2)) 
 ProcedureReturn r 
EndProcedure 

Procedure GetMouseX(Gadget) 
  GetCursorPos_(mouse.POINT) 
  MapWindowPoints_(0,GadgetID(Gadget),mouse,1) 
  ProcedureReturn mouse\x 
EndProcedure 


Procedure GetMouseY(Gadget) 
  GetCursorPos_(mouse.POINT) 
  MapWindowPoints_(0,GadgetID(Gadget),mouse,1) 
  ProcedureReturn mouse\y 
EndProcedure 
Procedure Open_Window_0() 
  If OpenWindow(#Window_0, 391, 283, 521, 511, "test",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar ) 
    If CreateGadgetList(WindowID(#Window_0)) 
      ImageGadget(#Image_0, 10, 10, 500, 500, Image0) 
      
    EndIf 
  EndIf 
EndProcedure 

Open_Window_0() 

Repeat 
  
  Event = WaitWindowEvent() 
  
  WindowID = EventWindow() 
  
  GadgetID = EventGadget() 
  
  EventType = EventType() 
  
  
  If GetAsyncKeyState_(#VK_LBUTTON) 
    winkel=0 
    If altRadius.f >= 0
     altStart.f = Start.f
     altRadius = Radius.f
    EndIf
    posx= GetMouseX(#Image_0) 
    posy=GetMouseY(#Image_0) 
    x_mitte=250 
    y_mitte=250 
    Start = Winkel(posx-x_mitte,posy-y_mitte) 
    Radius = Abstand(posx,posy,x_mitte,y_mitte) 
    If altRadius = -1
     altStart.f = Start.f
     altRadius.f = Radius.f
    EndIf
    If posx>0 And posx<501 
      If posy>0 And posy<501 
        For n = 0 To 330 Step 30 
         winkel = Start+n 
         x1 = Radius * Cos(winkel *(2*3.1415/360)) + x_mitte ; Winkel als Bogenmaß 
         y1 = Radius * Sin(winkel *(2*3.1415/360)) + y_mitte 
         winkel = altStart+n 
         x2 = altRadius * Cos(winkel *(2*3.1415/360)) + x_mitte ; Winkel als Bogenmaß 
         y2 = altRadius * Sin(winkel *(2*3.1415/360)) + y_mitte 
         StartDrawing(ImageOutput(0)) 
          LineXY(x1,y1,x2,y2,RGB(0,0,0)) 
         StopDrawing() 
         SetGadgetState(#Image_0,ImageID(0)) 
        Next 
      EndIf 
    EndIf 
  Else
   altStart.f = 0
   altRadius.f = -1
  EndIf 
  If Event = #PB_Event_Gadget 
    
    
    
  EndIf 
  
Until Event = #PB_Event_CloseWindow 

End 
und ja dune ist eingestellt, siehe DUNE 2077 Thema.

EDIT: ich muss jetzt der AstroPhysikVorlesung folgen, bin erst gegen 20:00 wieder da ...
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
roherter
Beiträge: 1407
Registriert: 10.04.2005 18:58
Kontaktdaten:

Beitrag von roherter »

Danke,jetzt weiß ich auch wie die anderen Programme das machen :D
Purebasic 5.0 32bit und 64 bit

I'm back from hell
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

Beitrag von NicTheQuick »

@Stargate:
'ATan()' ist für x/0 definiert. Fließkommazahlen auch.

Code: Alles auswählen

a1.d = 1.0
a2.d = -1.0
b.d = 0.0
c1.d = a1 / b
c2.d = a2 / b

Debug c1
Debug c2

d.d = c1 + c2

Debug d

Debug ATan(c1)
Debug ATan(c2)
Debug ATan(d)
Wie du siehst, funktioniert 'ATan()' bei 'c1' und 'c2', bei 'd' aber nicht, da
'c1' und 'c2' unendlich bzw. -unendlich darstellen. Und 'c1+c2' gibt
natürlich nicht Null, sondern einen unbestimmten Ausdruck.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

cool das muss aber neu sein, in 3.3 konnte man noch nicht davon ausgehen das er das richtig handhabt.

das man nicht mit Unendlich rechnen kann ist mir klar, aber ich musste nicht das man sie trotzdem für Proceduren benutzen kann

Aber PB hat ein mathematischen BUG drin :

Code: Alles auswählen

Debug Pow(0,0)
das ist nicht 1 sonder 0^0 ist auch ein unbestimmter Ausdruck
EDIT: habe bei WIKI gelesen das das je nach "Zweck" abers ist, und in der Informatik wurde 0^0=1 definiert
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
Antworten