{"id":682,"date":"2012-04-17T03:53:56","date_gmt":"2012-04-17T03:53:56","guid":{"rendered":"http:\/\/www.new-territories.com\/blog\/rmit.uts\/?page_id=682"},"modified":"2012-04-30T02:50:11","modified_gmt":"2012-04-30T02:50:11","slug":"brico_uric-equilibria-coding","status":"publish","type":"page","link":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/code\/brico_uric-equilibria-coding\/","title":{"rendered":"brico_uric equilibria coding"},"content":{"rendered":"<div>\/*<\/div>\n<div>\u00a0* Copyright (c) 2012 Gwyllim Jahn<\/div>\n<div>\u00a0*\u00a0<a href=\"http:\/\/scripts.crida.net\/gh\" target=\"_blank\">http:\/\/scripts.crida.net\/gh<\/a><\/div>\n<div>\u00a0<\/div>\n<div>\u00a0* Developed By Gwyllim Jahn, Javed de Costa, and Intje Siswandi<\/div>\n<div>\u00a0* during the 2012 RMIT nCertainties studio.<\/div>\n<div>\u00a0*<\/div>\n<div>\u00a0* This\u00a0code\u00a0makes extensive use of several freely distributed<\/div>\n<div>\u00a0* processing libraries &#8211; thankyou especially to toxi.<\/div>\n<div>\u00a0<\/div>\n<div>\u00a0* This\u00a0code\u00a0is free software; you can redistribute it and\/or<\/div>\n<div>\u00a0* modify it under the terms of the GNU Lesser General Public<\/div>\n<div>\u00a0* License as published by the Free Software Foundation; either<\/div>\n<div>\u00a0* version 2.1 of the License, or (at your option) any later version.<\/div>\n<div>\u00a0*<\/div>\n<div>\u00a0*\u00a0<a href=\"http:\/\/creativecommons.org\/licenses\/LGPL\/2.1\/\" target=\"_blank\">http:\/\/creativecommons.org\/<wbr>licenses\/LGPL\/2.1\/<\/wbr><\/a><\/div>\n<div>\u00a0*<\/div>\n<div>\u00a0* This\u00a0code\u00a0is distributed in the hope that it will be useful,<\/div>\n<div>\u00a0* but WITHOUT ANY WARRANTY; without even the implied warranty of<\/div>\n<div>\u00a0* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. \u00a0See the GNU<\/div>\n<div>\u00a0* Lesser General Public License for more details.<\/div>\n<div>\u00a0*<\/div>\n<div>\u00a0* You should have received a copy of the GNU Lesser General Public<\/div>\n<div>\u00a0* License along with this library; if not, write to the Free Software<\/div>\n<div>\u00a0* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA \u00a002110-1301 \u00a0USA<\/div>\n<div>\u00a0*\/<\/div>\n<p>&nbsp;<\/p>\n<p>\/\/\/\/\/ 2.5 d reaction diffusion: custom grey scott as voxel array with agent interaction. iterative, cyclic model &#8211; diffusion and agent interaction alternates<\/p>\n<p>MAIN:<\/p>\n<p>import processing.video.*;<\/p>\n<p>import processing.dxf.*;<\/p>\n<p>import processing.opengl.*;<br \/>\nimport javax.media.opengl.*;<br \/>\nimport peasy.org.apache.commons.math.*;<br \/>\nimport peasy.*;<br \/>\nimport peasy.org.apache.commons.math.geometry.*;<\/p>\n<p>import toxi.math.conversion.*;<br \/>\nimport toxi.geom.*;<br \/>\nimport toxi.geom.mesh2d.*;<br \/>\nimport toxi.util.datatypes.*;<br \/>\nimport toxi.util.events.*;<br \/>\nimport toxi.geom.mesh.subdiv.*;<br \/>\nimport toxi.geom.mesh.*;<br \/>\nimport toxi.util.*;<br \/>\nimport toxi.math.noise.*;<br \/>\nimport toxi.volume.*;<\/p>\n<p>\/**<\/p>\n<p>*\/<\/p>\n<p>import toxi.sim.grayscott.*;<br \/>\nimport toxi.math.*;<br \/>\nimport controlP5.*;<br \/>\nimport toxi.color.*;<br \/>\n\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;Volume Params<\/p>\n<p>int DX=120;<br \/>\nint DY=60;<br \/>\nint DZ=60;<br \/>\nOscillatingVolume volumeU;<br \/>\nOscillatingVolume volumeV;<br \/>\nOscillatingVolume volumeF;<br \/>\nVolumetricBrush brushU;<br \/>\nVolumetricBrush brushV;<br \/>\nVolumetricBrush brushF;<br \/>\nVec3D SCALE=new Vec3D(DX,DY,DZ);<br \/>\nint sX = int(SCALE.x\/DX);<br \/>\nint sY = int(SCALE.y\/DY);<br \/>\nint sZ = int(SCALE.z\/DZ);<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;Agent params<\/p>\n<p>\/\/==============================<br \/>\n\/\/Trail length and agent speed &#8211; obviously if you want<br \/>\n\/\/to run the agents for ages, you will need longer trails.<br \/>\n\/\/agent speed also has a significant effect on the root geom.<br \/>\nint trailLength = 200;<br \/>\nfloat agentSpeed = 1;<br \/>\n\/\/ammount to confine to a particular threshold<br \/>\nfloat confineToThreshold = 0.1;<br \/>\n\/\/distance between trail points<br \/>\nint dropSpacing = 2;<br \/>\n\/\/number of agents<br \/>\nint numAgents = 50;<\/p>\n<p>\/\/if the agent cant find a value in its neighbouring<br \/>\n\/\/voxels that is less than this number from the ideal<br \/>\n\/\/threshold (by default 0.5) =dead. LOWER=MORE DEATH<br \/>\nfloat cutoffToDie = 0.2;<br \/>\n\/\/if the agent finds a value in its neighbouring<br \/>\n\/\/voxels that is less than this number from the ideal<br \/>\n\/\/threshold (by defauly 0.5), then it starts counting<br \/>\n\/\/towards branching LOWER=LESS BRANCHING<br \/>\nfloat cutoffToThinkAboutBranching = 0.0;<br \/>\n\/\/The agent needs to have been within its branching cutoff<br \/>\n\/\/for this number of steps, then it branches.<br \/>\nint numEasyMovesBeforeBranch =10;<br \/>\n\/\/number of new agents to make.<br \/>\nint splitIntoAgents=3;<\/p>\n<p>\/\/==============================<br \/>\n\/\/parameters for how the agents modify the field&#8230;<br \/>\n\/\/how big the brush is that modifies the diffusion f parameter.<br \/>\nfloat fBrushSize = 2;<br \/>\nfloat rootRadius = 2;<br \/>\n\/\/density value for the agents &#8211; a negative<br \/>\n\/\/number removes material from the diffusion,<br \/>\n\/\/numbers closer to 0 mean that more agents need to fly<br \/>\n\/\/down a similar path to actually remove the material &#8230;<br \/>\nfloat density = -0.01;<br \/>\n\/\/controls the strength of the diffusion parameter.<br \/>\nfloat fDensity = -0.05;<br \/>\nBoolean drawAgents = true;<br \/>\nBoolean saveRaw = false;<br \/>\nMovieMaker mm;<br \/>\nBoolean filming =true;<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;Diffusion params<br \/>\nint NUM_ITERATIONS = 10;<br \/>\nControlP5 controlP5;<br \/>\nControlWindow controlWindow;<br \/>\nGrayScott gs;<br \/>\nToneMap toneMap;<br \/>\nPImage img;<\/p>\n<p>float f = 0.0210;<br \/>\nfloat k = 0.076;<br \/>\nfloat dU = 0.0976;<br \/>\nfloat dV = 0.0653;<\/p>\n<p>PeasyCam cam;<br \/>\nWorld world;<br \/>\nint currentLevel =0;<br \/>\nBoolean building = true;<br \/>\nBoolean firstRun = true;<br \/>\nBoolean cycle = true;<\/p>\n<p>\/\/==============================<br \/>\n\/\/make this false to make the simution<br \/>\n\/\/reset to the ground plane rather than oscillating<br \/>\nBoolean oscillate = false;<\/p>\n<p>\/\/==============================<br \/>\n\/\/sets how long the agents and the diffusion<br \/>\n\/\/run for. REMEMBER cant be larger than the actual field.<br \/>\nint agentSteps = 50;<br \/>\nint numSteps = DZ;<br \/>\nint cycleIterator = numSteps;<\/p>\n<p>void setup() {<br \/>\nsize(500,500,OPENGL);<br \/>\ncam = new PeasyCam(this,200);<br \/>\nmm = new MovieMaker(this, width, height, &#8220;drawing.mov&#8221;,30, MovieMaker.ANIMATION, MovieMaker.HIGH);<\/p>\n<p>gs=new PatternedGrayScott(DX,DY,false);<br \/>\nimg=loadImage(&#8220;r1_60.png&#8221;);<br \/>\ngs.setCoefficients(f,k,dU,dV);<br \/>\n\/\/ create a color gradient for 256 values<br \/>\nColorGradient grad=new ColorGradient();<br \/>\n\/\/ NamedColors are preset colors, but any TColor can be added<br \/>\n\/\/ see javadocs for list of names:<br \/>\n\/\/ http:\/\/toxiclibs.org\/docs\/colorutils\/toxi\/color\/NamedColor.html<br \/>\ngrad.addColorAt(0,NamedColor.WHITE);<br \/>\ngrad.addColorAt(16,NamedColor.CORNSILK);<br \/>\ngrad.addColorAt(128,NamedColor.PINK);<br \/>\ngrad.addColorAt(192,NamedColor.PURPLE);<br \/>\ngrad.addColorAt(255,NamedColor.BLACK);<br \/>\n\/\/ this gradient is used to map simulation values to colors<br \/>\n\/\/ the first 2 parameters define the min\/max values of the<br \/>\n\/\/ input range (Gray-Scott produces values in the interval of 0.0 &#8211; 0.5)<br \/>\n\/\/ setting the max = 0.33 increases the contrast<br \/>\ntoneMap=new ToneMap(0,0.33,grad);<br \/>\ngs.seedImage(img.pixels,img.width,img.height);<\/p>\n<p>\/\/setup voxels<br \/>\nvolumeU=new OscillatingVolume(SCALE,DX,DY,DZ);<br \/>\nvolumeV=new OscillatingVolume(SCALE,DX,DY,DZ);<br \/>\nvolumeF=new OscillatingVolume(SCALE,DX,DY,DZ);<br \/>\nbrushU=new RoundBrush(volumeU,5);<br \/>\nbrushV=new RoundBrush(volumeV,5);<br \/>\nbrushF=new RoundBrush(volumeF,5);<\/p>\n<p>volumeU.setLandscape(gs.u,0);<br \/>\nvolumeV.setLandscape(gs.v,0);<\/p>\n<p>setupP5();<\/p>\n<p>world = new World();<br \/>\n}<\/p>\n<p>void draw() {<br \/>\nbackground(255);<br \/>\ngs.setCoefficients(f,k,dU,dV);<br \/>\n\/\/diffusion cycle<br \/>\nif(building){<\/p>\n<p>if(!firstRun){<br \/>\n\/\/read in the layer<br \/>\ngs.u = volumeU.getLayer(currentLevel);<br \/>\ngs.v = volumeV.getLayer(currentLevel);<\/p>\n<p>}<\/p>\n<p>\/\/ update the simulation a few time steps<br \/>\nfor(int i=0; i&lt;NUM_ITERATIONS; i++) {<br \/>\ngs.update(1);<br \/>\n}<\/p>\n<p>\/\/if first run then just write the values, otherwise<br \/>\n\/\/modify the values.<br \/>\nif(firstRun){<br \/>\nvolumeU.setLandscape(gs.u,currentLevel);<br \/>\nvolumeV.setLandscape(gs.v,currentLevel);<br \/>\n}else{<br \/>\nvolumeU.modLandscape(gs.u,currentLevel);<br \/>\nvolumeV.modLandscape(gs.v,currentLevel);<br \/>\n}<\/p>\n<p>\/\/toggle moving up or down and change the level<br \/>\nif(oscillate){<br \/>\nif(cycle){<br \/>\ncurrentLevel++;<br \/>\n}else{<br \/>\ncurrentLevel&#8211;;<br \/>\n}<br \/>\n}else{<br \/>\ncurrentLevel++;<br \/>\n}<br \/>\ncycleIterator&#8211;;<br \/>\n\/\/completed the cycle<br \/>\nif(cycleIterator &lt;=0){<br \/>\nbuilding = false;<br \/>\nif(firstRun) {<br \/>\nfirstRun = false;<br \/>\nworld.spawnOnThreshold();<br \/>\n\/\/world.spawn();<br \/>\n}<br \/>\ncycle = !cycle;<br \/>\ncycleIterator = agentSteps;<br \/>\nif(!oscillate) currentLevel = 0;<br \/>\n}<\/p>\n<p>}else{<\/p>\n<p>\/\/setup the oscilation<br \/>\nworld.update();<\/p>\n<p>cycleIterator&#8211;;<br \/>\nif(cycleIterator&lt;=0){<br \/>\nbuilding = true;<br \/>\ncycleIterator = numSteps;<br \/>\n}<br \/>\n}<\/p>\n<p>volumeV.drawPoints();<\/p>\n<p>if(filming) mm.addFrame();<br \/>\n}<\/p>\n<p>void keyPressed() {<br \/>\nif(key == &#8216;r&#8217;){<br \/>\ngs.reset();<br \/>\n}<\/p>\n<p>if(key == &#8216;q&#8217;){<br \/>\nGsaveData(volumeV,&#8221;G:\/ncertainties\/export\/&#8221;+day()+&#8221;_&#8221;+hour()+&#8221;_&#8221;+minute()+&#8221;_&#8221;+second()+&#8221;voxels.raw&#8221;);<br \/>\n}<\/p>\n<p>if(key == &#8216;w&#8217;){<br \/>\nsavePts();<br \/>\n}<\/p>\n<p>if(key == &#8216;e&#8217;){<br \/>\nsaveParams();<br \/>\n}<\/p>\n<p>if(key == &#8216; &#8216;){<br \/>\nmm.finish();<br \/>\n}<br \/>\n}<\/p>\n<p>&nbsp;<\/p>\n<p>AGENTS:<\/p>\n<p>\/\/simple agent class to interact with the data<br \/>\n\/\/field and other agents<\/p>\n<p>class Agent {<\/p>\n<p>Vec3D loc,vel;<br \/>\nArrayList&lt;Vec3D&gt; trail;<br \/>\nfloat gVal;<br \/>\nfloat dropNum;<br \/>\nboolean alive;<br \/>\nint id;<br \/>\nfloat aX,aY,aZ,lastBest;<br \/>\nint easy;<\/p>\n<p>Agent(Vec3D _loc, Vec3D _vel,int _id){<br \/>\nloc = _loc;<br \/>\nvel = _vel;<br \/>\ntrail = new ArrayList&lt;Vec3D&gt;();<br \/>\ngVal = 255;<br \/>\ndropNum = 0;<br \/>\nalive = true;<br \/>\nid = _id;<br \/>\neasy = 0;<br \/>\nlastBest = 0;<br \/>\n}<\/p>\n<p>void run(){<br \/>\nif (alive){<br \/>\ngetGridPos();<br \/>\npushPullToData(true,0.0005);<\/p>\n<p>branch();<\/p>\n<p>volBrushLocation();<\/p>\n<p>update();<br \/>\n}<br \/>\nrender();<br \/>\n}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>\/\/Behaviour for avoiding the worst (highest greyscale value) data within a proximity,<br \/>\n\/\/and interpolating the agent velocity away that point.<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>void getGridPos(){<br \/>\naX = constrain(loc.x,0,SCALE.x);<br \/>\naX = map(aX,0,SCALE.x,0,DX);<br \/>\naY = constrain(loc.y,0,SCALE.y);<br \/>\naY = map(aY,0,SCALE.y,0,DY);<br \/>\naZ = constrain(loc.z,0,SCALE.z);<br \/>\naZ = map(aZ,0,SCALE.z,0,DZ);<br \/>\nif(loc.x&gt;SCALE.x || loc.y &gt;SCALE.y || loc.z&gt;SCALE.z)vel.invert();<br \/>\nif(loc.x&lt;0 || loc.y &lt;0 || loc.z&lt;0)vel.invert();<br \/>\n}<\/p>\n<p>void pushPullToData(Boolean push, float t){<\/p>\n<p>float bestThreshDiff = 100;<br \/>\nVec3D bestThreshPt = new Vec3D(0,0,0);<\/p>\n<p>\/\/iterate over neighbouring grid pos<br \/>\nfor (int i =-5;i&lt;=5;i++){<br \/>\nfor (int j =-5;j&lt;=5;j++){<br \/>\nfor (int k =-5; k&lt;=5;k++){<\/p>\n<p>\/\/if the value of this noisepoints better than the others, then update variables<br \/>\n\/\/scale val by distance<br \/>\nVec3D vec = new Vec3D(i,j,k);<\/p>\n<p>if((aX+i)&gt;=0&amp;&amp;(aX+i)&lt;DX&amp;&amp;(aY+j)&gt;=0&amp;&amp;(aY+j)&lt;DY&amp;&amp;(aZ+k)&gt;=0&amp;&amp;(aZ+k)&lt;DZ){<br \/>\nfloat val = volumeV.getVoxelAt(int(aX+i),int(aY+j),int(aZ+k));<br \/>\nif(val&gt;0.0001 &amp;&amp;val&lt;0.01){<br \/>\nfloat threshVal = abs(val-t);<\/p>\n<p>if(threshVal &lt;bestThreshDiff) bestThreshDiff=threshVal;<br \/>\n\/\/float threshVal = val;<br \/>\nvec.scaleSelf(1-(threshVal*threshVal));<br \/>\nbestThreshPt.addSelf(vec);<br \/>\n}<br \/>\n}<br \/>\n}<br \/>\n}<br \/>\n}<\/p>\n<p>\/\/attract to threshold<br \/>\nvel.interpolateToSelf(bestThreshPt,confineToThreshold);<\/p>\n<p>\/\/SOME VERY TOUCHY VALUES HERE BECAUSE OF THE NOISE<\/p>\n<p>\/\/ bestThreshDiff*=10;<\/p>\n<p>\/\/die if in a really crappy possy<br \/>\nif(bestThreshDiff&gt;cutoffToDie)alive=false;<\/p>\n<p>\/\/if in a good posy, see if we should branch<br \/>\nif(bestThreshDiff&lt;cutoffToThinkAboutBranching){<br \/>\neasy++;<br \/>\n}else{<br \/>\neasy = 0;<br \/>\n}<br \/>\n}<\/p>\n<p>Boolean moveToThreshold(int searchRad){<\/p>\n<p>getGridPos();<\/p>\n<p>for (int i =-searchRad;i&lt;=searchRad;i++){<br \/>\nfor (int j =-searchRad;j&lt;=searchRad;j++){<br \/>\nfor (int k =-searchRad;k&lt;=searchRad;k++){<\/p>\n<p>\/\/if the value of this noisepoints better than the others, then update variables<br \/>\n\/\/scale val by distance<br \/>\nVec3D vec = new Vec3D(i,j,k);<\/p>\n<p>if((aX+i)&gt;=0&amp;&amp;(aX+i)&lt;DX&amp;&amp;(aY+j)&gt;=0&amp;&amp;(aY+j)&lt;DY&amp;&amp;(aZ+k)&gt;=0&amp;&amp;(aZ+k)&lt;DZ){<br \/>\nfloat val = volumeV.getVoxelAt(int(aX+i),int(aY+j),int(aZ+k))*200;<\/p>\n<p>if(val&gt;=1&amp;&amp;val&lt;5){<br \/>\n\/\/move<br \/>\nloc.addSelf(vec);<br \/>\nreturn true;<br \/>\n}<br \/>\n}<br \/>\n}<br \/>\n}<br \/>\n}<br \/>\n\/\/if cant find anything then die<br \/>\nloc = new Vec3D(random(0,DX),random(0,DY),random(10,DZ));<br \/>\nreturn false;<\/p>\n<p>}<br \/>\n\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>\/\/creates new agents from this one if the agent path is easy.<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>void branch(){<\/p>\n<p>if(easy&gt;numEasyMovesBeforeBranch){<br \/>\neasy =0;<br \/>\nfor (int i = 1;i&lt;splitIntoAgents;i++){<\/p>\n<p>Vec3D aVel = vel.copy();<br \/>\naVel.rotateX(random(-0.5,0.5));<br \/>\naVel.rotateY(random(-0.5,0.5));<br \/>\naVel.rotateZ(random(-0.5,0.5));<\/p>\n<p>Agent a = new Agent(loc.copy(),aVel,id);<br \/>\nworld.newPop.add(a);<br \/>\n}<br \/>\nalive = false;<br \/>\n}<\/p>\n<p>}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>\/\/function for constraining agent movement to only z if they are moving within<br \/>\n\/\/very dense material<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>void volBrushLocation(){<br \/>\nbrushF.setSize(fBrushSize);<br \/>\nbrushF.drawAtGridPos(aX,aY,aZ,fDensity);<br \/>\nbrushV.setSize(rootRadius);<br \/>\nbrushV.drawAtGridPos(aX,aY,aZ,(density));<br \/>\nif(aZ-5&gt;0) brushV.drawAtGridPos(aX,aY,aZ-5,-density*2);<br \/>\n\/\/ brushV.drawAtGridPos(aX,aY,aZ,density);<br \/>\n}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>\/\/Functions for managing trails and rendering the agent.<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>void update(){<br \/>\n\/\/move the agent randomly<br \/>\nvel.normalizeTo(agentSpeed);<br \/>\n\/\/vel.interpolateToSelf(new Vec3D (0,0,1),vert);<br \/>\nloc.addSelf(vel);<\/p>\n<p>\/\/update the trail geom every 5 moves<br \/>\nif(dropNum%dropSpacing==0){<br \/>\nif(trail.size()&lt;trailLength){<br \/>\ntrail.add(new Vec3D(loc.x, loc.y, loc.z));<br \/>\n}else{<br \/>\ntrail.remove(0);<br \/>\n}<br \/>\ndropNum=0;<br \/>\n}<br \/>\ndropNum++;<\/p>\n<p>}<\/p>\n<p>void render(){<br \/>\n\/\/render agent trail as lines<br \/>\nVec3D ls = null;<br \/>\nfor (Vec3D l : trail){<br \/>\nif(ls !=null){<br \/>\nstroke(0);<br \/>\nline (l.x,l.y,l.z,ls.x,ls.y,ls.z);<br \/>\n}<br \/>\nls = l;<br \/>\n}<br \/>\n}<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>ARRAY OSCILLATIONS<\/p>\n<p>class OscillatingVolume extends VolumetricSpaceArray {<\/p>\n<p>int z;<\/p>\n<p>public OscillatingVolume (Vec3D _S, int _DX, int _DY,int _DZ) {<br \/>\nsuper(_S,_DX,_DY,_DZ);<br \/>\nz = 0;<br \/>\n}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n<p>void setLandscape(float[] d,int l){<\/p>\n<p>for (int i=0;i&lt;resX;i+=1){<br \/>\nfor (int j =0;j&lt;resY;j+=1){<br \/>\n\/\/set the voxel to the pixel<br \/>\nsetVoxelAt(i,j,l,d[(j*resX)+i]);<br \/>\n}<br \/>\n}<br \/>\n\/\/set the current layer<br \/>\nz = l;<br \/>\n}<\/p>\n<p>void modLandscape(float[] d,int l){<\/p>\n<p>for (int i=0;i&lt;resX;i+=1){<br \/>\nfor (int j =0;j&lt;resY;j+=1){<br \/>\n\/\/set the voxel to the pixel<br \/>\nfloat mod = d[(j*resX)+i];<br \/>\nfloat existing = getVoxelAt(i,j,l);<br \/>\nmod = (mod+existing)\/2;<br \/>\nsetVoxelAt(i,j,l,mod);<br \/>\n}<br \/>\n}<br \/>\nz = l;<br \/>\n}<\/p>\n<p>float[] getLayer(int level){<\/p>\n<p>float[] d = new float[resX*resY];<\/p>\n<p>for (int i=0;i&lt;resX;i+=1){<br \/>\nfor (int j =0;j&lt;resY;j+=1){<br \/>\n\/\/set the voxel to the pixel<br \/>\nd[(j*resX)+i] = getVoxelAt(i,j,level);<br \/>\n}<br \/>\n}<br \/>\nreturn d;<br \/>\n}<\/p>\n<p>void drawPoints() {<br \/>\nint r=1;<br \/>\nfor(int i=0;i&lt;resX;i+=r) {<br \/>\nfor(int j=0;j&lt;resY;j+=r) {<br \/>\nfor(int k=0;k&lt;resZ;k+=r) {<br \/>\nfloat v = getVoxelAt(i,j,k)*2000;<br \/>\nif(v&gt;=1&amp;&amp;v&lt;5){<br \/>\nstroke(100);<br \/>\npoint(i,j,k);<br \/>\n}<br \/>\n}<br \/>\n}<br \/>\n}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>VOXEL FUNCTIONS<\/p>\n<p>public void GsaveData(OscillatingVolume v,String fn) {<br \/>\nprint(&#8220;saving volume data&#8230;&#8221;);<br \/>\nint c=0;<br \/>\nint tot = v.getData().length;<br \/>\ntry {<br \/>\nBufferedOutputStream ds = new BufferedOutputStream(new FileOutputStream(fn));<br \/>\n\/\/ ds.writeInt(volumeData.length);<br \/>\nfor (float element : v.getData()) {<br \/>\nif(element&lt;0)element=0;<br \/>\nds.write((int)(element*100));<\/p>\n<p>}<br \/>\nds.flush();<br \/>\nds.close();<br \/>\n} catch (IOException e) {<br \/>\ne.printStackTrace();<br \/>\n}<br \/>\n}<\/p>\n<p>WORLD<\/p>\n<p>\/\/Class to manage addition and subtraction of agents from<br \/>\n\/\/the environment<\/p>\n<p>class World {<\/p>\n<p>ArrayList&lt;Agent&gt; agentPop;<br \/>\nArrayList&lt;Agent&gt; newPop;<\/p>\n<p>World(){<\/p>\n<p>agentPop = new ArrayList&lt;Agent&gt;();<br \/>\nnewPop = new ArrayList&lt;Agent&gt;();<\/p>\n<p>}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;main function<\/p>\n<p>void update(){<br \/>\nnewPop = new ArrayList&lt;Agent&gt;();<\/p>\n<p>runAgents();<\/p>\n<p>if(newPop.size()&gt;0) addAgents();<br \/>\n}<\/p>\n<p>void runAgents(){<br \/>\nint c = 0;<br \/>\nfor (Agent a :agentPop){<br \/>\na.run();<br \/>\n}<br \/>\n}<\/p>\n<p>void addAgents(){<br \/>\nagentPop.addAll(newPop);<br \/>\n}<br \/>\nvoid spawn(){<br \/>\nnewPop = new ArrayList();<br \/>\nagentPop = new ArrayList();<br \/>\nfor (int i=0;i&lt;numAgents;i++){<br \/>\n\/\/ Vec3D loc = new Vec3D(random(0,gW*gRes),random(0,gH*gRes),0);<br \/>\nVec3D loc = new Vec3D(random(0,DX),random(0,DY),3);<br \/>\nVec3D vel = new Vec3D(0,0,3);<br \/>\nAgent a = new Agent(loc,vel,i);<br \/>\nagentPop.add(a);<br \/>\n}<br \/>\n}<\/p>\n<p>void spawnOnThreshold(){<br \/>\nnewPop = new ArrayList();<br \/>\nagentPop = new ArrayList();<br \/>\nfor (int i=0;i&lt;numAgents;i++){<br \/>\n\/\/ Vec3D loc = new Vec3D(random(0,gW*gRes),random(0,gH*gRes),0);<br \/>\nVec3D loc = new Vec3D(random(0,DX),random(0,DY),random(10,DZ));<br \/>\nVec3D vel = new Vec3D(0,0,3);<br \/>\nAgent a = new Agent(loc.copy(),vel,i);<\/p>\n<p>\/\/try to find a threshold 5 times<br \/>\nboolean searching =true;<br \/>\nint c= 0;<\/p>\n<p>while(searching==true) {<br \/>\nif(a.moveToThreshold(5)){<br \/>\nsearching = false;<br \/>\nagentPop.add(a);<br \/>\n}else{<br \/>\nc++;<br \/>\n}<br \/>\nif(c&gt;50) searching = false;<br \/>\n}<\/p>\n<p>}<br \/>\n}<br \/>\n}<\/p>\n<p>DIFFUSION<\/p>\n<p>class PatternedGrayScott extends GrayScott {<br \/>\npublic PatternedGrayScott(int w, int h, boolean tiling) {<br \/>\nsuper(w,h,tiling);<br \/>\n}<\/p>\n<p>public float getFCoeffAt(int x, int y) {<br \/>\nif(x*y*currentLevel&lt;volumeF.getData().length){<br \/>\nreturn (f+volumeF.getVoxelAt(x,y,currentLevel));<br \/>\n}else{<br \/>\nreturn f;<br \/>\n}<br \/>\n}<br \/>\n\/*<br \/>\npublic float getKCoeffAt(int x, int y) {<br \/>\nVec3D val = new Vec3D(mouseX-x,mouseY-y,0);<br \/>\nfloat d = val.magnitude();<br \/>\nd = k-(map(d,0,height,0,1))*0.04;<br \/>\nreturn d;<br \/>\n}<\/p>\n<p>*\/<br \/>\n}<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\/* \u00a0* Copyright (c) 2012 Gwyllim Jahn \u00a0*\u00a0http:\/\/scripts.crida.net\/gh \u00a0 \u00a0* Developed By Gwyllim Jahn, Javed de Costa, and Intje Siswandi \u00a0* during the 2012 RMIT nCertainties studio. \u00a0* \u00a0* This\u00a0code\u00a0makes extensive use of several freely distributed \u00a0* processing libraries &#8211; thankyou especially to toxi. \u00a0 \u00a0* This\u00a0code\u00a0is free software; you can redistribute it and\/or \u00a0* [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":20,"menu_order":0,"comment_status":"closed","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-682","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/pages\/682","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/comments?post=682"}],"version-history":[{"count":5,"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/pages\/682\/revisions"}],"predecessor-version":[{"id":1014,"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/pages\/682\/revisions\/1014"}],"up":[{"embeddable":true,"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/pages\/20"}],"wp:attachment":[{"href":"https:\/\/www.new-territories.com\/blog\/rmit.uts\/wp-json\/wp\/v2\/media?parent=682"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}