Skip to content

Instantly share code, notes, and snippets.

@GoToLoop
Last active August 10, 2020 03:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GoToLoop/145418d1dfb062c7c41a630bce5b8374 to your computer and use it in GitHub Desktop.
Save GoToLoop/145418d1dfb062c7c41a630bce5b8374 to your computer and use it in GitHub Desktop.
Brownian Motion
height: 610
scrolling: no
border: no
license: cc-by-4.0
/**
* ArrayQueue (v1.1.1)
* GoToLoop (2020/Apr/20)
* https://Discourse.Processing.org/t/linkedlist-vs-arraylist/19946/14
*/
//package java.util; // Uncomment this line if this is a ".java" file
import java.util.Collection;
import java.util.Queue;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.io.Serializable;
static // Comment this out if this is a ".java" file
public class ArrayQueue<E> implements Queue<E>, Cloneable, Serializable {
//static final long serialVersionUID = 8_779_387_929_858_209_947L;
static final long serialVersionUID = 779_387_929;
protected final List<E> list;
public ArrayQueue() {
list = new ArrayList<E>();
}
public ArrayQueue(final int initialCapacity) { // Ignored by Pjs
list = new ArrayList<E>(initialCapacity);
}
public ArrayQueue(final Collection<? extends E> c) {
list = new ArrayList<E>(c);
}
public void clear() {
list.clear();
}
public int size() {
return list.size();
}
public boolean isEmpty() {
return list.isEmpty();
}
public boolean offer(final E e) {
return add(e);
}
public boolean add(final E e) { // No return (void) on Pjs
return list.add(e);
}
public E peek() {
return isEmpty()? null : element();
}
public E element() {
return list.get(0);
}
public E poll() {
return isEmpty()? null : remove();
}
public E remove() {
return list.remove(0);
}
public boolean remove(final Object o) {
return list.remove(o);
}
public boolean removeAll(final Collection<?> c) {
return list.removeAll(c);
}
public boolean addAll(final Collection<? extends E> c) { // void on Pjs
return list.addAll(c);
}
public boolean retainAll(final Collection<?> c) { // Undefined on Pjs
return list.retainAll(c);
}
public boolean containsAll(final Collection<?> c) { // Undefined on Pjs
return list.containsAll(c);
}
public boolean contains(final Object o) {
return list.contains(o);
}
public Object[] toArray() {
return list.toArray();
}
public <T> T[] toArray(final T[] a) { // Parameter ignored by Pjs
return list.toArray(a);
}
public Iterator<E> iterator() {
return list.iterator();
}
public ArrayQueue<E> clone() {
return new ArrayQueue<E>(list);
}
public String toString() { // Undefined on Pjs
return list.toString();
}
}
/**
* Brownian Motion (v3.0.0)
* by Ammon.Owed (2013/Aug)
* mod GoToLoop
*
* Forum.Processing.org/two/discussion/2829/fifo-queue-problem-with-code#Item_1
*
* OpenProcessing.org/sketch/878458
* Bl.ocks.org/GoToLoop/145418d1dfb062c7c41a630bce5b8374
*/
import java.util.Queue;
import java.util.ArrayDeque; // not needed anymore
static final String TITLE1 = "Brownian Motion FPS: ", TITLE2 = " Size: ";
static final boolean JAVA = 1/2 != 1/2.;
static final boolean HAS_MAX_LIMIT = false;
static final int DIM = 100, LIMIT = 03000, DETAIL = 1000, DEPTH = 2000;
static final int HUE = 1 << 10, HUE_M1 = HUE - 1;
static final int FPS = 60, MIN_FPS = 40, SMOOTH = 2;
static final float BOLD = 1.5, AMP = 10;
//final Queue<PVector> points = new ArrayDeque<PVector>(LIMIT);
final Queue<PVector> points = new ArrayQueue<PVector>(LIMIT);
final PVector cam = new PVector(), lp = new PVector();
float canvasRatio, zNear, zFar;
boolean paused;
void setup() {
size(950, 600, P3D);
smooth(SMOOTH);
frameRate(FPS);
colorMode(HSB, HUE, 1, 1);
strokeWeight(BOLD);
noFill();
canvasRatio = (float) width/height;
final float camZ = .5 * height / tan(PI * FPS / 360);
zNear = camZ / AMP;
zFar = camZ * AMP;
frameRate = LIMIT << 1;
}
void draw() {
// Local-cached & short-named variables:
final int fr = round(frameRate), len = points.size();
int fc = frameCount;
if (JAVA) surface.setTitle(TITLE1 + fr + TITLE2 + len);
// Recycled or new vector point:
final PVector np = len != 0 &&
(!HAS_MAX_LIMIT && fr <= MIN_FPS || HAS_MAX_LIMIT && len >= LIMIT)?
points.remove() : new PVector();
// Interpolated rotating camera aimed at latest added point (tail):
cam.mult(.99);
cam.add(PVector.mult(lp, .01, np));
camera(
cam.x + sin(.01 * fc) * DETAIL,
cam.y + cos(8e-3 * fc + 10) * DETAIL,
cam.z - DEPTH,
cam.x, cam.y, cam.z,
0, 1, 0
);
//perspective();
perspective(THIRD_PI, canvasRatio, zNear, zFar);
// Draw colored curved lines:
background(0);
beginShape();
for (final PVector p : points) {
stroke(fc++ & HUE_M1, 1, 1);
curveVertex(p.x, p.y, p.z);
}
endShape();
// Generate a new point at specified range:
PVector.random3D(np, this).mult(DIM); // pick a new random direction.
np.add(lp); // add that up from latest point.
lp.set(np); // this is now the latest point too.
points.add(np); // add new point to queue's tail.
}
void mousePressed() {
if (mouseButton == RIGHT) points.clear();
else if (paused ^= true) noLoop();
else loop();
}
<script defer src=https://Unpkg.com/processing-js></script>
<canvas data-processing-sources="Brownian_Motion.pde ArrayQueue.pde"></canvas>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment