[erledigt]Bestimmte kurve berechnen mittels Sin() bzw. Cos()

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Sunny
Beiträge: 290
Registriert: 19.02.2009 06:02

[erledigt]Bestimmte kurve berechnen mittels Sin() bzw. Cos()

Beitrag von Sunny »

Hi@all,
Ich habe vor mittels PB folgende Kurve zu zeichnen:
Bild
Das muss ja sicherlich irgendwie mittels Sin() bzw Cos() gemacht werden, aber wie genau, weiß ich leider nich.

Der Startpunkt dieser Kurve muss der höchste Punkt sein und der Endpunkt der tiefste.
Es wäre super, wenn mir jemand erklären könnte, wie sowas Funktioniert (am besten wäre ein Beispielcode) und dann müsste ich noch wissen, welche Werte wie verändert werden müssen, um den Start- und Endpunkt sowohl in der höhe als auch in der entfernung zueinander zu variieren.

Ich hoffe doch sehr, das ihr mich so halbwegs verstanden habt und mir helfen könnt.
Ich bedanke mich schonmal im voraus.
Zuletzt geändert von Sunny am 04.02.2011 23:43, insgesamt 1-mal geändert.
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Re: Bestimmte kurve berechnen mittels Sin() bzw. Cos()

Beitrag von TomS »

Arbeiten wir mit dem Kosinus, dann brauchen wir nicht ganz so viel rumrechnen, da der Kosinus bei x=0 genau 1 ist und er damit seinen höchsten Punkt bei 0 hat.
Den niedrigesten Punkt hat er bei #Pi/2

Folgender code zeichnet eine halbe Kosinuskurve.
Dabei is zu beachen, dass die Kurve bei #LeftOffset beginnt.
Die Kurve wird momentan mittig gezeichnet, so dass unabhängig von der angegeben Amplitude, oberhalb und unterhalb der Kurve gleich viel Platz ist.
Kann aber bei Bedarf einfach geändert werden.

Code: Alles auswählen

#Amplitude = 380 ;Kurvenhöhe in Pixel
#Weite = 380
#LeftOffset = 10 ;Abstand vom linken Rand
Define a.f=0
Define x.f,y.f
Define Weite = #Weite / #PI
Define Amplitude = #Amplitude / 2

CreateImage(0, 400, 400)
StartDrawing(ImageOutput(0))
Box(0, 0, 400, 400, $FFFFFF)
Repeat
	a + 0.01	
	x=a + #LeftOffset
	y=ImageHeight(0)/2 - Cos(a / Weite) * Amplitude	
	If x>0 And x<400
		If y>0 And y<400
			Plot(x, y ,0)
		EndIf
	EndIf 	
Until a > #PI *Weite
StopDrawing()

OpenWindow(0, 0, 0, 400, 400, "", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ImageGadget(0,0,0,0,0,ImageID(0))
Repeat
	event = WaitWindowEvent(20)
	
Until event = #PB_Event_CloseWindow
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Bestimmte kurve berechnen mittels Sin() bzw. Cos()

Beitrag von STARGÅTE »

der Code von TomS ist sicherlich richtig, wenn es wirklich um Cosinus geht.
ich finde aber, diese Kurve sieht mehr nach einer kubischen Bézierkurve aus.

Ohne dich jetzt völlig zu verwirren, zum vergleich mal mein Beispielcode:

Code: Alles auswählen


Structure Vector2D
	x.f
	y.f
EndStructure

Structure Curve2D
	Detail.i
	Array Position.Vector2D(0)
EndStructure

Procedure.f FactorialF(Value)
	Protected n, Factorial.f = 1
	For n = 2 To Value
		Factorial * n
	Next n
	ProcedureReturn Factorial
EndProcedure

Procedure Curve2DPosition(*Curve2D.Curve2D, Time.f, *Position.Vector2D)
	With *Curve2D
		Protected i, n = ArraySize(\Position())
		;         n        n!
		; P(t) = Sum ( --------- t^i (1-t)^(n-i) P[i] )
		;        i=0   i!*(n-i)!
		Protected Fn.f = FactorialF(n), Factor.f
		ClearStructure(*Position, Vector2D)
		For i = 0 To n
			Factor = Fn/(FactorialF(i)*FactorialF(n-i)) * Pow(Time,i) * Pow(1-Time,n-i)
			*Position\x + Factor*\Position(i)\x
			*Position\y + Factor*\Position(i)\y
		Next
	EndWith
EndProcedure

Procedure DrawCurve2D(*Curve2D.Curve2D, Color)
	Protected i.i, Dim Position.Vector2D(*Curve2D\Detail)
	Protected Detail.i = *Curve2D\Detail-1
	With *Curve2D
		For i = 0 To \Detail
			Curve2DPosition(*Curve2D, i/\Detail, Position(i))
		Next
		For i = 0 To Detail
			LineXY(Position(i)\x, Position(i)\y, Position(i+1)\x, Position(i+1)\y, Color)
		Next
	EndWith
EndProcedure





Enumeration
	#Window : #Gadget : #Image
EndEnumeration


Dim Curve2D.Curve2D\Position(3)
Curve2D\Detail = 50
Curve2D\Position(0)\x = 20
Curve2D\Position(0)\y = 20
Curve2D\Position(1)\x = 170
Curve2D\Position(1)\y = 20
Curve2D\Position(2)\x = 170
Curve2D\Position(2)\y = 120
Curve2D\Position(3)\x = 320
Curve2D\Position(3)\y = 120


CreateImage(#Image, 340, 140)

StartDrawing(ImageOutput(#Image))
DrawingMode(#PB_2DDrawing_Transparent)
Box(0,0,340, 140,$FFFFFF)
DrawCurve2D(Curve2D.Curve2D, $000000)
StopDrawing()


SetClipboardImage(#Image)


OpenWindow(#Window, 0, 0, ImageWidth(#Image), ImageHeight(#Image), "Image", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ImageGadget(#Gadget, 0, 0, ImageWidth(#Image), ImageHeight(#Image), ImageID(#Image))

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Zuletzt geändert von STARGÅTE am 04.02.2011 23:42, insgesamt 1-mal geändert.
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
Sunny
Beiträge: 290
Registriert: 19.02.2009 06:02

Re: Bestimmte kurve berechnen mittels Sin() bzw. Cos()

Beitrag von Sunny »

Perfekt!!!
Das ist genau das, was ich gesucht hab...
Dankeschön
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Re: [erledigt]Bestimmte kurve berechnen mittels Sin() bzw. C

Beitrag von TomS »

Auch nicht schlecht, Stargate!

Ich hab mein Beispiel ein wenig zum Rumspielen erweitert.

Code: Alles auswählen

#Amplitude = 77 ;Kurvenhöhe in Pixel
#Weite = 190
#LeftOffset = 0 ;Abstand vom linken Rand


Procedure draw(img, _Amplitude, _Weite)
	
Protected a.f=0
Protected x.f,y.f
Protected Weite.i = _Weite / #PI
Protected Amplitude.i = _Amplitude / 2

CreateImage(0, 400, 400)
StartDrawing(ImageOutput(0))
Box(0, 0, 400, 400, $FFFFFF)
Repeat
   a + 0.01   
   x=a + #LeftOffset
   y=ImageHeight(0)/2 - Cos(a / Weite) * Amplitude   
   If x>0 And x<399
      If y>0 And y<399
         Plot(x, y ,0)
      EndIf
   EndIf    
Until a > #PI *Weite

StopDrawing()


EndProcedure 

draw(0,#Amplitude,#Weite)


OpenWindow(0, 0, 0, 500, 430, "", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ImageGadget(0, 0, 0, 0, 0, ImageID(0))
TrackBarGadget(1, 410, 5,40, 400, 0, 800, #PB_TrackBar_Vertical) : SetGadgetState(1, #Amplitude+400)
TrackBarGadget(2, 450, 5,40, 400, 0, 400, #PB_TrackBar_Vertical) : SetGadgetState(2, #Weite)
StringGadget(3, 5, 405, 200, 20, "Amplitude: "+Str( #Amplitude)+" / Weite: "+Str( #Weite))
Repeat
	event = WaitWindowEvent(20)
	Select event
		Case #PB_Event_Gadget
			Select EventGadget()
				Case 1,2
					draw(0, GetGadgetState(1)-400, GetGadgetState(2))
					SetGadgetState(0,ImageID(0))
					SetGadgetText(3, "Amplitude: "+Str( GetGadgetState(1)-400)+" / Weite: "+Str( GetGadgetState(2)))
			EndSelect
	EndSelect
	
					
   
Until event = #PB_Event_CloseWindow
Antworten