基于Java的群组仿真有限状态机

基于Java的群组仿真有限状态机,java,javafx,Java,Javafx,我正在使用Java构建群组模拟。我已经基于MVC框架拆分了我的应用程序。我使用了群集算法来模拟人们的运动。现在我需要一群人沿着既定的道路前进。我试图用FSM来做这件事,但需要一些额外的指导 每组乘客由一个阵列列表组成,该列表中有一个小的三角形符号表示每个乘客 import java.util.ArrayList; import java.util.List; import java.util.Random; import utility.Vector2d; import javafx.anim

我正在使用Java构建群组模拟。我已经基于MVC框架拆分了我的应用程序。我使用了群集算法来模拟人们的运动。现在我需要一群人沿着既定的道路前进。我试图用FSM来做这件事,但需要一些额外的指导

每组乘客由一个阵列列表组成,该列表中有一个小的三角形符号表示每个乘客

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;
}
目前,它对BOID采取的整体路径没有影响。它们需要作为一个组从屏幕的一个区域移动到另一个区域,但在该组中保留随机移动


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

您忘记问实际问题了。请添加一个。我不能评论“最佳”方法,但尝试将boid位置编码为相对于组的位置,这样组作为一个整体移动,因为boid相对于组移动,它也必须移动相同的方向,但它也可以围绕质心随机移动。或者你可以有一个boid“响应”一段时间后,一个群体的运动是随机的,所以它的运动不会完全是随机的。
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;
}