Android implementation of water ripple

Source: Internet
Author: User

In Android, each image pixel is displayed by a 4-byte INTEGER: the highest byte is used as the alpha channel, and the following things are red, and so on. The next two bytes correspond to green and Bule.

It is difficult to achieve the real water wave effect. Everything is simplified here.

First, review physics. In a calm water surface (the amplitude of all points is 0), place a circular stone with a radius of R, the water that is first hit by a rock on the water surface will sink (the amplitude changes to negative ). Then, each hit point will spread the obtained energy around (in this example, it is assumed that only the points in the top, bottom, and left directions are affected by the center, at the same time, because of the energy loss during the diffusion process, the amplitude will become smaller and smaller until the whole water surface recovers.

Refraction: The focus of simulating water waves in a background image is to simulate the refraction of water waves. When a water wave occurs, the height of the adjacent two points is inconsistent and a certain height difference occurs. If we look at the water wave from the top, this height difference will produce a refraction effect, that is, the point we see should be in the lower position of the actual position. If everything is simplified, the deviation of the position is determined by the height difference. Simply simulate it. In fact, the effect after running is not that bad.

Segment code analysis:

Buf1 and buf2 are used to store the amplitude of a pixel before and after a rendering, respectively. bitmap1 and bitmap2 are used to store the acquired image pixels.

1 short[] buf2;
2 short[] buf1;
3 int[] Bitmap2;
4 int[] Bitmap1;
5 buf2 = new
short[BACKWIDTH * BACKHEIGHT];
6 buf1 = new
short[BACKWIDTH * BACKHEIGHT];
7   
8 Bitmap2 = new
int[BACKWIDTH * BACKHEIGHT];
9 Bitmap1 = new
int[BACKWIDTH * BACKHEIGHT];

Throwing stones, as described above
The water that is first hit by a rock on the water surface will sink (the amplitude changes to negative ).

01 void
DropStone(
int x,// X coordinate
02 int
y,
// Y coordinate
03 int
stonesize,
// Wave source RADIUS
04 int
stoneweight)
// Wave source energy
05 {
06 for
(
int posx = x - stonesize; posx < x + stonesize; posx++)
07 for
(
int posy = y - stonesize; posy < y + stonesize; posy++)
08 if
((posx - x) * (posx - x) + (posy - y) * (posy - y) < stonesize* stonesize)
09 buf1[BACKWIDTH * posy + posx] = (short) -stoneweight;
10 }

This section is a process of practical diffusion. Buf2 is the amplitude after diffusion. Because only the upper and lower left directions affect the center amplitude, the amplitude of a point after one diffusion is the amplitude of four weeks and the amplitude of the last one. The four-week impact is assumed to be the same. Set X as the center amplitude. The upper and lower left amplitude is x1, x2, X3, X4, and X' as the amplitude after one diffusion. X' = (X1 + X2 + X3 + X4) * A + x * B. This diffusion is relative, and the four directions are also affected by the central point. The calculation is very crude, and this part is considered as a whole based on conservation of energy. X + X1 + X2 + X3 + X4 = x' + X1 '+ x2' + x3'
+ X4 '. The result is 4A + B = 1. The combination is interpreted as a = 1/2, B =-1. To improve efficiency, divide by 2 to shift. After a new amplitude is obtained, the attenuation is performed.

01 void
RippleSpread() {
02 for
(
int i = BACKWIDTH; i < BACKWIDTH * BACKHEIGHT - BACKWIDTH; i++) {
03 // Wave energy diffusion
04 buf2[i] = (short) (((buf1[i -
1] + buf1[i +
1]+ buf1[i - BACKWIDTH] + buf1[i + BACKWIDTH]) >>
1) - buf2[i]);
05 // Wave Attenuation
06 buf2[i] -= buf2[i] >> 5;
07 }
08 // Exchange the Boundary Data Buffer
09 short[] ptmp = buf1;
10 buf1 = buf2;
11 buf2 = ptmp;
12 }

After one diffusion, the offset xoff and yoff are calculated based on the height difference (amplitude difference) between adjacent pixels. As mentioned above, the offset is directly equal to the height difference, and everything is simplified. Then, add the offset to the specific pixel. The new Pixel adds the offset to the original pixel.

01 /* Render your watermark effect */
02 void
render() {
03 int
xoff, yoff;
04 int
k = BACKWIDTH;
05 for
(
int i =
1; i < BACKHEIGHT -
1; i++) {
06 for
(
int j =
0; j < BACKWIDTH; j++) {
07 // Calculate the offset
08 xoff = buf1[k - 1] - buf1[k +
1];
09 yoff = buf1[k - BACKWIDTH] - buf1[k + BACKWIDTH];
10 // Determine whether the coordinates are within the window range
11 if
((i + yoff) <
0) {
12 k++;
13 continue;
14 }
15   
16   
17 if
((i + yoff) > BACKHEIGHT) {
18 k++;
19 continue;
20 }
21   
22 if
((j + xoff) <
0) {
23 k++;
24 continue;
25 }
26   
27 if
((j + xoff) > BACKWIDTH) {
28 k++;
29 continue;
30 }
31   
32 // Calculate the memory address offset of the Offset pixel and the original Pixel
33 int
pos1, pos2;
34 pos1 = BACKWIDTH * (i + yoff) + (j + xoff);
35 pos2 = BACKWIDTH * i + j;
36 Bitmap2[pos2++] = Bitmap1[pos1++];
37 k++;
38 }
39 }
40   
41 }

Finally, add these to the thread. The dropstone method is called in the onkeyup event, and the thread is drawn. It is expanded every 50 ms until the water surface is calm.

01 public
void
run() {
02 while
(!Thread.currentThread().isInterrupted()) {
03 try
{
04 Thread.sleep(50);
05 } catch
(InterruptedException e) {
06 Thread.currentThread().interrupt();
07 }
08   
09 RippleSpread();
10 render();
11 // Use postinvalidate to directly update the interface in the thread
12 postInvalidate();
13 }
14   
15 }

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.