diff --git a/README.md b/README.md
index af75dfc..a0a9fbc 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,11 @@ Caustics ([wikipedia](https://en.wikipedia.org/wiki/Caustic_(optics))) are lumin
In [this post](https://laurentperrinet.github.io/sciblog/posts/2020-06-19-caustic-optics.html), I will develop a simple formalism to generate such patterns, with the paradoxical result that it is *very* simple to code yet generates patterns with great complexity, such as:
-![sciblog](https://laurentperrinet.github.io/sciblog/files/2020-06-19_caustique/2020-06-19_caustique.gif)
+
+
+
+
+
This is joint work with artist [Etienne Rey](https://laurentperrinet.github.io/authors/etienne-rey/), in which I especially follow the ideas put forward in the series [Turbulence](http://ondesparalleles.org/projets/turbulences/).
@@ -18,4 +22,17 @@ python3 -m pip install -e .
```
## running it
-Launch [jupyter](https://jupyter.org/).
+```
+from caustique import init
+opt = init()
+opt.bin_dens = 8
+
+from caustique import Caustique
+c = Caustique(opt)
+z = c.wave()
+gifname = c.plot(z)
+```
+
+## exploring more
+
+Launch [jupyter](https://jupyter.org/) and open the notebook.
diff --git a/caustique.gif b/caustique.gif
new file mode 100644
index 0000000..aac6fd8
Binary files /dev/null and b/caustique.gif differ
diff --git a/caustique.py b/caustique.py
index ab7af56..ff14702 100644
--- a/caustique.py
+++ b/caustique.py
@@ -10,7 +10,7 @@ def init(args=[], ds=1):
parser = argparse.ArgumentParser()
parser.add_argument("--tag", type=str, default='caustique', help="Tag")
- parser.add_argument("--figpath", type=str, default='2020-06-19_caustique', help="Folder to store images")
+ parser.add_argument("--figpath", type=str, default='.', help="Folder to store images")
parser.add_argument("--nx", type=int, default=5*2**8, help="number of pixels (vertical)")
parser.add_argument("--ny", type=int, default=8*2**8, help="number of pixels (horizontal)")
parser.add_argument("--bin_dens", type=int, default=4, help="relative bin density")
@@ -48,11 +48,11 @@ def make_gif(gifname, fnames, fps):
class Caustique:
def __init__(self, opt):
"""
- Image coordinates follow 'ij' indexing, that is,
- * their origin at the top left,
+ Image coordinates follow 'ij' indexing, that is,
+ * their origin at the top left,
* the X axis is vertical and goes "down",
* the Y axis is horizontal and goes "right".
-
+
"""
self.ratio = opt.ny/opt.nx # ratio between height and width (>1 for portrait, <1 for landscape)
X = np.linspace(0, 1, opt.nx, endpoint=False) # vertical
@@ -67,14 +67,14 @@ def wave(self):
import MotionClouds as mc
fx, fy, ft = mc.get_grids(self.opt.nx, self.opt.ny, self.opt.nframe)
env = mc.envelope_gabor(fx, fy, ft, V_X=self.opt.V_Y, V_Y=self.opt.V_X, B_V=self.opt.B_V,
- sf_0=self.opt.sf_0, B_sf=self.opt.B_sf,
+ sf_0=self.opt.sf_0, B_sf=self.opt.B_sf,
theta=self.opt.theta, B_theta=self.opt.B_theta)
z = mc.rectif(mc.random_cloud(env, seed=self.opt.seed))
return z
def transform(self, z_):
xv, yv = self.xv.copy(), self.yv.copy()
-
+
dzdx = z_ - np.roll(z_, 1, axis=0)
dzdy = z_ - np.roll(z_, 1, axis=1)
xv = xv + self.opt.H * dzdx
@@ -94,9 +94,9 @@ def plot(self, z, gifname=None, dpi=150):
hist = np.zeros((binsx, binsy, self.opt.nframe))
for i_frame in range(self.opt.nframe):
xv, yv = self.transform(z[:, :, i_frame])
- hist[:, :, i_frame], edge_x, edge_y = np.histogram2d(xv.ravel(), yv.ravel(),
- bins=[binsx, binsy],
- range=[[0, 1], [0, self.ratio]],
+ hist[:, :, i_frame], edge_x, edge_y = np.histogram2d(xv.ravel(), yv.ravel(),
+ bins=[binsx, binsy],
+ range=[[0, 1], [0, self.ratio]],
density=True)
hist /= hist.max()