基于Java的人群模拟的有限状态机

时间:2017-08-18 11:26:37

标签: java javafx

我正在使用Java构建人群模拟。我已经基于MVC框架拆分了我的应用程序。我使用了植绒算法来模拟人们的动作。现在我需要一群人沿着一条路走。我试图使用FSM来做这件事但需要一些额外的指导。

每组乘客都是由一个ArrayList组成,其中一个小三角形符号代表每位乘客。

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import utility.Vector2d;
import javafx.animation.PathTransition;
import javafx.animation.Timeline;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.shape.Circle;
import javafx.scene.shape.CubicCurveTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;


public class Flock2 {
public ArrayList<BusinessPersonBoid> boids2;
private double movementFactor = 1000;       
private double boundingFactor = 10;         
private int seperationDistance = 43;        
private double seperationFactor = 50;   


Circle c = new Circle();
Circle c2 = new Circle();


public Flock2() {
    boids2 = new ArrayList<BusinessPersonBoid>();


    Random randNum = new Random();
    RandomName randName = new RandomName();

    for(int i = 0; i < 10; i++) {
        int  x = randNum.nextInt(1000) + 1;
        int  y = randNum.nextInt(400) + 1;

        boids2.add(new BusinessPersonBoid(x,y, randName.getName(), c ));
    } 

} 


public void updateBoidsPostion() {
    Vector2d v1, v2, v3, v4, v5 = new Vector2d();
    for (BusinessPersonBoid cBoid : boids2) {

        Path path = new Path();
        path.getElements().add(new MoveTo(-50,140));
        path.getElements().add(new MoveTo(150,140));
        path.getElements().add(new MoveTo(750,140));
        path.getElements().add(new MoveTo(910,-40));

        PathTransition pathTransition = new PathTransition();

        pathTransition.setPath(path);
        pathTransition.setNode(cBoid);



    v1 = groupFlock(cBoid);
    v2 = collisionAvoidance(cBoid);
    v3 = matchFlockVelocity(cBoid);
    v4 = bounding(cBoid);
    v5 = positionTend(cBoid);




    Vector2d sum = new Vector2d();
    sum = sum.add(v1);
    sum = sum.add(v2);
    sum = sum.add(v3);
    sum = sum.add(v4);
    sum = sum.add(v5);




    cBoid.setVelocity(cBoid.getVelocity().add(sum));
    Vector2d next = new Vector2d( cBoid.getPosition().add(cBoid.getVelocity()) );
    cBoid.setPosition(next);
    Vector2d next2 = new Vector2d( cBoid.getPosition().add(cBoid.getVelocity()) );





    pathTransition.play();


    }
}


private Vector2d groupFlock(BusinessPersonBoid cBoid) {
    Vector2d center = new Vector2d();

    for (BusinessPersonBoid aBoid : boids2) {
        if(!aBoid.equals(cBoid)) {
            center = center.add(aBoid.getPosition());
        }
    }
    center = center.division(boids2.size() - 1 );
    center = center.subtract(cBoid.getPosition());
    center = center.division(movementFactor);

    return center;   
}


private Vector2d collisionAvoidance(BusinessPersonBoid cBoid) {
    Vector2d correction = new Vector2d();
    Vector2d cPosition = new Vector2d(cBoid.getPosition());

    for (BusinessPersonBoid aBoid : boids2) {
        if (!aBoid.equals(cBoid)) {
            Vector2d aPosition = aBoid.getPosition();
            Vector2d xD = new Vector2d(aPosition.xPos - cPosition.xPos, aPosition.yPos - cPosition.yPos);

            if(Math.abs(xD.xPos) < seperationDistance && Math.abs(xD.yPos) < seperationDistance) {  
                correction = correction.subtract(xD).division(seperationFactor);
            }

        }
}
return correction;
}


private Vector2d matchFlockVelocity(BusinessPersonBoid cBoid) {
    Vector2d perceivedVelocity = new Vector2d();

    for(BusinessPersonBoid aBoid : boids2) {
        if(!aBoid.equals(cBoid)) {
            perceivedVelocity = perceivedVelocity.add(aBoid.getVelocity());
        }
    }
    perceivedVelocity = perceivedVelocity.division(boids2.size() - 1);
    perceivedVelocity = perceivedVelocity.subtract(cBoid.getVelocity());
    perceivedVelocity = perceivedVelocity.division(8);
    return perceivedVelocity;
}


private Vector2d bounding(BusinessPersonBoid cBoid) {
    Vector2d bound = new Vector2d();

    int xMin = 0, xMax = 1400, yMin = 0, yMax = 320;

    Vector2d cPos = cBoid.getPosition();

    if (cPos.xPos < xMin) {
         bound.xPos += 1;
         cPos.xPos = bound.xPos;
    } else if (cPos.xPos > xMax){
        bound.xPos += -100;
        cPos.xPos = bound.xPos;
    }
    if (cPos.yPos < yMin) {
         bound.yPos += 1;
         cPos.yPos = bound.yPos;
    } else if (cPos.yPos > yMax){
        bound.yPos += -100;
        cPos.yPos = bound.yPos;
    }

    bound = bound.division(boundingFactor);

    return bound;
}


private Vector2d positionTend(BusinessPersonBoid cBoid) {
    Vector2d place = new Vector2d(900,600); 
    Vector2d tend = new Vector2d();

    tend = new Vector2d(place.subtract(cBoid.getPosition()));
    tend.division(6000);        
    return tend;
}


public List<ImageView> getBoidsRepresentation() {
    List<ImageView> circles = new ArrayList<ImageView>();
    for(BusinessPersonBoid aBoid : boids2) {
        circles.add( aBoid.getDisplay() );
    }
    return circles;
}


private Vector2d bounding2(BusinessPersonBoid cBoid) {
    Vector2d bound = new Vector2d();

    int xMin = 0, xMax = 600, yMin = 0, yMax = 600;

    Vector2d cPos = cBoid.getPosition();


         bound.xPos = 100;
         cPos.xPos = bound.xPos;

         bound.yPos = 100;
         cPos.yPos = bound.yPos;


    bound = bound.division(boundingFactor);

    return bound;
}

这是我改变路径的尝试:

private Vector2d pathway(BusinessPersonBoid cBoid) {
    Vector2d pathway = new Vector2d();

    Path path = new Path();
    path.getElements().add(new MoveTo(20,20));
    path.getElements().add(new CubicCurveTo(380, 0, 380, 120, 200, 120));
    path.getElements().add(new CubicCurveTo(0, 120, 0, 240, 380, 240));
    PathTransition pathTransition = new PathTransition();
    pathTransition.setDuration(Duration.millis(4000));
    pathTransition.setPath(path);
    pathTransition.setNode(cBoid);


  return pathway;
}

目前,它对于boids所采取的整体途径没有影响。他们需要从一个屏幕区域移动到另一个区域,但保留该组内的随机移动。

我的问题是什么是最好的方法将boids从屏幕的一个区域移动到另一个区域,同时保留boids组中的随机移动?

0 个答案:

没有答案