我正在使用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组中的随机移动?