用sin,cos函数创建一个真实的水波动画

package waveanim;

import javafx.stage.Stage;
import javafx.scene.Scene;
import java.lang.Math;
import javafx.scene.*;
import javafx.scene.effect.*;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import java.lang.Math.*;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;

/**
* @author Administrator
*/

var w = 300;
var h = 274;
var map:FloatMap;
//amplitude
var A:Number = 1/200.0;
//frequency
var f:Number = 0.08;
//horizontal phase angle
var upangle:Number = 90;
//vertical phase angle
var vpangle:Number = 0 on replace {
    map = FloatMap { width: w height: h };
    for (i:Integer in [0..w-1]) {
        var u = A*cos(i*f + upangle);
        for (j:Integer in [0..h-1]) {
            var v = A*sin(j*f + vpangle);
            map.setSamples(i, j, u, v);
        }
    }
};

Timeline {
        repeatCount: Timeline.INDEFINITE
        keyFrames : [
            KeyFrame {
                time : 150ms
                action: function() {
                     upangle ++;
                     vpangle ++;
                }
            }
        ]
}.play();

Stage {
    title: "水波动画"
    width: 285
    height: 290
    scene: Scene {
        content: [
            ImageView {
                effect: DisplacementMap { mapData: bind map }
                x: -2
                y: -2
                image: Image {
                    url: "{__DIR__}flower.jpg"
                }
            }
        ]
    }
}
把图形文件同源程序放在同一个目录中,试一试!

波动的原理见第二个图,这是水面的横截面,每个质点都绕着自已的中心做园规迹的运动,
如果从上向下看,也就是从水面上看,质点都在中心左右来回摆动.
和序如下,
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;
import java.lang.Math.*;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.animation.Interpolator;
import javafx.scene.shape.Line;
/**
* @author Administrator
*/
var t:Number = 0;
Timeline {
    repeatCount: Timeline.INDEFINITE
    keyFrames : [
        KeyFrame {
            time : 100ms
            action: function() {
                    t+=1;
            }
        }
    ]
}.play();


Stage {
    title: "水波原理"
    width: 450
    height: 180
    scene: Scene {
        content: [
            for (i in [0..16])
                Circle {
                    centerX: 15+i*25
                    centerY: 50
                    radius: 12.5
                    strokeDashOffset: 2
                    strokeDashArray: [4]
                    fill: null
                    stroke: Color.GRAY
                },
            for (i in [0..16])
                Circle {
                    fill: Color.MAGENTA
                    centerX: bind 15+i*25 + 12.5*cos(i*0.5 + t)
                    centerY: bind 50 + 12.5*sin(i*0.5 + t)
                    radius: 3

                }
            for (i in [0..16])
                Line {
                    startX: 15+i*25
                    startY: 50
                    endX: bind 15+i*25 + 12.5*cos(i*0.5 + t)
                    endY: bind 50 + 12.5*sin(i*0.5 + t)
                    strokeWidth: 1
                    stroke: Color.GRAY
                }


        ]
    }
}
也可做成园形的波动,水波向外传播。见图3
javafx站点有个RippleEffect虽然也是用sin, cos但两者的效果如何自已去比较了.

你可能感兴趣的:(F#,J#,JavaFX)