Recent changes Random page
GAMING
Technology
 
Gaming
Entertainment
Science Fiction
Biggest wikis
Hobbies
Music
See more...

RelativityParticleCollision

Материал из JavaFX

Перейти к: навигация, поиск
 

Главная | Описание языка | API | Примеры | Инструменты Разработки | Новости | Ресурсы | Вопросы и ответы | Форум

[править] Разлет частиц

[править] Релятивистский случай

text

Столкновение частиц.

Закон сохранения импульса и энергии:

 math
 math


import javafx.animation.*;
import javafx.application.*;

import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.geometry.*;
import javafx.scene.transform.*;
import java.lang.Math;

import java.lang.System;
var a = 2;
var i=0;//счетчик
var v = 0.887;//скорость налетающей частицы относительно скорости света
var m1=10;//масса первой частицы
var m2=10;//масса второй частицы
var ang = Math.random()*Math.PI;//угол разлета в системе центра масс
if (ang==0) ang=Math.PI;//частицы не могут пройти сквозь друг друга
function abs (x:Number):Number {
    return if ( 0 < x ) then x else -x;
} 
function q (w:Number):Number{//возведение в квадрат
    return w*w
}
function arth (x:Number):Number{//обратная к гиперболическому тангенсу
    return Math.log((1+x)/(1-x))/2
}
function arch (x:Number):Number{//~косинуа
    return Math.log(x+Math.sqrt(q(x)-1)) 
}
function arsh (x:Number):Number{//~синуса
    return Math.log(x+Math.sqrt(q(x)+1))
}
function tch (ang:Number, v1:Number, v2:Number):Number{//по теореме косинусов находит сторону по сторонам и углу
   return if  (ang==Math.PI) v1+v2
   else if (ang==0) v1-v2 
      else arch(Math.cosh(v1)*Math.cosh(v2)-Math.sinh(v1)*Math.sinh(v2)*Math.cos(ang));

}
function tch1 (v1:Number, v2:Number, v3:Number):Number{//по теореме косинусов находим угол разлета
    return if (v2==0) 0
    else Math.acos((Math.cosh(v1)*Math.cosh(v2)-Math.cosh(v3))/Math.sinh(v1)/Math.sinh(v2))
}
function d (p1:Particle,p2:Particle){//обработка события столкновения
  var v1=arth(p2.mass*Math.sinh(arth(v))/(p1.mass+p2.mass*Math.cosh(arth(v))));//расстояние по кинематическому графу
  var v2=arth(p1.mass*Math.sinh(arth(v))/(p2.mass+p1.mass*Math.cosh(arth(v))));//расстояние по кинематическому графу
  var ang1=tch1(v2, tch(Math.PI-ang, v1,v2),v1);//угол отлета первой частицы
  var ang2=tch1(v2,tch(ang,v2,v2),v2);//угол отлета второй частицы
  
    p1.dX=Math.cos(ang1)*Math.tanh(tch(Math.PI-ang,v1,v2))*10/v;//нахолим скорость по оси абсцисс
    p1.dY=-Math.sin(ang1)*Math.tanh(tch(Math.PI-ang,v1,v2))*10/v;//и ординат
    p2.dX=Math.cos(ang2)*Math.tanh(tch(ang,v2,v2))*10/v;
    p2.dY=Math.sin(ang2)*Math.tanh(tch(ang,v2,v2))*10/v;
    
   }

public class Particle{//класс частиц
    public attribute name:String ;
    public attribute color:Color;
    
    public attribute x:Number ;
    public attribute y:Number ;
    public attribute dX:Number ;
    public attribute dY:Number ;

    public attribute radius:Number ;
    public attribute mass:Number;
}

public class ParticleSystem extends CustomNode{//сама модель
    public attribute particles: Particle[];
    
    public attribute dt:Number = 0.05 ;
       public function run () {
                
        for (particle1 in particles){
            for (particle2 in particles[
            particle| particle != particle1]){
                var minDistance = particle1.radius + particle2.radius;
                if( abs(particle1.x - particle2.x) < minDistance and i==0){//столкновение
                    i=1;
                    System.out.println("Particle collision!");                                    
                    d(particle1, particle2);                    
                                    }
            }
        }
        
        for (particle in particles){//движение

            particle.x =  particle.dX * dt +  particle.x;
            particle.y =  particle.dY * dt +  particle.y;
            for (particle1 in particles){ //торможение
              for (particle2 in particles){
                if (Math.sqrt(particle1.x*particle1.x+particle1.y*particle1.y)>150 or (
                     Math.sqrt(particle2.x*particle2.x+particle2.y*particle2.y)>150) ) 
         {
                    particle1.dX=0;
                    particle1.dY=0;
                    particle2.dX=0;
                    particle2.dY=0;
                }
                }
                }
            
        }
    } 
    
    function create():Node{
        return Group{
            content: [
                for (particle in particles) 
                Circle{
                    radius: particle.radius
                    fill:  bind particle.color
                    centerX: bind particle.x
                    centerY: bind particle.y
                }
            ]
        }
    }
}


var particleSystem = ParticleSystem{
    transform: Transform.translate(250, 200)
            
    particles: [
        Particle{
            name: "Particle 1"
            mass: m1 
            radius: 4
            x: -149
            y: 0
            dX:  10
            dY:  0
            color: Color.GREEN
        },
        Particle{
            name: "Particle 2"
            mass: m2
            radius: 4
            x: 0
            y: 0
            dX:  0
            dY:  0
            color: Color.RED
        }
    ]
            
            
};

var timeline = Timeline {
        keyFrames:  KeyFrame { time: 0.01s,  action: function() { particleSystem.run() 
        } } 
    repeatCount: java.lang.Double.POSITIVE_INFINITY
} 

timeline.start();

Frame{
    title: "Particle Collision"
    width: 500
    height: 400
    closeAction: function(){ System.exit(0); 
    }
    stage: Stage{
        content: particleSystem
    }
    visible: true

}


Пример того, как можно задавать начальные данные для частиц:


import javafx.ext.swing.*;


public class SetupParticleSystem extends CustomNode{

    public attribute particles:Particle[];
    
    public attribute run:Boolean;
    
    attribute index:Integer on replace{
        mass   = "{particles[index].mass}";
        radius = "{particles[index].radius}";
    };
    
    attribute mass:String on replace{
        particles [index].mass = java.lang.Double.parseDouble(mass);
    };
    
    attribute radius:String on replace{
        particles [index].radius = java.lang.Double.parseDouble(radius);
    };
    
    
    function create():Node{
        return ComponentView {
            component: BorderPanel{
                left: List{
                    items: bind 
                        for (particle in particles) 
                        ListItem{
                            text: particle.name
                        }
                    selectedIndex: bind index with inverse  
                }
                center: FlowPanel{ content: GridPanel{
                    columns: 2, rows: 2
                    content: [
                        Label{ text: "Mass"},   TextField{ columns: 7, text: bind mass with inverse},
                        Label{ text: "Radius"}, TextField{ columns: 7, text: bind radius with inverse},
                    ]

                } }
                
                right: FlowPanel{ 
                    content: Button{
                        text: bind if(run) then "Stop" else "Run" 
                        action: function(){ run = not run;}
                    }
                }
                    
            }
        }
    }
    
}

Frame{
    title: "Particle Collision"
    width: 500
    height: 400
    closeAction: function(){ 
        System.exit(0); 
    }
    stage: Stage{
        content: [
            SetupParticleSystem{ particles: particleSystem.particles},
            particleSystem
        ]
    }
    visible: true

}

Оцените: Share this article: