Seite 1 von 1

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

Verfasst: 04.02.2011 22:45
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.

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

Verfasst: 04.02.2011 23:13
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

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

Verfasst: 04.02.2011 23:39
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

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

Verfasst: 04.02.2011 23:42
von Sunny
Perfekt!!!
Das ist genau das, was ich gesucht hab...
Dankeschön

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

Verfasst: 05.02.2011 00:13
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