旗帜飞扬核心算法思想:
图片每个交织点的横坐标较之前不发生变化,而纵坐标较之前呈现一个三角函数的周期性变化
public class WaveFlag extends View {
private Bitmap bitmap;
private final static int HEIGHT = 80;
private final static int WIDTH = 60;
float[] orig, verts;
private final float A = 3.0f;
private double k ;
public WaveFlag(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.seekbar_bg_pic);
orig = new float[((WIDTH + 2) * 2 * HEIGHT + 1)];
verts = new float[(WIDTH + 2) * 2 * HEIGHT + 1];
float bitmapWidth = bitmap.getWidth();
float bitmapHeight = bitmap.getHeight();
int index = 0;
for (int y = 0; y <= HEIGHT; y++) {
float fy = bitmapHeight * y / HEIGHT;
for (int x = 0; x <= WIDTH; x++) {
float fx = bitmapWidth * x / WIDTH;
orig[index * 2 + 0] = verts[index * 2 + 0] = fx;
//这里人为将坐标+100是为了让图像下移,避免扭曲后被屏幕遮挡
orig[index * 2 + 1] = verts[index * 2 + 1] = fy + 100;
index += 1;
}
}
}
public void flagWave() {
for (int j = 0; j < HEIGHT; j++) {
for (int i = 0; i <= WIDTH; i++) {
verts[(j * (WIDTH + 1) + i) * 2 + 0] += 0;
float offsetY = (float) Math.sin((float) i / WIDTH * 2 * Math.PI + Math.PI * k);
verts[(j*(WIDTH+1)+i)*2+1] = orig[(j*WIDTH+i)*2+1]+offsetY* A;
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
flagWave();
k+=0.1F;
canvas.drawBitmapMesh(bitmap,WIDTH,HEIGHT,verts,0,null,0,null);
invalidate();
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CH6.section6.WaveFlagActivity">
<wangsheng.swpuiot.qunyingzhuan.CH6.section6.WaveFlag
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
public class WaveFlagActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wave_flag);
}
}