Coding Challenge 102: 2D Water Ripple
Вставка
- Опубліковано 11 чер 2024
- In this coding challenge, I attempt to simulate 2D water ripples using Processing (Java). Code: thecodingtrain.com/challenges...
🕹️ p5.js Web Editor Sketch: editor.p5js.org/codingtrain/s...
🎥 Previous video: • Coding Challenge #101:...
🎥 Next video: • Coding Challenge #103:...
🎥 All videos: • Coding Challenges
References:
📓 2D Water: web.archive.org/web/201604180...
💾 Processing: processing.org
Videos:
🎥 Cellular Automata: • 7.1: Cellular Automata...
🔴 Livestream Archive: • Live Stream #135: May ...
Related Coding Challenges:
🚂 #24 Perlin Noise Flow Field: • Coding Challenge #24: ...
🚂 #85 The Game of Life: • Coding Challenge #85: ...
🚂 #103 Fire Effect: • Coding Challenge #103:...
Timestamps:
0:00 Introduction
0:54 2D water ripples algorithm
1:38 Let's Code
2:14 Create a 2D Array
5:08 Find new current pixel value
7:54 Display new pixel value
9:31 Initialize array
10:06 Swap buffers
12:16 Add dampening
12:54 Correction: subtract current value
13:56 Add mousePressed
15:51 Add mouseDragged
Editing by Mathieu Blanchette
Animations by Jason Heglund
Music from Epidemic Sound
🚂 Website: thecodingtrain.com/
👾 Share Your Creation! thecodingtrain.com/guides/pas...
🚩 Suggest Topics: github.com/CodingTrain/Sugges...
💡 GitHub: github.com/CodingTrain
💬 Discord: thecodingtrain.com/discord
💖 Membership: ua-cam.com/users/thecodingtrainjoin
🛒 Store: standard.tv/codingtrain
🖋️ Twitter: / thecodingtrain
📸 Instagram: / the.coding.train
🎥 Coding Challenges: • Coding Challenges
🎥 Intro to Programming: • Start learning here!
🔗 p5.js: p5js.org
🔗 p5.js Web Editor: editor.p5js.org/
🔗 Processing: processing.org
📄 Code of Conduct: github.com/CodingTrain/Code-o...
This description was auto-generated. If you see a problem, please open an issue: github.com/CodingTrain/thecod...
#2dwaterripple #cellularautomata #processing
Hugo Elias is a friend of mine. His site is a treasure trove of creative graphics techniques, wonderfully explained. Way ahead of his time in terms of visual online educational material. Really glad it got archived!
Please say hello. I am a huge fan and admirer!
@@TheCodingTrain @iestyn Hi guys! Thanks for the love. So happy to see that my page is still inspiring people after all this time. Your site is amazing, and I've learned so much from it. Thank you.
@@hugoelias1392 Oh wow, amazing to hear from you!!! Thanks for the inspiration!
this interaction made my day
Don't understand a single thing. I'm 0 at what you do. Neither understand a single thing what's going. But love the way how you do it. . You are pro! Keep it up. Watch all of ur videos...
Ati javed yooo, you gotta get in on this man, coding will let you look at stuff in different perspectives, here's something to get you started
ua-cam.com/video/r530ovO8Ysc/v-deo.html
I've learned a ton of stuff from watching your videos.
A big THANK YOU and don't ever stop coding. ☺
You have been the biggest inspiration in me pushing myself towards coding and programming. Because of you I have created multiple versions of the animated circle packing, learned to make simple physx engines in P3D and have even made several audio visualizers as part of my senior capstone for highschool. Thank you so much Daniel Shiffman for what you have provided me and others!
So nice to hear this!
Man seeing how webpages looked back in the day makes me feel so old
2:50 The struggles are real 😂
I love how happy you present yourself. It's motivating.
Wow! I'm up to date!!! Started watching the coding challenges at the beginning of the year and after watching 150 of them, I'm now up to date. Thanks so much for the videos Dan!
Wow! Just curious, over how long a period of time did you watch all the challenges?
I just had a look back through my watch history and can't find any exact dates but I'm sure I started in January, so about 4.5 months. First vid was 3D knots then, decided to start from the beginning. I managed to fit in the Neural network playlist at some point during that time too...hmmm....might need to find my local Coding Train Anonymous meeting.
Best programming teacher in Oasis!!🕹😘☺Thnx!
I love this algorithm! I actually implemented this years ago back when I was in school from the exact same webpage. Was looking for it again recently but couldn't find it.
Well now I know why.
Glad to find it again :D
Same here, though I also implemented it in GPU shaders way back in the day when programmable GPUs were just becoming a thing.
same, first used Java but it was incredibly slow so I took the opportunity to learn ARB assembly.
This was back when most computers didn't even have Pixel Shader 2.0 so it wouldn't work on the school computers :P
Floating-point error cause a bunch of issues if I remember.
Easy to forget how much easier things are these days.
@@addowhite6331 Wow the puts things into perspective
The ripples look super cool when they bounce off the edges :)
I've just coded this in Lua using your video as a guide :) Love this coding challenge and your channel!
what sort of environment did you run this in? a shot in the dark at 3 years lol
With damping 0,999 u get rly cool patterns if u drop one water drop in the middle
So check damping = 1, it's so cool and relaxing
nice 15 min challenges but i'd also like to see some more longer coding challenges, they were really awesome!!!
Very nice video, Daniel! Keep up the great work especially with the NN stuff.
Just one quick question to you and the community:
Is it possible to have no reflections at the walls?
Congratulations! Great job once again!!!
pretty sick effect, also I think I am laughing a little too much at your small jokes XD
processing 3, so happy seeing them frequent again,
@Daniel you need to be more careful when you find old code on the internet, you got lucky this was not an ancient curse that opened a time portal and allowed the zombies back in! I am of course subscribed to this channel and thumbs up as always! I love that you took the time to thank the original author and dust off old technology that is still cool and in fact fun to run even on new technology! This makes me wonder how many awesome code archives could be dusted off and revampt. I also thought it was really neat how quickly you adapted the code into only a few lines of Easy-to-Read code. I really hope the original person that posted the web page decades ago sees your video, this was as fun today as it was then I am sure! I wonder if some newer technology used in conjunction with this algorithm could use some kind of hardware acceleration or webgl or just plain horsepower on new hardware that could add features and performance that the original author only dreamed of back in the day?
I think it makes the effect look better if you use the abs function when assigning current[i][j] and also if you take the diagonal neighbours to your pixel
i watched the video without sound but still get it! Thanks alot!
Hey I love your videos, I noticed you did some coding challenges for some arcade games like snake and space invaders. Please please please do a video on making tetris!
The grids are really practical for some robotics devices that appear like they function off hand gestures and will raise small columns to move items,
"no that bothers me more" 😂 slayed me
Just amazing
Very cool result from a seemingly simple looking code.
If your arrays become too large and you need to save memory, it is possible to "skip" the temp array and the swap operation at the expense of adding some dirty looking code.: you add a second loop after the first one with the arrays swapped "by hand" (it requires a rendering in between them).
You need to implement wave physics in this one; cancelation, addition etc.
My goodness, I have to try this in UE4 (or Unity). Might be able to generate heightmap waves that react to actual objects being tossed into water. Oh man now I'm excited.
Please share if you do!
If I'm not wrong here's a nice example of this done in WebGL
madebyevan.com/webgl-water/
I found it years ago and am glad it's still there!
Dan you are the Man! Keep up the great work man!
Dan the man!
That's a fun and nice simple routine that I've appropriated to create a 1D FastLED example on the Arduino.
My challenge, however, is limited RAM. Some folks spend most of their available RAM on the CRGB array for the LEDs, and not enough memory is left over for the arrays used in this example.
So, how to create a nice smooth propagated and dampened droplet without using arrays. So far, I've got sine waves, phase shifting and exponential dampening, but not the time oriented propagation from the initial 'splash'.
I made something like this a while back with the same algorithm. Cool!
why not curr and prev :P
You made my day sir.
1:34 someone who knows what they are talking about! I respect that!
Amazing!
I wish you could mess around with PixelFlow at some point. Seems like a cool library for Processing.
Yes please. This library looks absolutely amazing!
Great tutorial ! Very useful, especial to understand the basic logic of CA.
I think that in huge domain, the order of matrix (lattice) you access make different in processing time. I C language, It is better access cols x row than row x cols.
Really cool effect / video. Would be great to see more application of cellular automata in terms of effects.
13:38 Waaaaaw wasn't ready for such a nice render :O
Hey That's Pretty good
Memories from the 90's demoscene :)
I LOVE YOUR CHANNEL!!!!!!!!!!!!!!!! AHHHH!!!!!!!!!!!!
thank you so much for these videos they ar so inspiring and I love watching them I cant what every day to see if you uploaded thanks dan
by the way, im Live_Destin I just changed my name:)
Thank you for teaching this which i also requested in one of my comments
wow that's awesome
An other very good video !
I love your french accent 😝 préviou
I'm french and I can totally confirm that he nailed the accent.
EDIT : Well I just read your username and I guess you're french too lol
french squad here
Hey, I'm bit the only french here 😉
Jean-Nay Mar Yes I'm french 😂
Id love to see js version!
Thank you for showing all of these wonderful coding lessons! I am trying to learn python so I attempted to do this in pygame. I learned numpy is slow also need to see how I messed up my array because the waves are diamond shaped. Need to fix the array, ditch numpy, and maybe use something to not update black space. I am having fun though.
import pygame as pg
import numpy as np
import random
rows, cols = 600, 400
pg.init()
screen = pg.display.set_mode((rows, cols))
# 3 = rgb
npArray = np.ndarray( (rows, cols, 3) )
current = np.ndarray( (rows, cols) )
previous = np.ndarray( (rows, cols) )
temp = np.ndarray( (rows, cols) )
previous.fill( 0 )
dampening = 0.99
continueLoop = True
while continueLoop:
mouseX, mouseY = pg.mouse.get_pos()
for event in pg.event.get():
if event.type == pg.QUIT:
continueLoop = False
if event.type == pg.MOUSEBUTTONDOWN:
previous[ mouseX ][ mouseY ] = 250
print( 'x: ', mouseX, ' y: ', mouseY )
for i in range( 2, rows - 2 ):
for j in range( 2, cols - 2 ):
current[i][j] = previous[i-1][j] + \
previous[i+1][j] + \
previous[i][j-1] + \
previous[i][j+1] / 2 - current[i][j]
current[i][j] = current[i][j] * dampening
npArray[i][j][0] = current[i][j] % 100 #red
#npArray[i][j][1] = current[i][j] #green
npArray[i][j][2] = current[i][j] % 255 #blue
#if current[i][j] > 255 or current[i][j] < 0:
# print( 'Out of bounds: ', current[i][j] )
# create a surface same size as the array
surf = pg.Surface( (npArray.shape[0], npArray.shape[1]) )
# draw npArray onto surface
pg.surfarray.blit_array(surf, npArray)
# transform the surface to screen size
#surf = pg.transform.scale(surf, (rows, cols))
screen.blit(surf, (0, 0))
temp = previous
previous = current
current = temp
pg.display.update()
pg.quit()
That's so cool:o
best, intro, ever.
Looks like color(current[i][j]) at 12:30 became color(current[i][j]*255) at 12:49 without any explanation ...
Since the values in current and previous are already between 0 and 255, why do we have to multiply them again by 255 ?
I don't get the ranges of these values either. The array is init'd with 0's I think (he didn't explicitly init it) and with the dampening at 0.9 the number may be getting so low you can't see anything so he pushed it up with * 255 (which would clip past 255 often I'm sure). He also changed the array to hold floats so he may have messed up some assumption the original code made about the values being words (unsigned ints) and how these were truncated using integer arithmetic.
who knows but it's a good question. He already messed this one up after renaming the arrays from buffer1/2 and the iterators from x/y to i/j and totally confused himself. :)
This is just a mistake that occurred during my debugging. I've removed it and added a short explanation here.
github.com/CodingTrain/website/commit/eb798afc71f8e8cf3e2a71779dc52907305ea74b#diff-11c53590d2031c3a491dcca747f3831b
Thank you for pointing this out!
He made the values a float and so float * 255 to convert to a color wasnt it?
Thank you for taking the time to respond
Yey. Love it.
Waow !!!
dude thanks lieterally entirely to this channel I want to program a fast fourier into processing to read analogue guitar inputs and create a mosaic of imagry based on what the guitar is playing at that moment.
Thats about 5 years and 1000 more videos away, but I will get there one day! (or if you see this and can do it yourself, random person out there, let me know!)
That's awesome! Keep us posted if you give it a shot!
I implemented this and I think It should be noted that the values in the buffer's can be negative
Does it matter if I began coding in JS but then used Java to add this ripple effect?
hey Dan do you ever plan on doing a GLSL for Processing tutorial?
I'd like to, yes.
That would be marvellous, I struggle wrapping my mind around glsl, I feel stuff I try in sdl would be so much faster using shaders/opengl, there's not that much in the way of 2d stuff on UA-cam for it.. Great series by the way!
check out thebookofshaders.com I dont think id have even been able to approach GLSL without it
Omg... what did u do 😱
Great video!
I was able to get the same result, however, I can't figure out how to use an image as the background which interacts with the ripples. Any help? :)
You need to create a *displacement* map, derived from the *current* buffer. The *current* buffer can be thought as a height map.
For each pixel in the image, the *displacement* map has two elements, dX and dY (which together form the displacement vector).
The C declaration of such *displacement* map looks like this:
struct DMAP {float dX, dY} disp [W][H];
and can be computed as follows:
disp [x][y] .dX = ( current [x+1][y] - current [x][y] ) * RI;
disp [x][y] .dY = ( current [x][y+1] - current [x][y] ) * RI;
where RI is a constant between 0.0f and 2.0f or more, which you can loosely call the refraction index, and sets the strength of the distortion.
To use the *displacement* map on the image:
OutputImage [x][y] = SourceImage [x][y] + (int) disp [x][y] .dY * W + disp [x][y] .dX;
Not familiar with Processing, but is it just rendering a pixel for each integer in the 2d array?
the ripples are a bit squarey, maybe if you took into account all 8 pixels (not just 4) around the middle pixel, but the diagonal pixels are further away and so shouldn't be taken into account as much as the adjacent pixels. This could make it more circular.
Can you make a video about music or any recommedation system? And it would be really nice if you implement nwural networks in it :)
I am also bothered by letter length mismatch... Try spacing it out. *:)*
I use curr and prev
Dale Thomas Me too. 👍
I want to know how to change the colour fo the background color ,thank you!
"i so wanna do that, i'm not gonna do that" :DDDD
Hugo Elias is a demoscene legend, of the Hornet Archive fame. Not just any random person. I'm a bit sad that if you google "hugo elias hornet demoscene" or something like that, you don't get any history, instead just very few random pages (you should go and check any way). If I remember correctly Hornet was a big archive of demoscene productions, kept by Hugo.
I would love to learn more!!
thank you so much for sharing this, i've been trying to achieve what you said at the end of the video, i tried populating those two arrays with the pixels of an image so that the background wouldn't be just all zeros(black) but all i get is some crazy random colors and weird things, i just want to have those same ripples but over a background, is it possible if you could give me a hand with it
In p5.js you can lay your canvas over an image and achieve that effect. I don’t think it works the same in processing, but they are pretty much identical, except p5 runs in the browser.
Has something changed with Processing?
I have successfully recreated this project using the latest version but my ripples are coloured (pinks and greens with a few whites)
Thinking Id done something wrong I downloaded Daniels and it has the same effect.
Omg u are god
Could we give color to the individual ripples and let those too interfere? Guess that would also slow it down quite a bit, but just for the exercise...
This is a great idea, you should try it!
studying the reference in processing.org now ....
have fun everyone. thanks Dan
This is really like Huygens principle
What is the shortcut for auto formatting the code in Atom?
someone please explain me this two lines,
int index = i + j * cols;
pixels[index] = color(current[i][j]);
i m trying to implement it in js, so what does the color() means here in java p5?
Mr. Hugo Elias would be proud.
"This is going to be over soon!"
Is it possible to make the code your writting bigger (zoom in) using processing 3? Thanks.
Thanks for the feedback, yes I can try to make the code bigger for the next video.
Does anyone know how to change the background? I found out it's related to pixels[index] = color(current[i][j] * 255); I think I need to grab the color of img I use in the background. I am currently trying PIxel Sorting but I don't know what exactly I should do.. .
Could anyone explain in detail about the algorithms?
Does anyone know how to mirror webcam video in P5 JS?
15:47 "What am I even doing"
A nice example - but the numerics bugged me because it looked so close to a numerical derivative! It turns out it actually is just the naive central difference approximation to the 2D wave equation on a square lattice, but with a very special choice of wave speed and/or step size. Here's a derivation with a unit time and space step size:
Use central difference to get discrete version of wave equation for ripple height H:
d_tt H = c^2 (d_xx + d_yy) H
H_{x,y,t-1} - 2 H_{x,y,t} + H_{x,y,t+1} = c^2 (H_{x-1,y,t} - 2 H_{x,y,t} + H_{x+1,y,t} + H_{x,y-1,t} - 2 H_{x,y,t} + H_{x,y+1,t})
H_{x,y,t+1} = c^2 (H_{x-1,y,t} + H_{x+1,y,t} + H_{x,y-1,t} + H_{x,y+1,t}) + (2 - 4 c^2) H_{x,y,t} - H_{x,y,t-1}
If c^2 = 0.5 then you get the nice simplification that is used in this video
H_{x,y,t+1} = 0.5 * (H_{x-1,y,t} + H_{x+1,y,t} + H_{x,y-1,t} + H_{x,y+1,t}) - H_{x,y,t-1}
whoa, thanks for this!
shut up simon
i like learn more
I downloaded the code but i cant get it to run. I'm on processing 3 and its set to Java. Anyone know why it doesn't work?
hey everyone I would like to code this but I don’t know how to draw using python.. is it possible to things like this with python ?
How about simulating the constructive and destructive interference???
That's already part of wave equations, so you don't need to add it in by hand. What you can do to demonstrate it is maybe to set up a pair of oscillations to simulate a double slit etc...
were can we find the code?
(8:16) meme review!
oow.. sorry.. wrong show. ;p
the algorithm works, but i cant wrap my head around why it works
Here's a derivation of the algorithm: use a central difference approximation to get discrete version of wave equation for ripple height H: d_tt H = c^2 (d_xx + d_yy) H
H_{x,y,t-1} - 2 H_{x,y,t} + H_{x,y,t+1} = c^2 (H_{x-1,y,t} - 2 H_{x,y,t} + H_{x+1,y,t} + H_{x,y-1,t} - 2 H_{x,y,t} + H_{x,y+1,t})
H_{x,y,t+1} = c^2 (H_{x-1,y,t} + H_{x+1,y,t} + H_{x,y-1,t} + H_{x,y+1,t}) + (2 - 4 c^2) H_{x,y,t} - H_{x,y,t-1}
If c^2 = 0.5 then you get the nice simplification that is used in this video
H_{x,y,t+1} = 0.5 * (H_{x-1,y,t} + H_{x+1,y,t} + H_{x,y-1,t} + H_{x,y+1,t}) - H_{x,y,t-1}
You can then use two arrays to store the current and previous grid values as done in the video.
I just opened paint and like manually did a 4*4 grid according to the code, and kinda understood. I know it sounds dumb (and it is) but it helped.
Can you make a typing race game?
Like
if anyone manages a shader language version of this, please let me know!
5th
Check out Paul falstsds ripple tank.
Prev and curr have the same number of letters
Anyone know of any good online schools? And don't say WGU, going their, not bad but, I don't feel like I'm learning anything.
Sponsored by skillshare
Sponsored by brilliant
somehow that looks easy
the first language is java right?
Yup, this one is Java!
yeah
i found a little bug
try to click on edge of the window and you find it :)
DO THAT