Ripple/Raindrop Pattern

Hi,

I hope that the old thread have enough information and example Gh file for your case.

Cheers,
BVR

like a box of rain…

A few more threads on the subject:


2 Likes

My biggest issue is that I want to get rid of the inner rings and not sure how I could do that. Otherwise I think I’m getting closer.

Thanks for quick replies I’ll post if I figure out how to remove or filter the inner ripples.

I’m not inclined to revisit this topic in depth but a quick scan of some of the code I referred to tells me you’ll be better off skipping the earlier work that depends on Graph Mapper and start with this post that uses an alternative way of generating a damped sine wave from David Rutten:

This post (below) and others that follow it don’t use Graph Mapper so offer the potential of more flexible control but I confess, they aren’t easy to understand:

Beginning in ripples_2019Jun06a.gh and ripples_2019Jun06b.gh, a switch between “Config” (cyan group) and “Scale” (yellow group) is offered with a ten second (!) Data Dam that delays putting into effect any parameter changes. That can be confusing.

Some of the later posts in that thread (June 7 and after) mention extremely long elapsed times for high resolution models, which is probably the reason for the Data Dam.

The thread gets into the weeds offering a “Ripple Preview” feature and ripple patterns that span multiple panels, along with other refinements. I’d have to dig in deep to understand it myself at this point.

Good luck.

3 Likes



droplets.gh (15.3 KB)

Here a small “simulator” using points as droplets.
Droplet fall speed is equal to wave propagation speed, so when a droplet is below Z=0 it is projected to XY plane and its Z value used as radius of the wave.

Waves keeps a constant volume (conservation of energy… ? maybe not…)

Used a c# script for most of the work, used Parallel.For for increased speed using multithreading.
Managing big lists of values is slow on grasshopper, doing everything inside a c# script let the simulation works realtime even with big meshes and high droplets count.

Added comments inside the c# script so anyone could reverse engineer it and maybe learn how to do stuff…

Cya boyz!

code:

using System.Threading;
using System.Threading.Tasks;

 private void RunScript(Mesh M, List<Point3d> P, double Wp, double Wh, ref object A)
  {
    double pi = Math.PI;

    // Finding droplets that are below Z=0 and putting them into a new list. Projecting them into XY plane.
    // Saving the Z values into a separate list. Point depth is used as time factor (the further down, the earlier the droplet did hit the water surface).
    List<Rhino.Geometry.Point3f> pts = new List<Rhino.Geometry.Point3f>();
    List<double> t = new List<double>();
    foreach(Rhino.Geometry.Point3d p in P){
      if(p.Z < 0){
        pts.Add(new Rhino.Geometry.Point3f((float) p.X, (float) p.Y, 0));
        t.Add(-p.Z);
      }
    }

    // The next 2 lines do the same thing: iterate through M.Vertices list.
    Parallel.For(0, M.Vertices.Count, i => { // This is the parallel, multithreaded method. Faster.
      // for(int i = 0;i < M.Vertices.Count;i++){ // This is the normal for loop method. Slower.

      // Current vertex is M.Vertices[i] .

      // This value will become later the Z movement of current vertex.
      double m = 0;

      // Now iterating to each Z<0 droplets; finding distance to current vertex and applying function to increment m.
      for(int j = 0;j < pts.Count;j++){
        double d = M.Vertices[i].DistanceTo(pts[j]); // distance
        // Wave speed is same as droplet, so wave radius is equal to droplet value below Z=0;
        if(!(d < t[j] - Wp / 2 || d > (t[j] + Wp / 2))){ // Applying function only to areas around the wave radius +/- half Wave pitch (Wp).
          m += Wh * (1 - Math.Cos(pi + pi * (d - t[j]) / (0.5 * Wp))) / (d + 1);
        }
      }
      // Moving vertex.
      M.Vertices[i] = M.Vertices[i] + new Rhino.Geometry.Vector3f(0, 0, (float) m);

      }); // End of parallel method.
    // } // End of for loop method.

    M.RebuildNormals();
    A = M;
  }
29 Likes

Oh WOW!!! But nothing happens when I open the file? I see only a static image?

I did use the right-click > animate on the green slider…

You can use a timer+counter to do the same thing… more or less.

Just move up/down the droplets (points from populate).

Ah so, I missed that. AWESOME!!!

That’s brilliant, thanks for sharing.
It looks like each drop sends one ring / wave out from the point that it hits the surface.
In reality, each drop would send a decaying oscillation outwards from each point. Is there an easy tweak to the script to do this?

You want to edit here:

if(!(d < t[j] - Wp / 2 || d > (t[j] + Wp / 2))){ // Applying function only to areas around the wave radius +/- half Wave pitch (Wp).
  m += Wh * (1 - Math.Cos(pi + pi * (d - t[j]) / (0.5 * Wp))) / (d + 1);
}

That part is when the distance (d, from vertex to droplet) is begin used. t[j] is the “time” since droplet hit.

You can edit that formula.
Keep the "m += " part, and put whatever. (it’s needed to sum the effects of every droplets)

I can do it for you but i don’t know a function . I’ve found some but i didn’t like them.
Anyway, if you find a formula using d and t[j] i can fix that…

Wave equations tends to be complex and… opinion-dependent.
Maybe i’m wrong.

1 Like

Really cool to see thanks.

Not sure if this is using d and t…


This is from a @DavidRutten example from years ago (can’t find the link)
I use this for nice static wave interference from point sources.
ripplesDR.gh (13.7 KB)

1 Like

This approach reminds me of a shock wave propagating as a cone.


droplets_bis.gh (11.9 KB)
… edited to use that formula.

But this don’t seems a “ripple/raindrop” … more like the visualization of a constant audio tone/sound.

For a ripple/raindrop i imagine variables like, for each droplet:

  • speed … so energy
  • time elapsed since hit
  • volume (pouring a glass of water from 1cm might have the same energy of a droplet, but the resulting wave is completely different)
  • direction … but this would be overkill…

… anyway…

1 Like

Yes, this looks like a reversion to the models I posted in June, 2019.

Of the additional parameters you mentioned, I think time elapsed is the most important. I imagine it to be a kind of damped oscillation at the center point, in addition to the “half-life” damping factor at a distance in @DavidRutten’s equation from 2016:

Beyond me though.

P.S. It’s not as simple as this but maybe something similar?

ripple_time_factor

I said I wasn’t inclined to revisit this topic… But visualizing ripples have been a fascination of mine for more than 40 years(!), going back to using character sets to represent “pixel” density.

Looking again at ripples_2019Jun07b.gh from June, 2019, I’m really impressed with some of the features in this model, especially “caliper” (purple blob group) and “Ripple Preview” (yellow group):

I added the “EXPERIMENTAL” ‘time’ slider (blue group), which is nonsense but interesting? No other changes. Resolution (white group) is low for better response time but can be increased.


ripples_2020Sep22a.gh (57.1 KB)

Nowhere near as cool as @maje90’s animation though!

2 Likes

I’m on R5 so can’t open the file. Don’t worry, I will just comment from the sidelines on this one.

I agree it looks more like a visualisation of a constant sound. Perhaps that is because the decay is not significant enough?

I agree that the parameters you suggest are probably what are needed.

@Joseph_Oster

Yes, this came from a definition that David Rutten posted and I believe you contributed to that discussion too. I can’t find the original link.

In the damped sine wave equation, does energy correspond to Amplitude and volume correspond to Wavelength? Wave form and propagation are probably among the most studied and best understood aspects of physics so the answers we seek are certainly well documented in textbooks.

But for the lazy artist trying to visualize ripples, consider this waking insight:

The white curves are a result of plotting the damped sine curves for each point along the X axis, then mirroring them in the YZ plane and joining the originals to their mirror images. The blue curves are the result of “time shifting” the white curves in the X direction and lopping off both ends to match the original curves.

I butchered a copy of the model I posted yesterday, leaving only the “Ripple Preview” feature to see the effect on any selected point. The white group at the bottom does the mirror/time shift thing.


ripples_2020Sep23a.gh (39.4 KB)

There must be a way to accomplish this mathematically instead of by geometric construction?

1 Like