JavaFX: Mathematics & Physics

Friday Jan 15, 2010

Fractals



A fractal can be implemented as a class that has a shape and consists of the same classes in JavaFX Script language

 

public abstract class Fractal {

    public abstract function shape(): Node;

    public abstract function childs(): Fractal[];

}
FractalView is a class that uses a recursion to show a fractal in the JavaFX Scene:
 
public class FractalView extends CustomNode {

    public var fractal: Fractal;
    public var depth: Integer;

    override function create() {
        create(depth, fractal);
    }

    function create(depth: Integer, fractal: Fractal): Node {
        if (depth == 1) {
                fractal.shape()
        } else {
            Group {
                content: for (f in fractal.childs()) create(depth - 1, f)
            }
        }
    }

}


Koch snowflake side is a fractal:
 
class Side extends Fractal {

    public var x1: Number;
    public var y1: Number;
    public var x2: Number;
    public var y2: Number;

    override public function childs(): Fractal[] {
        var dx = x2 - x1;
        var dy = y2 - y1;
        var x3 = x1 + dx / 3;
        var y3 = y1 + dy / 3;
        def sqrt = Math.sqrt(3.0);
        var x4 = x1 + dx / 2 - sqrt * dy / 6;
        var y4 = y1 + dy / 2 + sqrt * dx / 6;
        var x5 = x1 + 2 * dx / 3;
        var y5 = y1 + 2 * dy / 3;
        [
            Side { x1: x1 y1: y1 x2: x3 y2: y3 }
            Side { x1: x3 y1: y3 x2: x4 y2: y4 }
            Side { x1: x4 y1: y4 x2: x5 y2: y5 }
            Side { x1: x5 y1: y5 x2: x2 y2: y2 }
        ]
    }

    override public function shape(): Node {
        Line {
            startX: x1 startY: y1 endX: x2 endY: y2
            stroke: Color.BLUE
        }
    }

}
The Snowflake consistes of 3 sides:
 
class SnowFlake extends CustomNode {

    public var centerX: Number;
    public var centerY: Number;
    public var radius: Number;
    public var depth: Integer;

    override function create() {
        def angle = 2 * Math.PI / 3;
        def PI2 = Math.PI / 2;
        var x = for (i in [1..3]) centerX + radius * Math.cos(i * angle + PI2);
        var y = for (i in [1..3]) centerY - radius * Math.sin(i * angle + PI2);
        Group {
            content: [
                FractalView {
                    depth: depth
                    fractal: Side { x1: x[0] y1: y[0] x2: x[1] y2: y[1] }
                }
                FractalView {
                    depth: depth
                    fractal: Side { x1: x[1] y1: y[1] x2: x[2] y2: y[2] }
                }
                FractalView {
                    depth: depth
                    fractal: Side { x1: x[2] y1: y[2] x2: x[0] y2: y[0] }
                }
            ]
        }
    }

}
And the main application is
 
Stage {
    title: "Snowflake"
    scene: Scene {
        width: 400
        height: 400
        content: SnowFlake {
            depth: 6
            centerX: 200
            centerY: 200
            radius: 150
        }
    }
}

Tuesday Nov 17, 2009

JavaFX Set Demo



JavaFX Set is the open-source project that contains a set of JavaFX samples.
From the lists on the left side you can choose to work with Shapes, Transforms, Controls, Animation, Media and simple samples.

See the JavaFX Set Demo

Anyone can add his samples to the JavaFX Set project using the steps below:

  • Checkout the JavaFX Set project from the repository
    • > svn checkout https://svn.kenai.com/svn/javafxset~master javafxset
  • Open the project in an IDE with JavaFX plugin
  • Add you sample under the javafxset.samples package
  • Open the javafxset.samples.Configuration.fx file
  • Add the Sample record to the Module class
  • Commit the changes
Example of the Configuration.fx file:
 
import javafxset.core.Module;
import javafxset.core.Sample;

Module {

    name: "Samples"

    samples: [
        Sample{
            name: "Hello World"
            className: "javafxset.samples.FXHelloWorld"
        },
        Sample{
            name: "Sample Name"
            className: "javafxset.samples.SampleFile"
        },
    ]
}

Thursday Oct 01, 2009

Simple Graph Sample



This is the simple Graph sample written on JavaFX Script language.

The graph consists of edges and vertices. The Connection class is used for the graph creation. The GraphView is a Node for painting the graph object .

 
Stage {
    title : "JavaFX Simple Graph"
    scene: Scene {
        width: 300
        height: 300
        content: [
            GraphView{
                translateX: 150
                translateY: 150
                graph: Graph{
                        order: 5
                        connections: [
                            Connection{ vertex1: 0 vertex2: 1 }
                            Connection{ vertex1: 0 vertex2: 2 }
                            Connection{ vertex1: 0 vertex2: 3 }
                            Connection{ vertex1: 1 vertex2: 2 }
                            Connection{ vertex1: 3 vertex2: 4 }
                        ]
                    }
                }
            ]
    }
}
Below is the source code of the Graph class.
The full source code is integrated into the open source JavaFX MultiDimensional Library project.
public class Edge {
    public var vertex1:Vertex;
    public var vertex2:Vertex;
}

public class Vertex {
    public var edges:Edge[];
}

public class Connection {
    public var edge:Edge;
    public var vertex1:Integer;
    public var vertex2:Integer;

}


public class Graph {


    public var order:Integer;

    public var vertices:Vertex[];
    public var edges: Edge[];

    public var connections:Connection[];


    init{

        for(i in [sizeof vertices..order-1]){
            insert Vertex{} into vertices;
        }

        order = sizeof vertices;

        for(connection in connections){
            var edge = connection.edge;

            if(edge == null){ edge = Edge{}; }

            insert edge into edges;

            var v1 = vertices[connection.vertex1];
            var v2 = vertices[connection.vertex2];

            edge.vertex1 = v1;
            edge.vertex2 = v2;

            insert edge into v1.edges;
            insert edge into v2.edges;

        }
    }
}

Wednesday Sep 23, 2009

NumberBox control



It is not so difficult to create a NumberBox control using the Textbox control, triggers and data binding in JavaFX:

 

import javafx.scene.*;
import javafx.scene.control.*;

public class NumberBox extends CustomNode {

    public var value:Number on replace { str = "{value}"};

    var str:String on replace{
        try{  
            value = Number.valueOf(str);
         } catch(e){
            str = "0";
        }
    }

    public override function create(): Node {
        TextBox {
            columns: 12
            selectOnFocus: true
            text: bind str with inverse
        }
    }
}

Example with the NumberBox control:

import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.control.*;


var num = 10.0;

Stage {
    title: "NumberBox"
    width: 250
    height: 280
    scene: Scene {
        content: VBox{
            translateX: 20
            translateY: 20
            content: [
                Slider {
                    min: 0
                    max: 100
                    value: bind num with inverse
                }
                NumberBox{
                    value: bind num with inverse
                }
            ]
        }
    }
}

Friday Jul 17, 2009

Permutation Algorithm

The algorithm below just permutes i and j elements of a sequence to produce a list of all permutations:

 
function permutation(arr:Integer[]):Void{
    permutation(0, sizeof arr, arr)
}

function permutation(index: Integer, size:Integer, arr:Integer[]):Void{

    if(index == size-1){ println(arr); return; }

    permutation(index+1, size, arr);

    for(i in [index+1..size-1]){
        permutation( index+1, size, [ arr[0..index-1], arr[i],arr[index+1..i-1],arr[index],arr[i+1..size-1]]);
    }

}
For example:
 
  permutation([1..4]);
produces:
 
  [ 1, 2, 3, 4 ]
  [ 1, 2, 4, 3 ]
  [ 1, 3, 2, 4 ]
  [ 1, 3, 4, 2 ]
  [ 1, 4, 3, 2 ]
  [ 1, 4, 2, 3 ]
  [ 2, 1, 3, 4 ]
  [ 2, 1, 4, 3 ]
  [ 2, 3, 1, 4 ]
  [ 2, 3, 4, 1 ]
  [ 2, 4, 3, 1 ]
  [ 2, 4, 1, 3 ]
  [ 3, 2, 1, 4 ]
  [ 3, 2, 4, 1 ]
  [ 3, 1, 2, 4 ]
  [ 3, 1, 4, 2 ]
  [ 3, 4, 1, 2 ]
  [ 3, 4, 2, 1 ]
  [ 4, 2, 3, 1 ]
  [ 4, 2, 1, 3 ]
  [ 4, 3, 2, 1 ]
  [ 4, 3, 1, 2 ]
  [ 4, 1, 3, 2 ]
  [ 4, 1, 2, 3 ]

Wednesday Jul 15, 2009

Bubble Sort Algorithm

Bubble sort algorithm written on JavaFX Script:

 
function bubbleSort(seq:Number[]):Number[]{

    var sort = seq;
    var elem:Number;

    for(n in reverse [0..sizeof seq - 2]){
        for(i in [0..n] ){
            if(sort[i+1] < sort[i] ){
                elem = sort[i];
                sort[i] = sort[i+1];
                sort[i+1] = elem;
            }
        }
    }
    
    return sort;
}
For example:
println( bubbleSort( [5,3,1,2,4] ) ); // output: [ 1.0, 2.0, 3.0, 4.0, 5.0 ] 

Saturday Jun 06, 2009

Hyper Cube



There are a lot of interesting 3, 4 or even more dimensional shapes that can be created with the MultiDimensional library on JavaFX Script.

Take a look at the Hyper Cube sample code. It can be included into any JavaFX application.

 
import javafx.stage.*;
import javafx.scene.*;

import javafx.animation.*;
import javafx.scene.transform.*;

import mathematics.multidimensional.*;
import mathematics.multidimensional.shape.*;



var dim = 4;

Stage {
    title: "Hyper Cube"
    width:  300
    height: 300

    scene: Scene{
        content: MDUniversePlayer{
            transforms: Transform.translate(150,140);
            dimension: dim
            time: 30s
            autoplay: true
            shapes: [ MDCube{ dim: dim  side: 50} ]
        }
    }
}

Saturday May 30, 2009

Functorial and Gamma functions

The factorial function is defined by:

    `n! = 1 * 2 * ... * n`

or recursively defined by:
    `n! = 1 if n=0 `
    `n! = n * (n-1)! if n>0`
The recursive implementation of factorial in JavaFX is:
 
function factorial(n:Integer):Integer{ 
    if (n==0) 1 else n * factorial(n-1)
}

The Gamma function is defined by:

`\Gamma(z) = \int_0^\infty t^{z-1} e^{-t}\,dt `

It is related to the factorial by:

`Gamma(n) = (n-1)!`

The implementation of the Gamma function in JavaFX is:
 
def dx = 0.1;
def INFINITY = 1e5;

function gamma(a:Number):Number{
    integral(function (x: Number):Number{
        Math.pow(x, a - 1) * Math.exp( - x);
    }, 0, INFINITY, dx);
}

function integral(f:function(Number):Number, a:Number, b:Number, dx):Number{
    var s = 0.0;
    var x = a;
    while(x <= b){ x += dx; s += f(x) * dx; }
    return s;
}



Let's compare the factorial and the Gamma functions:
 
for(n in [1..7]){
    println("n = {n}");
    println("factorial({n  }) = {factorial(n)}");
    println("gamma    ({n+1}) = {gamma(n + 1)}");
    println("");
}
 

n = 1
factorial(1) = 1
gamma    (2) = 0.9991672

n = 2
factorial(2) = 2
gamma    (3) = 1.9999995

n = 3
factorial(3) = 6
gamma    (4) = 6.0000014

n = 4
factorial(4) = 24
gamma    (5) = 24.000011

n = 5
factorial(5) = 120
gamma    (6) = 119.999954

n = 6
factorial(6) = 720
gamma    (7) = 719.99945

n = 7
factorial(7) = 5040
gamma    (8) = 5039.9897

Wednesday May 20, 2009

Sequences: sum and mul functions

I asked a question about sum and mul functions for sequences in JavaFX on JavaFX forum and PhiLho replayed that it is possible to implement such functions using the suggested reduce function:

 
function reduce(sequence: Number[], s:Number, operator: function (r: Number, v: Number): Number): Number{
    var result = s;
    for (v in sequence){
        result = operator(result, v);
    }
    return result;
}

function sum(seq:Number[]):Number{ reduce(seq, 0, function (r:Number, v:Number) { r + v }) }
function mul(seq:Number[]):Number{ reduce(seq, 1, function (r:Number, v:Number) { r * v }) }

var seq = [ 1, 2, 3, 4, 5];

println("sum: {sum(seq)}");
println("mul: {mul(seq)}");
The results for the [ 1, 2, 3, 4, 5] sequence are:
  • sum: 15.0
  • mul: 120.0

Monday May 18, 2009

Matrix-Vector Multiplication

Assume that `x` and `y` are vectors and `A` is a matrix.
The matrix-vector multiplication is defined as:
`y=Ax`
`y_n=sum_m A_{n,m} y_m`

JavaFX does not contains arrays. It contains sequences which have only one dimension.

To create a matrix class we will use getElem method:

 
    function getElem (n:Integer, m: Integer):Number {
        return elems[dimM * n + m ];
    }

Using the getElem function allows to program a matrix-vector multiplication in JavaFX:

 

function sum(nums:Number[]):Number{ 
    var s = 0.0;
    for(num in nums) s+=num;
    return s;
}

public class Vector {

    public var dim: Integer ;
    public var elems: Number[];

    public function getElem(n: Integer):Number{ elems[n] }
    override function toString ():String { "[ {for(s in elems) (" {s}")} ]" }
    
}


public class Matrix {


    public var dimN:Integer;
    public var dimM:Integer;

    public var elems:Number[] ;

    function getElem (n:Integer, m: Integer):Number {
        return elems[dimM * n + m ];
    }

    public function mul (vector:Vector):Vector {
        Vector{
            dim: dimN
            elems: for(n in [0..dimN -1]) sum(for(m in [0..dimM-1]) getElem ( n, m ) * vector.getElem(m))
        }
    }
}


Let's try to calculate something:

 
var vector = Vector{
    dim: 2
    elems: [ 1, 2 ]
}


var matrix = Matrix{
    dimN: 2
    dimM: 2
    elems: [
            [ 1, 2 ],
            [ 3, 4 ]
    ]
}

println("result: {matrix.mul(vector)}");
The result is: [ 5.0 11.0 ]

Friday May 15, 2009

Planetary System



The program below uses Newton's laws of motion for the Solar system modeling:

Physical Object:

public class PhysicalObject {

    public var name: String;

    public var mass: Number;
    public var radius: Number;

    public var color: Color;

    public var coordinate: VectorDim3 = VectorDim3{};
    public var velocity: VectorDim3 = VectorDim3{};
    public var acceleration: VectorDim3 = VectorDim3{};
    
}
Physical Object System:
public class PhysicalObjectSystem{
    
    public var dt: Number = 60* 60 * 24 * 2;
    public var G: Number = 6.67e-11;
    public var objects:  PhysicalObject[];


    public function run():Void{

        for(obj1 in objects){
            
            obj1.acceleration.zero();

            for(obj2 in objects[obj| obj!= obj1]){
                var distance = obj2.coordinate.sub(obj1.coordinate);
                obj1.acceleration = obj1.acceleration.add(distance.normal().mul(G * obj2.mass / distance.square() ))
            }
        }

        for(obj in objects){
            obj.velocity   = obj.velocity.add( obj.acceleration.mul( dt) );
            obj.coordinate = obj.coordinate.add( obj.velocity.mul( dt ));
        }
    }
}
System Visualization:
public class PhysicalObjectSystem extends CustomNode{
    override function create():Node{
        Group{
            content: bind for(obj in objects)
            Group{
                content: [
                    Circle{
                        centerX: bind obj.coordinate.elems[0] * scale.coordinateScale
                        centerY: bind obj.coordinate.elems[1] * scale.coordinateScale
                        radius: obj.radius * scale.radiusScale
                        fill: obj.color
                    },
                    Text{
                        content: obj.name
                        font: Font {name: "BOLD" size: 16}
                        x: bind obj.coordinate.elems[0] * scale.coordinateScale + 15
                        y: bind obj.coordinate.elems[1] * scale.coordinateScale - 15
                        strokeWidth: 3
                        fill: Color.WHITE
                    }
                ]
            }
        };
    }
}

Main program:
var solarSystem = PhysicalObjectSystem{
    objects: [
        PhysicalObject{
            name: "Sun"
            mass : 2e30
            color: Color.YELLOW
            radius:   14000
            coordinate : VectorDim3{}
            velocity : VectorDim3{}
        },PhysicalObject{
            name: "Mercury"
            mass : 3.3e23
            color: Color.BLUE
            radius: 2400
            coordinate : VectorDim3{ elems:[ -57e9 ,  0, 0] }
            velocity : VectorDim3{ elems: [ 0, -47e3, 0 ] }
        },
        PhysicalObject{
            name: "Venus"
            mass : 4.8e24
            color: Color.PINK
            radius: 6000
            coordinate : VectorDim3{ elems: [ 108e9 ,  0, 0] }
            velocity : VectorDim3{ elems: [ 0, 35e3, 0 ] }
        },
        PhysicalObject{
            name: "Earth"
            mass : 6e24
            color: Color.GREEN
            radius: 6300
            coordinate : VectorDim3{ elems: [ 0 , -150e9, 0 ] }
            velocity : VectorDim3{ elems: [ 30e3, 0, 0 ] }
        },PhysicalObject{
            name: "Mars"
            mass : 6.4e23
            color: Color.RED
            radius: 3400
            coordinate : VectorDim3{ elems: [ 0 , 228e9, 0 ] }
            velocity : VectorDim3{ elems: [ -24e3, 0, 0 ] }
        }
    ]
};


Timeline {
    repeatCount: Timeline.INDEFINITE
    keyFrames:  KeyFrame {
        time: 0.02s
        action: function() { solarSystem.run(); }
    }
}.play();


var w = 600;
var h = 400;

Stage {
    title: "Solar System"
    width: w
    height: h
    scene: Scene{
        content: Group{
           transforms: Transform.translate(w/2, h/2)
           content: [ Stars{}, solarSystem ]
        }
        fill: Color.BLACK
    }
}

Monday Apr 27, 2009

Pendulum

A simple pendulum consists of a ball of mass m tied to a string which is considered massless.



In order to realize Newton's second law you need to project the force mg on a line perpendicular to the string:

  • m (length * amplitute)'' = mg * sin(amplitute)


Here is a small JavaFX code snippet that allows you to simulate a pendulum:

def g = 9.8;
def dt = 0.1;

public class Pendulum {

    public var length: Number;
    public var mass: Number;

    public var amplitute: Number;
    public var velocity:Number;
    public var acceleration:Number;


    public function run(){
        acceleration = - g / length * Math.sin(amplitute);
        velocity  += acceleration * dt;
        amplitute += velocity * dt;
    }
}

Full source code

Pendulum.fx


import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import java.lang.Math;

def g = 9.8;
def dt = 0.1;

public class Pendulum extends CustomNode {

    public var length: Number;
    public var mass: Number;

    public var amplitute: Number;
    public var velocity:Number;
    public var acceleration:Number;


    public function run(){
        acceleration = - g / length * Math.sin(amplitute);
        velocity  += acceleration * dt;
        amplitute += velocity * dt;
    }

    public override function create(){
        Group{
            content: [
                Line {
                    endX: bind length * Math.sin(amplitute)
                    endY: bind length * Math.cos(amplitute)
                    stroke: Color.ORANGE
                },
                Circle {
                    radius: 5
                    fill: Color.GRAY
                },
                Circle {
                    centerX: bind length * Math.sin(amplitute)
                    centerY: bind length * Math.cos(amplitute)
                    radius: 20
                    fill: Color.YELLOW
                    stroke: Color.ORANGE
                }
            ]

        }
    }
}

Main.fx

import javafx.stage.*;
import javafx.scene.*;
import javafx.animation.*;

import java.lang.Math;

var pendulum = Pendulum{
    mass: 10
    length: 150
    amplitute: Math.PI / 4
};

Timeline {
    repeatCount: Timeline.INDEFINITE
    keyFrames : [
        KeyFrame {
            time : 10ms
            canSkip : true
            action: function(){
                pendulum.run();
            }


        }
    ]
}.play();


Stage {
    title: "Pendulum"
    width: 300
    height: 300
    scene: Scene {
        content: [
            Group{
                translateX: 150 translateY: 30
                content: pendulum
            }
        ]
    }
}
Click on the Pendulum to run it as an applet.

Wednesday Apr 15, 2009

Numerical Integration

Here is an implementation of the rectangle method for integrals calculation on JavaFX Script language:

function integral(f:function(Number):Number, a:Number, b:Number, dx:Number):Number{
    var s = 0.0;
    var x = a;
    while(x <= b){
        x += dx;
        s += f(x) * dx;
    }
    return s;
}
Let's calculate an integral of cos(x) function:
import java.lang.Math;

function cos(x:Number):Number{ Math.cos(x) }
println( integral(cos, -Math .PI / 2, Math.PI / 2, 0.01) );

The result is: 1.9999075

Sunday Apr 12, 2009

Simple Function Plotter

It is very simple to show a function graphic using JavaFX Script language. What you need is a simple JavaFX component that draws a function point by point:

import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;

public class FunctionView extends CustomNode{

    public var xMin: Number;
    public var xMax: Number;
    public var dx: Number = 0.1;
    public var scale: Number = 1.0;
    public var color: Color = Color.BLUE;

    public var func: function(a: Number):Number;

    override function create():Node{
        Polyline{
            stroke: color
            points: for(x in [xMin..xMax step dx]) [x * scale, func(x) * scale]
        }
    }
}
To use it in the JavaFX Script program, just put the FunctionView component into the Stage:
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.transform.*;

import java.lang.Math;

function f(x:Number):Number{  10 * Math.sin(3 * x) / (1 + x * x) }

Stage {
    title: "Function Graphic"
    scene: Scene {
        width: 200
        height: 200
        content: Group {
            transforms: [ Translate{ x: 100 y: 100}, Scale{ x: 1 y: -1 } ]
            content: FunctionView{
                xMin: -10
                xMax: 10
                scale: 10
                func: f
            }
        }
    }
}
 
Put the code into the FunctionView.fx and Main.fx files and run the Main file.

Calendar

Feeds

Search

Links

Navigation

Referrers