AndrewT's Stuff [Image-Heavy]

Community Forums/Showcase/AndrewT's Stuff [Image-Heavy]

AndrewT(Posted 2009) [#1]
This is some math-related stuff I've been working on recently that I thought I'd show you guys.

Mandelbrot Explorer




Parametric Systems Plotter

Butterfly Curve:



Epicycloid:



Lissajous:



DFS Maze Generation



L-Systems





Vector Fields



Feedback is welcome. If you'd like to see any of the code, feel free to ask.


_Skully(Posted 2009) [#2]
That stuff is awesome

I love looking at math creations...


ImaginaryHuman(Posted 2009) [#3]
I like the vectorfields, do the dots move in realtime?


AndrewT(Posted 2009) [#4]
Yea. There are two systems: one based on cells, and one based on functions.

In cellular system, the field is divided into cells which are assigned angles, and a particle's velocity will change depending on the cell it is currently in. It results in a more organic, random look. That's the system you see in the last shot I posted.

In the function-based system, the velocity of a particle is determined by a function of its position. It results in a more formulaic appearance. This is a screenshot of the field (x, y) -> (y, -x).




_Skully(Posted 2009) [#5]
Thats really interesting... I should try something like this using my tilemax engine... each cell already has a vector based force configurable per cell... as well as surface and spacial friction. Do the particles in this have energy as well or are they just dragged around by the forces? Cells going off the edges, are they wrapped?


Warpy(Posted 2009) [#6]
Nice!


AndrewT(Posted 2009) [#7]
Thats really interesting... I should try something like this using my tilemax engine... each cell already has a vector based force configurable per cell... as well as surface and spacial friction. Do the particles in this have energy as well or are they just dragged around by the forces? Cells going off the edges, are they wrapped?


The particles are just dragged around by forces in the cellular system--it's a very simple system. If they go off the edge then they do get wrapped around. In the function-based system, however, they are not wrapped when the go over the edge, instead every frame ten random particles are deleted, and ten are added.


elcoo(Posted 2009) [#8]
Very interesting stuff you've got there!
May I know how many particles there are on the first "Vector fields" example and how many fps you got?


Jesse(Posted 2009) [#9]
That is really interesting. I would like to see the code for the Parametric System Plotter and everything below except for the maze generator if that's possible. I have the DFS Maze Generator.


AndrewT(Posted 2009) [#10]
Very interesting stuff you've got there!
May I know how many particles there are on the first "Vector fields" example and how many fps you got?


I've since changed the settings so I can't give you an exact number, but in a test I just did I'm getting a solid 60FPS up to about 26000 particles, then it starts decreasing. This is on a Geforce GTS 250, AMD Phenom II X4 820, 6GB RAM.

That is really interesting. I would like to see the code for the Parametric System Plotter and everything below except for the maze generator if that's possible. I have the DFS Maze Generator.


No problem, I'll try and post it tonight--I'm cleaning up the parametric plotter code and working on an expression evaluator so you can edit the system in real-time.


DavidDC(Posted 2009) [#11]
Vector Fields gets my vote if you are posting code :-)


AndrewT(Posted 2009) [#12]
Parametric Plotter - Sorry, no editing in realtime--the expression evaluator was far too slow to perform the tens of thousands of operations required every second. Change the TX and TY expressions on lines 80 and 81 to change the system. I also have several systems commented out that you can look at.

SuperStrict

Global MinX:Float = -6.0, MinY:Float = -4.0, MaxX:Float = 6.0, MaxY:Float = 4.0

Graphics 1024, 768, 0

Local TX:Float, TY:Float, GX:Float = Float(GraphicsWidth()), GY:Float = Float(GraphicsHeight()), X:Float, Y:Float, OX:Float, OY:Float
Local T:Double, TStart:Float, TEnd:Float, Ticks:Int
Local e:Float = 2.71828183

T = 0.0
TStart = 0.0
TEnd = 2500.0
Ticks = 1000

Local A:Double, AInc:Float

A = 0.0

Local MZS:Float
Local MXS:Float, MYS:Float
Local Animation:Int = 1

Repeat

	SetClsColor(20, 20, 20)
	Cls

	MXS = MouseXSpeed()
	MYS = MouseYSpeed()
	MZS = MouseZSpeed()
	
	If KeyHit(KEY_SPACE)
		Animation = 1 - Animation
	EndIf
	
	If KeyHit(KEY_LSHIFT)
		A = 0.0
	EndIf
	
	If MZS > 0.0
		Local R:Float = MaxX - MinX
		MinX :+ R / 10.0
		MaxX :- R / 10.0
		R = MaxY - MinY
		MinY :+ R / 10.0
		MaxY :- R / 10.0	
	EndIf
	
	If MZS < 0.0
		Local R:Float = MaxX - MinX
		MinX :- R / 10.0
		MaxX :+ R / 10.0
		R = MaxY - MinY
		MinY :- R / 10.0
		MaxY :+ R / 10.0	
	EndIf
	
	If MouseDown(3)
		Local OMinX:Float = MinX, OMinY:Float = MinY
		MinX :- MXS * 0.001 * (MaxX - MinX)
		MinY :+ MYS * 0.001 * (MaxY - MinY)
		MaxX :- MXS * 0.001 * (MaxX - OMinX)
		MaxY :+ MYS * 0.001 * (MaxY - OMinY)
	EndIf

	If Animation
		A :+ 0.01
	EndIf

	For Local I:Int = 1 To Ticks
		
		OX = X
		OY = Y
	
		T = Float(I) / Float(Ticks) * (TEnd - TStart) + TStart
		
		'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
		
		TX = Sin(T) * (e^Cos(T) - 2 * Cos(4 * T) - Sin(T / 12) ^ 5)
		TY = Cos(T) * (e^Cos(T) - 2 * Cos(4 * T) - Sin(T / 12) ^ 5)
		
		'''''''''''''''''''''''''''''''''''''''''
		
		'Local R:Float, K:Float
		
		'R = 1.0
		'K = Sin(A/10.0)
		
		'TX = R * (K + 1.0) * Cos(T) - R * Cos((K + 1.0) * T)
		'TY = R * (K + 1.0) * Sin(T) - R * Sin((K + 1.0) * T)
		
		'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
		
		'Local A2:Float, B:Float, Ang:Float
		
		'A2 = Sin(A / 30.0)
		'B = Cos(A / 30.0)
		'Ang = 90.0
		
		'TX = A2 * Sin(A2 * T + Ang)
		'TY = B * Sin(B * T)
		
		'TX = Expression("cos(t)*cos(a*t)")
		'TY = Sin(T) * Cos(A*T)
		
		'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
		
		X = ((TX - MinX) / (MaxX - MinX)) * (GX - 1)
		Y = GY - ((TY - MinY) / (MaxY - MinY)) * (GY - 1)
		
		If I = 1
			OX = X
			OY = Y
		EndIf
		
		SetColor(Abs(Sin(T * 6.0)) * 255.0, Abs(Cos(T * 4.0)) * 255.0, Abs(Sin(T * 3.4)) * 255.0)
		
		DrawLine(OX, OY, X, Y)
	
	Next
	
	SetColor(255, 255, 255)
	DrawText("Use the mouse wheel to zoom.", 10, 10)
	DrawText("Hold down the middle mouse button and move the mouse to move the curve.", 10, 25)
	DrawText("Press the space key to toggle animation.", 10, 40)
	DrawText("Press the shift key to reset animation.", 10, 55)
	DrawText("A: " + A, 10, 100)
	DrawText("Ticks: " + Ticks, 10, 115)
	DrawText("Start: " + TStart, 10, 130)
	DrawText("End: " + TEnd, 10, 145)

	Flip
	
Until KeyHit(KEY_ESCAPE) Or AppTerminate()

Function Equal:Int(Num:Float, Num2:Float, Margin:Float = 0.005)
	If Num > Num2 - (Margin / 2) And Num < Num2 + (Margin / 2)
		Return 1
	EndIf
	Return 0
EndFunction

Function Pow:Double(Base:Double, Exponent:Double)
	Return Base ^ Exponent
EndFunction

Function TextInput:String(Prompt:String, X:Int, Y:Int)
	Local I:String
	While KeyHit(KEY_ENTER) = 0
		Cls
		Local C:Int = GetChar()
		If C > 0
			If C = 8
				I = I[..I.length - 1]
			Else
				I :+ Chr(c)
			EndIf
		EndIf
		DrawText(Prompt + I, X, Y)
		Flip
	EndWhile
	Return I
EndFunction


L-Systems

SuperStrict

Global DrawLength:Float = 20.0
Global AngleChange:Float = 60.0
Global StartX:Float = 500.0
Global StartY:Float = 500.0
Global StartA:Float = 180.0
Global SavedX:Float[10000]
Global SavedY:Float[10000]
Global SavedAngle:Float[10000]
Global NumSaved:Int = 0

Graphics 1024, 768, 1
SeedRnd(MilliSecs())

Local Scroll:Float
Local MoveX:Float, MoveY:Float
Local Iterations:Int = 1
Local Axiom:String = "A"
Local ProdRule:String = "A[-A-A+A++A]A[+A+A--A-A]A"
Local SystemString:String = CreateLSystemString(Axiom, ProdRule, Iterations)

SetClsColor(0, 0, 30)
SetColor(220, 220, 255)

Repeat

	Cls
	
	DrawText("Scroll Mouse Wheel to change DrawLength", 0, 0)
	DrawText("SHIFT + Scroll Mouse Wheel to change AngleChange", 0, 12)
	DrawText("UP and DOWN keys to increase/decrease number of iterations.", 0, 24)
	DrawText("LEFT and RIGHT keys to rotate L-system.", 0, 36)
	DrawText("CONTROL to change production rule.", 0, 48)
	
	Scroll = MouseZSpeed()
	MoveX = MouseXSpeed()
	MoveY = MouseYSpeed()
	
	If Scroll
		If KeyDown(KEY_LSHIFT)
			AngleChange = AngleChange + Scroll
		Else
			DrawLength = DrawLength + (Scroll * (DrawLength / 20.0))
		EndIf
	EndIf
	
	If MouseDown(3)
		StartX = StartX + MoveX
		StartY = StartY + MoveY
	EndIf
	
	If KeyHit(KEY_UP)
		Iterations :+ 1
		SystemString = CreateLSystemString(Axiom, ProdRule, Iterations)
	EndIf
	If KeyHit(KEY_DOWN)
		Iterations :- 1
		SystemString = CreateLSystemString(Axiom, ProdRule, Iterations)
	EndIf
	
	If KeyDown(KEY_LEFT)
		StartA = StartA - 1
	EndIf
	If KeyDown(KEY_RIGHT)
		StartA = StartA + 1
	EndIf
	
	If KeyHit(KEY_LCONTROL)
		ProdRule = TextInput("A -> ", 10, 10)
		SystemString = CreateLSystemString(Axiom, ProdRule, Iterations)
	EndIf

	LSystem(SystemString)

	Flip

Until KeyHit(KEY_ESCAPE) Or AppTerminate()

Function CreateLSystemString:String(Axiom:String, ProductionRule:String, Iterations:Int)
	
	Local _LSystemString:String = Lower(Axiom)
	ProductionRule = Lower(ProductionRule)

	For Local I:Int = 1 To Iterations
	
		_LSystemString = Replace(_LSystemString, "a", ProductionRule)
		
	Next
	
	Return _LSystemString
	
EndFunction

Function LSystem(LS:String)
	
	
	Local X:Float, Y:Float, A:Float
	
	X = StartX
	Y = StartY
	A = StartA
	
	Local OX:Float, OY:Float
	
	OX = X
	OY = Y
	
	For Local I:Int = 1 To Len(LS)
	
		Local Char:String = Mid(LS, I, 1)
		
		If Char = "a"
			X = X + Sin(A) * DrawLength
			Y = Y + Cos(A) * DrawLength
			DrawLine(OX, OY, X, Y)
			OX = X
			OY = Y
		EndIf
		
		If Char = "+"
			A = A + AngleChange
		EndIf
		
		If Char = "-"
			A = A - AngleChange
		EndIf
		
		If Char = "["
			SavedX[NumSaved] = X
			SavedY[NumSaved] = Y
			SavedAngle[NumSaved] = A
			NumSaved :+ 1
		EndIf
		
		If Char = "]"
			X = SavedX[NumSaved - 1]
			Y = SavedY[NumSaved - 1]
			A = SavedAngle[NumSaved - 1]
			OX = X
			OY = Y
			NumSaved :- 1
		EndIf
		
	Next
	
EndFunction

Function TextInput:String(Prompt:String, X:Int, Y:Int)
	Local I:String
	While KeyHit(KEY_ENTER) = 0
		Cls
		Local C:Int = GetChar()
		If C > 0
			If C = 8
				I = I[..I.length - 1]
			Else
				I :+ Chr(c)
			EndIf
		EndIf
		DrawText(Prompt + I, X, Y)
		Flip
	EndWhile
	Return I
EndFunction


Cellular Vector Fields

SuperStrict

Global Cells:Float[64, 64]

For Local X:Int = 0 To 63
	For Local Y:Int = 0 To 63
		Cells[X, Y] = Rnd() * 360.0
	Next
Next

Function DrawField()
	SetScale(2.0, 2.0)
	For Local X:Int = 0 To 63
		For Local Y:Int = 0 To 63
			Local TX:Float = (Float(X) / 63.0) * Float(GraphicsWidth()) + Float(GraphicsWidth()) / 128.0
			Local TY:Float = (Float(Y) / 63.0) * Float(GraphicsHeight()) + Float(GraphicsHeight()) / 128.0
			SetColor(100, 100, 100)
			DrawLine(TX + Cos(Cells[X, Y]) * 4, TY + Sin(Cells[X, Y]) * 4, TX, TY)
		Next
	Next
EndFunction

Function SetCell(X:Int, Y:Int, Ang:Float)
	If X > 63
		X = X Mod 63
	EndIf
	If Y > 63
		Y = Y Mod 63
	EndIf
	If X < 0
		X = 64 + X
	EndIf
	If Y < 0
		Y = 64 + Y
	EndIf
	Cells[X, Y] = Ang
EndFunction

Type Particle

	Field X:Float
	Field Y:Float
	
	Field Ang:Float
	
	Global List:TList
	Global TurnSpeed:Float = 3.0
	Global Velocity:Float = 1.2
	
	Function Init()
		List = CreateList()
	EndFunction
	
	Function AddParticles(Num:Int)
		For Local I:Int = 1 To Num
			Local P:Particle = New Particle
			P.X = Rand(0, GraphicsWidth() - 1)
			P.Y = Rand(0, GraphicsHeight() - 1)
			List.AddLast(P)
		Next
	EndFunction
	
	Function RemoveParticles(Num:Int)
		For Local I:Int = 1 To Num
			List.RemoveLast()
		Next
	EndFunction
	
	Function UpdateAll()
		Local TX:Float, TY:Float
		For Local P:Particle = EachIn List
			
			If P.X > GraphicsWidth()
				P.X = 0
			EndIf
			If P.Y > GraphicsHeight()
				P.Y = 0
			EndIf
			If P.X < 0
				P.X = GraphicsWidth()
			EndIf
			If P.Y < 0
				P.Y = GraphicsHeight()
			EndIf
			
			Local Angle:Float = Cells[Int((P.X / Float(GraphicsWidth())) * 63.0), Int((P.Y / Float(GraphicsHeight())) * 63.0)]
			
			If Angle > P.Ang + TurnSpeed
				P.Ang :+ TurnSpeed
			EndIf
			If Angle < P.Ang - TurnSpeed
				P.Ang :- TurnSpeed
			EndIf
			
			If P.Ang > 360.0
				P.Ang = P.Ang Mod 360.0
			EndIf
	
			P.X :+ Cos(P.Ang) * Velocity
			P.Y :+ Sin(P.Ang) * Velocity

			SetColor(255, 255, 255)
			Plot(P.X, P.Y)
		
		Next
	EndFunction
	
EndType

Graphics 640, 480, 1

Particle.Init()
Particle.AddParticles(2000)

Local MZS:Float
Local MXS:Float, MYS:Float

Local Arrows:Int = 0

Repeat

	Cls
	
	SetColor(255, 255, 255)
	SetScale(1.0, 1.0)
	DrawText("Press the space key to toggle the indicators.", 10, 10)
	DrawText("Scroll the mouse wheel to add/remove particles.", 10, 25)
	DrawText("Hold the left mouse button and drag the mouse to change the angle values.", 10, 40)
	
	If KeyHit(KEY_SPACE)
		Arrows = 1 - Arrows
	EndIf
	
	MXS = MouseXSpeed()
	MYS = MouseYSpeed()
	
	MZS = MouseZSpeed()
	If MZS > 0
		Particle.AddParticles(MZS * 200)
	Else
		If MZS < 0
			Particle.RemoveParticles(-MZS * 200)
		EndIf
	EndIf
	
	If MouseDown(1)
		If MXS And MYS
			Local Ang:Float = ATan2(Float(MYS), Float(MXS))
			Local CX:Int = Int((Float(MouseX()) / Float(GraphicsWidth())) * 63.0)
			Local CY:Int = Int((Float(MouseY()) / Float(GraphicsHeight())) * 63.0)
			SetCell(CX, CY, Ang)
			SetCell(CX - 1, CY, Ang)
			SetCell(CX + 1, CY, Ang)
			SetCell(CX, CY - 1, Ang)
			SetCell(CX, CY + 1, Ang)
			SetCell(CX - 1, CY - 1, Ang)
			SetCell(CX + 1, CY - 1, Ang)
			SetCell(CX - 1, CY + 1, Ang)
			SetCell(CX + 1, CY + 1, Ang)
		EndIf
	EndIf

	If Arrows
		DrawField()
	EndIf
	
	Particle.UpdateAll()

	Flip
	
Until KeyHit(KEY_ESCAPE) Or AppTerminate()


Function-Based Vector Fields

SuperStrict

Global MinX:Float = -1.0, MinY:Float = 1.0, MaxX:Float = 1.0, MaxY:Float = -1.0

Type Particle

	Field X:Float
	Field Y:Float
	
	Field VX:Float
	Field VY:Float
	
	Global List:TList
	
	Function Init()
		List = CreateList()
	EndFunction
	
	Function AddParticles(Num:Int)
		For Local I:Int = 1 To Num
			Local P:Particle = New Particle
			P.X = Rand(0, GraphicsWidth() - 1)
			P.Y = Rand(0, GraphicsHeight() - 1)
			List.AddLast(P)
		Next
	EndFunction
	
	Function RemoveParticles(Num:Int)
		For Local I:Int = 1 To Num
			List.RemoveLast()
		Next
	EndFunction
	
	Function RemoveFirstParticles(Num:Int)
		For Local I:Int = 1 To Num
			List.RemoveFirst()
		Next
	EndFunction
	
	Function RemoveRandomParticles(Num:Int)
		For Local I:Int = 1 To Num
			List.Remove(List.ValueAtIndex(Rand(0, List.Count() - 1)))
		Next
	EndFunction
	
	Function UpdateAll()
		RemoveRandomParticles(10)
		AddParticles(10)
		Local TX:Float, TY:Float, R:Float
		For Local P:Particle = EachIn List
			
				If P.X > GraphicsWidth()
					P.X = 1
				EndIf
				If P.Y > GraphicsHeight()
					P.Y = 1
				EndIf
				If P.X < 0
					P.X = GraphicsWidth()
				EndIf
				If P.Y < 0
					P.Y = GraphicsHeight()
				EndIf
				
				TX = (P.X - (GraphicsWidth() / 2))
				TX = TX / (Float(GraphicsWidth()) / 2)
				TX = TX * (MaxX - MinX)
				TY = (P.Y - (GraphicsHeight() / 2))
				TY = TY / (Float(GraphicsHeight()) / 2)
				TY = TY * (MaxY - MinY)

				R = Sqr(TX^2 + TY^2)
			
				''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
				'EDIT THIS PART TO CHANGE THE APPEARANCE OF THE FIELD
				'TX = the particle's X position from -1.0 to 1.0
				'TY = the particle's Y position from -1.0 to 1.0
				''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
				
				P.VX = TY
				P.VY = -TX
				
				'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
	
				P.X :+ P.VX
				P.Y :+ P.VY
				
				Local Ang:Float = ATan2(P.VY, P.VX)
				Local Vel:Float = Sqr(P.VX * P.VX + P.VY * P.VY)
				DrawLine(P.X + Cos(Ang) * Vel * 4, P.Y + Sin(Ang) * Vel * 4, P.X, P.Y)
				
				'Plot(P.X, P.Y)
		Next
	EndFunction
	
EndType

Graphics 1024, 768, 32

Particle.Init()

Particle.AddParticles(5000)

Local MZS:Float

Repeat

	Cls
	
	MZS = MouseZSpeed()
	
	If MZS
		MinX :+ Float(MZS) / 10.0
		MinY :- Float(MZS) / 10.0
		MaxX :- Float(MZS) / 10.0
		MaxY :+ Float(MZS) / 10.0
	EndIf

	Particle.UpdateAll()

	Flip
	
Until KeyHit(KEY_ESCAPE) Or AppTerminate()



Retimer(Posted 2009) [#13]
Beautiful stuff!


_PJ_(Posted 2009) [#14]
This is all really fascinating to me, Andrew!

I do have a coupla little questions though:

Mathematically, can the vector fields be considered continuous? Does that work with the code or is it only possible to constrain them to the individual pixels/ var coords?

and, how are you dealing with i or j for SQR(0-1) with respect to your fractal stuff?
I was looking into something kinda related a while back, and after trawling the net for methods of working with complex no's and i or j even what I could find was all in other languages which I couldn't easily convert...

If it's a 'trade secret' for you, no probs :)


Thareh(Posted 2009) [#15]
Good Stuff!
Look at the last one (Function-Based Vector Fields) with a litte higher speed for a while, and your vision will be messed up for a while :D


AndrewT(Posted 2009) [#16]
Mathematically, can the vector fields be considered continuous? Does that work with the code or is it only possible to constrain them to the individual pixels/ var coords?


I'm not quite sure what you mean--can you clarify a bit? Keep in mind that my knowledge of math is currently limited to Honors Pre-Calc :P

and, how are you dealing with i or j for SQR(0-1) with respect to your fractal stuff?
I was looking into something kinda related a while back, and after trawling the net for methods of working with complex no's and i or j even what I could find was all in other languages which I couldn't easily convert...


I came up with the following complex number UDT:

Type Complex

	Field A:Float 'real part
	Field B:Float 'imaginary part coefficient
	
	Method Multiply(C:Complex)
	
		Local Copy:Complex = New Complex
		Copy.A = C.A
		Copy.B = C.B
		
		Local TempA:Float = A
	
		A = (A * Copy.A) + (-1 * B * Copy.B)
		B = (TempA * Copy.B) + (B * Copy.A)
		
		'(a + bi)(c + di) = ac + i(ad + bc) + (-1)bd
		
	EndMethod
	
	Method Add(C:Complex)
		
		Local Copy:Complex = New Complex
		Copy.A = C.A
		Copy.B = C.B
		
		A = A + C.A
		B = B + C.B
		
		'(a + bi) + (c + di) = (a + c) + (b + d)i
		
	EndMethod
	
	Method Absolute:Float()
		
		Return Sqr(A * A + B * B)
		
	EndMethod
	
	Method AbsoluteSq:Float()
		
		Return A * A + B * B
		
	EndMethod
EndType


Because the concept of i in this case is purely abstract, there's no need to explicitly define its value. The only operation which will actually take its value into account is multiplication when we have to square it, and we know that i * i is -1, so that doesn't present a problem either. Hope that helps, and if you have any other questions I'll do my best to answer them.

I'm going to try and clean up these demos a bit by adding comments and implementing some more features so that they can be posted on my website. If you have any requests for demos feel free to ask and I'll see what I can do. :)


Jesse(Posted 2009) [#17]
this is really nice. thanks for posting the code.
I can spend hours messing with this.
Hopefully I can do some creative stuff with it.

Thanks a lot.
If you care here is some code for a sphere with nice effects. It may be down your alley and it's quite interesting to play with.


Strict
Global dots_in_ball# = 4440.0								' How many dots are in the ball?

' Globals For the 3d.

Type Tnode
	Field threeDx#
	Field threeDy#
	Field threeDz#
	Field color
	Global twoDx1#
	Global twoDy1#
	Global twoDx2#
	Global twoDy2#
	
End Type

Global numpoints# = dots_in_ball								' Number of points in the point table.
Global distance#  = 400.0										' Needed For perspective.
Global vx#													' X location.
Global vy#													' Y location.
Global vz#													' Z location.
Global multiplier!=150.0
' Arrays used by 3d code.
Global points#[numpoints, 3]									' Holds the point locations of the game over 3d.

Graphics 640,480,32

initdots()

While Not KeyDown(KEY_ESCAPE)
	threed()												' Call the threed thing.
	SetColor 255,255,255
	DrawText "Depth Colored Real 3D Dot Ball",0,0
	DrawText "origina Coding by Tracer For the Blitz CD.",0,15
	DrawText "modified by me",0,30 
	DrawText "Use up/down arrow Keys To adjust multiplier",0,45
	DrawText "multiplier = "+multiplier,0,60
	Local dummy = MouseX()										' Removes the mouse from fullscreen.
	If KeyDown(KEY_DOWN) Then 
		multiplier =multiplier-0.00005
		initdots()
	EndIf
	If KeyDown(KEY_UP) Then
		multiplier=multiplier+0.00005
		initdots() 
	EndIf
	
	Flip(0)													' Flip the screen.
	Cls														' Clear the screen.
Wend
Function initdots()
For Local t= 0 To dots_in_ball-1
	Local xd# = ((t*multiplier) Mod 180.0)-90.0    'Rnd(-90,90)
	points[t,0] = (Cos(xd) * 10.0) * (Cos(t) * 10.0)
	points[t,1] = (Cos(xd) * 10.0) * (Sin(t) * 10.0)
	points[t,2] = Sin(xd) * 100.0
Next

End Function 

Function threed()
	vx# = vx# + 0.5											' X rotation speed of ball.
	vy# = vy# + 0.5											' Y rotation speed of ball.
	vz# = vz# + 0.5											' Z rotation speed of ball.

	For Local n = 0 To numpoints-1
		Local x3d = points[n, 0]
		Local y3d = points[n, 1]
		Local z3d = points[n, 2]
       
		Local ty# = ((y3d * Cos(vx#)) - (z3d * Sin(vx#)))
		Local tz# = ((y3d * Sin(vx#)) + (z3d * Cos(vx#)))
		Local tx# = ((x3d * Cos(vy#)) - (tz# * Sin(vy#)))
		tz# = ((x3d * Sin(vy#)) + (tz# * Cos(vy#)))
		Local ox# = tx#
		tx# = ((tx# * Cos(vz#)) - (ty# * Sin(vz#)))
		ty# = ((ox# * Sin(vz#)) + (ty# * Cos(vz#)))
		Local nx  = Int(512 * (tx#) / (distance - (tz#))) + 320
		Local ny  = Int(240 - (512 * ty#) / (distance - (tz#)))
		SetColor 0,tz+100,(tz#+100)
		Plot nx,ny'
	Next
End Function

' This Function looks at the z-value of the pixel
' And sets the color accoordingly.
Function Color(t#)
	SetColor 0,0,(t+200.0)',(t+200.0),(t+200.0)
End Function



AndrewT(Posted 2009) [#18]
Sorry I haven't posted anything in awhile, I've been busy. That's an awesome demo jesse, thanks!

I've improved upon the fractal explorer a bit, I'll post the source sometime in the next week.

Burning Ship (zoomed in):



Mandelbrot (zoomed in):




AndrewT(Posted 2009) [#19]
Sorry about the double post, but I've been working on some more fractals, this time using Iterated Function Systems (IFS). Here are a couple randomly generated fractals I've made thus far:






Ryan Burnside(Posted 2009) [#20]
Some really cool looking stuff there. :)


Yahfree(Posted 2009) [#21]
Woah, if you stare in the center of the Function-Based Vector Fields example, then look around, everything moves... it's like a trippy optical illusion