Strange Attractors?


#1

Hey guys,

I am curious: has anyone ever tried creating a strange attractor effect using pflow?
Here is a link to a manual to a program to create strange-attractor effects:
http://www.btinternet.com/~ndesprez/manual/attractors.htm

I have been trying with the pickover type, but I can’t get max to behave correctly. After about 4 or 5 iterations max just ends up putting the same values over and over again, placing particles in the same location.

This code is for instances of an object, but once I learn my way around maxscripting pflow, I plan to impliment this into one.


global oldPos = $.position
A = 0.987654320987654
B = 1.09876543209877
C = 1.32098765432099
D = 1.5
newpos = [0.0, 0.0, 0.0]
Iter = 100

for i = 1 to Iter do
(
newobj = instance $
--Pickover
newpos.x = (sin(A * oldPos.y) - oldPos.z * cos(B * oldPos.x))
newpos.y = (oldPos.z * sin (C * oldPos.x) - cos (D * oldPos.y))
newpos.z = sin (oldPos.x)

newobj.position = newpos
oldpos = newobj.position
print oldpos
completeredraw()
)

Basically this creates 100 instances of the selected object and distributes them along whats supposed to be the path of the attractor.


#2

Sounds intresting, I might give it a try. I did one maxscript for Lorenz with splines some while ago.

http://www.niksula.cs.hut.fi/~jylilamm/lorenzattractor.shtml

With pflow you’d have to take slightly different path to achieve the effect.


#3

Yeah, I have a copy of your lorenz attractor - its pretty fun.
Unfortunately Lorenz, while famous, isn’t very helpful for the effect that I’m going for.


#4

Well here is the pflow birth script for the lorenz. Make sure you have Speed operator with 0 speed in the flow. Pflow seem to have a bug where it randomly sometimes give particles very high speeds unless you set it to 0. Probably some non initialized value used as speed, who knows.

on ChannelsUsed pCont do (
	pCont.usePosition = true
)
on Init pCont do (
	global thePoint = [.1,.1,.1]
	global a = 10.0
	global b = 28.0
	global c = 2.667
	global s = .018 -- scale
	global iterPerStep = 100
	global Lorenz
	execute "fn Lorenz p = ( [p.x+(a*(p.y - p.x))*s, p.y+(p.x*(b-p.z)-p.y)*s, p.z+(p.x*p.y-p.z*c)*s] )"
)
on Proceed pCont do (		
	for i in 1 to iterPerStep do (				
		pCont.AddParticle()
		pCont.setParticlePosition (pCont.NumParticles()) thePoint
		thePoint = Lorenz thePoint	
	)
)
on Release pCont do ()

#5

Lorenz worked liked a charm.

I changed your code around just a bit, so that instead of the script defining the number of particles, the birth will.


#6

I am beginning to think that max cannot handle really tiny numbers. I’m still getting it to so that after a particle or two they all sink to a position just outside of [0,0,0].


#7

In max sin cos tan work in degrees so you have to convert to them first. This version also uses doubles (64bit vs 32bit floats what max usually uses) so it should be pretty accurate.

on ChannelsUsed pCont do (
	pCont.usePosition = true
)
on Init pCont do (
	global px = .347d0
	global py = .599d0
	global pz = .853d0
	global npx = 0.0d0
	global npy = 0.0d0
	global npz = 0.0d0
	-- 1, 1.8, 0.71, 1.51
	global A = 1.3251d0
	global B = 1.51235d0
	global C = -1.0d0
	global D = 1.56431d0
	global deg = 360.0d0 / pi
	global ITERATIONS = 1000
)
on Proceed pCont do (		
	for i in 1 to ITERATIONS do (		
		npx = (sin(A * py * deg) - pz * cos(B * px * deg))
		npy = (pz * sin (C * px * deg) - cos (D * py * deg))
		npz = sin (px * deg)
		pCont.AddParticle()
		pCont.setParticlePosition (pCont.NumParticles()) [npx * 100.0,npy * 100.0,npz * 100.0]				
		px = npx
		py = npy
		pz = npz		
	)
)
on Release pCont do ()

#8

GENIOUS!
thank you bercon!


#9

If you come up with any good looking particles clouds you could post the script/values here. I tried the above code but never managed to get anything as pretty as in the Chaoscopes example.


#10
on ChannelsUsed pCont do (
	pCont.usePosition = true
)
on Init pCont do (	
	-- Adjust these values to get different shapes
	global A = -0.25
	global B =  0.7
	global C =  0.6
	global D =  0.4

	-- Number of particles created per frame
	global ITERATIONS = 10000
	
	-- Originally used doubles but max had some problems with those
	global px = 0.156452879309654
	global py = -0.466939155012369
	global pz = 0.144256137311459
	global npx = 0.0
	global npy = 0.0
	global npz = 0.0
	global deg = 360.0 / pi
	-- To make things faster, premultiply params with degree conversion
	A=A*deg;B=B*deg;C=C*deg;D=D*deg;	
)
on Proceed pCont do (		
	for i in 1 to ITERATIONS do (		
		-- Perform "Pickup" strange attractor transformation
		npx = (sin(A * py) - pz * cos(B * px))
		npy = (pz * sin (C * px) - cos (D * py))
		npz = sin (px * deg)
		-- Create particle to location given by the transformation
		pCont.AddParticle()
		pCont.setParticlePosition (pCont.NumParticles()) [npx * 100.0,npy * 100.0,npz * 100.0]				
		-- Update the point we calculate the next transformation to
		px = npx
		py = npy
		pz = npz		
	)
)
on Release pCont do ()


#11

Looking good, looking good!

Just wondering, why do you have iterations, why not use the number of particles in the birth parameter?


#12

whoh guys, this stuff is crazy cool! just trying them out at work. Keep it up


#13

woops, never mind… you have to place it into a default flow to work;
it won’t work with only a render op and a birth script only!

When I copy and paste this into a new birth script I get the folllowing error

– Syntax error: at on, expected while
– In line: on Init pCont do (

But this must have works for you!

Thanks


#14

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.