Seite 1 von 3

[gelöst] Bild auf Zylinder legen und den drehen

Verfasst: 16.02.2008 22:48
von scholly
moin, moin...

Ich hab keine Ahnung von 3D und so und möchte mich einlesen bzw anhand von Code bilden :D
Hab noch nichmal die Spur einer Ahnung, wonach ich suchen sollte :oops:

Ziel:
Bild um einen senkrecht stehenden Zylinder legen und diesen dann um die Achse rotieren lassen.

Welches Beispiel bzw welches Tutorial kann mir den Einstieg ermöglichen ?

mDv... scholly

Verfasst: 16.02.2008 22:53
von Andreas_S
Da brauchst du auch nicht viel wissen.. etweder du nutzt eine Engine oder zB OpenGL. In beiden Fällen geht das sehr einfach.

Kommt drauf an was du verwenden willst...

Es gibt zwar ein OGL tut bin aber jetzt zu faul um zu suchen :mrgreen:
Wenn du OGL verwedest dann such am besten im englischen Forum...

Verfasst: 16.02.2008 23:01
von scholly
Ich weis weniger wie "nicht viel", nämlich garnix.

Geht das nicht mit PB-Bordmitteln ?

Und deutsch wär mir lieber, mit Englischem "Fach-Chinesisch" steh ich recht schnell auf Kriegsfuß :(

Verfasst: 16.02.2008 23:05
von Kaeru Gaman
> Geht das nicht mit PB-Bordmitteln ?

nuja...
du könntest die ein zylinder-mesh erzeugen, und den mit dem bild texturieren.
das sollte auch mit dem bißchen OGRE funktionieren...

Verfasst: 16.02.2008 23:13
von scholly
"zylinder-mesh erzeugen" ?
"mit dem bild texturieren" ?
"bißchen OGRE" ?

Ich hab 0,0 Plan von dem Kram.

Kann ich mich denn nicht irgendwo da reinlesen ?
Oder 'n einfachen Code oder Thread angucken ?

Verfasst: 17.02.2008 16:09
von NicTheQuick
Dazu braucht man doch keine 3D-Engine. Man muss nur ein bisschen mit
Sin() und Cos() rumspielen und die Pixel mit Plot malen.

Ich habe grad keine Zeit so etwas zu entwickeln. Aber solange der Zylinder
nicht so groß wie der Screen ist, sollte es selbst mit Plot schnell genug gehen.

Verfasst: 17.02.2008 16:33
von scholly
NicTheQuick hat geschrieben:Dazu braucht man doch keine 3D-Engine. Man muss nur ein bisschen mit
Sin() und Cos() rumspielen und die Pixel mit Plot malen.
Ich versuch mal hier Entsprechendes über die Forensuche zu finden.
NicTheQuick hat geschrieben:Aber solange der Zylinder nicht so groß wie der Screen ist, sollte es selbst mit Plot schnell genug gehen.
Groß? Nö, geplant sind Bilder zwischen 200x100 und 400x200 und dann mal sehen, was besser kommt: Tonne senkrecht und dann um die Hauptachse drehen oder Tonne waagerecht.

Mir fehlt halt nur ein vernünftiger Einstieg um mich durchzubeißen...

Verfasst: 17.02.2008 18:32
von Andreas_S

Code: Alles auswählen

#PI2 = #PI * 2


Structure zylinder
	r.l
	h.l
	
	angle.d
	
	sprite.l
EndStructure


Global Dim sin_.d(360)
Global Dim cos_.d(360)


For i = 0 To 360
	sin_(i) = Sin(i * #PI/180)
	cos_(i) = Cos(i * #PI/180)
Next


Procedure zylinder2DW( *zylinderPtr )
	Protected *zylinder.zylinder = *zylinderPtr
	
	ProcedureReturn *zylinder\r * 2
EndProcedure
Procedure zylinder2DH( *zylinderPtr )
	Protected *zylinder.zylinder = *zylinderPtr
	
	ProcedureReturn *zylinder\h
EndProcedure

Procedure drawZylinderOnSprite( *zylinderPtr , drawingSprite )
	Protected *zylinder.zylinder = *zylinderPtr, newW, newH, rotatingAngle = *zylinder\angle, forX = sin_(rotatingAngle) * SpriteWidth(*zylinder\sprite), toX = forX + SpriteWidth(*zylinder\sprite) / 2, angle, angleD.d, newX, newZ
	
	For x = forX To toX
		angleD = (x / toX) * 360 + *zylinder\angle
		
		angle = angleD
		angle % 360
		
		newX = cos_(angle) * *zylinder\r + *zylinder\r
		
		For y = 0 To SpriteHeight(*zylinder\sprite)
			StartDrawing(SpriteOutput(*zylinder\sprite))
				rgb = Point(x, y)
			StopDrawing()
			StartDrawing(SpriteOutput(drawingSprite))
				Line(newX, y, 1, 1, rgb)
			StopDrawing()
		Next
	Next
EndProcedure


sprite$ = OpenFileRequester("BMP Laden","","BMP File (*.bmp)|*.bmp",0)

If sprite$
	InitSprite()
	InitKeyboard()
	
	
	OpenScreen(1280, 800, 32, "Zylinder Sprite")
		
		LoadSprite(0, sprite$)
		
		zylinder.zylinder
			zylinder\h = SpriteHeight(0)
			zylinder\r = SpriteWidth(0) / #PI2
			zylinder\angle = 0
			zylinder\sprite = 0
		
		CreateSprite(1, zylinder2DW(@zylinder), zylinder2DH(@zylinder))
			drawZylinderOnSprite(@zylinder, 1)
		
		CreateSprite(2, zylinder2DW(@zylinder) + 2, zylinder2DH(@zylinder) + 2)
			StartDrawing(SpriteOutput(2))
				Box(0, 0, zylinder2DW(@zylinder) + 2, zylinder2DH(@zylinder) + 2, RGB(255, 0, 0))
			StopDrawing()
		
		Repeat
			ExamineKeyboard()
			
			FlipBuffers()
			ClearScreen(RGB(0,0,0))
			
			drawZylinderOnSprite(@zylinder, 1)
			zylinder\angle + 1
			
			DisplaySprite(2,49,49)
			DisplaySprite(1,50,50)
			DisplaySprite(0,400,50)
			
			Delay(1)
		Until KeyboardPushed(#PB_Key_Escape)
	CloseScreen()
EndIf

Glaub das stimmt so... perfmranc ist aber mieß...
Kann das jemand optimieren?


Andreas

Verfasst: 17.02.2008 22:13
von scholly
Hat was länger gedauert, weil ich eben über Lebosteins FontMAP gestolpert bin :D

Ersma danke für den Code, ich habs mal mit dem PureBasicLogo.bmp aus den Examples versucht:
- es ruckelt arg
- es hat weiße und schwarze Streifen wo keine hingehören
- es staucht links
- es kommt nicht neu sondern igendwie verkehrtherum wieder von rechts rein
- und kackt irgendwann in der Zeile newX = cos_(angle) * *zylinder\r + *zylinder\r
mit der Bemerkung Error: Line 44 Array index out of bounds ab.

Keine Ahnung, wieviel ich von dem Code verstehen werde, aber ich versuch auf jeden fall, mal was zu verschlimmbessern.

Learning by try and error /:->

Verfasst: 18.02.2008 19:51
von Andreas_S

Code: Alles auswählen

#PI2 = #PI * 2


Structure zylinder
	r.l
	h.l
	
	xStep.d
	
	angle.d
	
	sprite.l
EndStructure


Procedure.d cutVal( val.d , min.d , max.d )
	Protected d.d = max - min
	
	While val > max.d
		val - d
	Wend
	While val < min.d
		val + d
	Wend
	
	ProcedureReturn val
EndProcedure


Procedure zylinder2DW( *zylinderPtr )
	Protected *zylinder.zylinder = *zylinderPtr
	
	ProcedureReturn *zylinder\r * 2
EndProcedure
Procedure zylinder2DH( *zylinderPtr )
	Protected *zylinder.zylinder = *zylinderPtr
	
	ProcedureReturn *zylinder\h
EndProcedure

Procedure drawZylinderOnSprite( *zylinderPtr , drawingSprite )
	Protected *zylinder.zylinder = *zylinderPtr, rotatingAngle = *zylinder\angle, toX.d = Sin(rotatingAngle * #PI/180) * SpriteWidth(*zylinder\sprite), x.d = zylinder2DW(*zylinder) + toX, a.d, angle.d, newX.d
	Protected aa.d, xx.d
	
	Repeat
		x - *zylinder\xStep
		a + *zylinder\xStep
		angle = a/zylinder2DW(*zylinder) * 180
		
		xx = cutVal(x, 0, SpriteWidth(*zylinder\sprite) - 1)
		
		newX = *zylinder\r + Cos(angle * #PI/180) * *zylinder\r
		
		Debug a
		
		For y = 0 To SpriteHeight(*zylinder\sprite)
			StartDrawing(SpriteOutput(*zylinder\sprite))
				rgb = Point(xx, y)
			StopDrawing()
			StartDrawing(SpriteOutput(drawingSprite))
				Line(newX, y, 1, 1, rgb)
			StopDrawing()
		Next
	Until x <= toX
EndProcedure


sprite$ = OpenFileRequester("BMP Laden","","BMP File (*.bmp)|*.bmp",0)

If sprite$
	InitSprite()
	InitKeyboard()
	
	
	OpenScreen(1280, 800, 32, "Zylinder Sprite")
		
		LoadSprite(0, sprite$)
		
		zylinder.zylinder
			zylinder\h = SpriteHeight(0)
			zylinder\r = SpriteWidth(0) / #PI2
			zylinder\xStep = 0.5
			zylinder\angle = 0
			zylinder\sprite = 0
		
		CreateSprite(1, zylinder2DW(@zylinder), zylinder2DH(@zylinder))
			drawZylinderOnSprite(@zylinder, 1)
		
		CreateSprite(2, zylinder2DW(@zylinder) + 2, zylinder2DH(@zylinder) + 2)
			StartDrawing(SpriteOutput(2))
				Box(0, 0, zylinder2DW(@zylinder) + 2, zylinder2DH(@zylinder) + 2, RGB(255, 0, 0))
			StopDrawing()
		
		Repeat
			ExamineKeyboard()
			
			FlipBuffers()
			ClearScreen(RGB(0,0,0))
			
			drawZylinderOnSprite(@zylinder, 1)
			zylinder\angle + 1
			
			DisplaySprite(2,49,49)
			DisplaySprite(1,50,50)
			DisplaySprite(0,400,50)
			
			Delay(1)
		Until KeyboardPushed(#PB_Key_Escape)
	CloseScreen()
EndIf
Ich muss mir eingestehn ich weis nicht wiso sich die Rotation kehrt...

Aber sonst gehts jetzt!
Man kann auch die "genauigkeit" ändern: >>zylinder\xStep = ...

Auf keinen Fall zu große Bilder mit dieser Genauigkeit verwenden!!!

Vil kann mir jemand helfen...


Andreas