Ripple/Raindrop Pattern

Would anyone know how to make something similar to this using grasshopper? I tried manually modelling but it just isn’t working out how I would like it. I’m new to GH and I found a similar thread on creating a ripple effect.


ripples_2017Aug23b (1).gh (27.9 KB)

1 Like

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;
  }
19 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)

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.