我正在尝试实现基于 Cornrad Prkers 算法的植绒程序。我似乎在总结所有力量(对齐、凝聚力和分离)时遇到问题。我一直有一种奇怪的行为。
算法的对齐部分负责速度匹配。
public Point alignment(Boids boid){
double xVelocity = 0;
double yVelocity = 0;
ArrayList<Boids> neighborhood = new ArrayList<Boids>();
neighborhood = neighborHood(boid, Boids.DetectionRange);
if(neighborhood.size() > 1){
for(int i = 0; i < neighborhood.size(); i++){
Boids otherBoid = neighborhood.get(i);
if(boid != otherBoid){
xVelocity += otherBoid.velocity.x;
yVelocity += otherBoid.velocity.y;
}
}
xVelocity /= neighborhood.size();
yVelocity /= neighborhood.size();
}
else{
return new Point(0, 0);
}
return new Point((int)xVelocity, (int)yVelocity);
}
分离负责避免碰撞
public Point sepration(Boids boid){
double xPosition = boid.location.x;
double yPosition = boid.location.y;
double xDistance = 0;
double yDistance = 0;
ArrayList<Boids> neighborhood = new ArrayList<Boids>();
neighborhood = neighborHood(boid, Boids.SeperationRange);
if (neighborhood.size() > 1){
for(int i = 0; i < neighborhood.size(); i++){
Boids otherBoid = this.get(i);
if(boid != otherBoid){
xDistance = (int) (boid.location.x - otherBoid.location.x);
yDistance = (int) (boid.location.y - otherBoid.location.y);
if(boid.checkCollision(otherBoid.getLocation())){
if(xDistance > 0 && xDistance < Boids.SeperationRange){
xPosition -= xDistance;
}
if(yDistance > 0 && yDistance < Boids.SeperationRange){
yPosition -= yDistance;
}
}
}
}
}else{
return new Point(0,0);
}
xPosition /= neighborhood.size();
yPosition /= neighborhood.size();
return new Point((int)xPosition, (int)yPosition);
}
凝聚力负责植绒行为,只要它们在检测范围内,就会相互吸引。
public Point cohesion(Boids boid){
int x = 0;
int y = 0;
ArrayList<Boids> neighborhood = new ArrayList<Boids>();
neighborhood = neighborHood(boid, Boids.DetectionRange);
if (neighborhood.size() > 0){
for(int i = 0; i < neighborhood.size(); i++){
Boids otherBoid = neighborhood.get(i);
if(boid != otherBoid){
x += otherBoid.location.x;
y += otherBoid.location.y;
}
x /= neighborhood.size();
y /= neighborhood.size();
}
}else{
return new Point(0 , 0); // empty vector
}
return new Point(x, y);
}
每个转向行为都会返回一个向量(Java 中的点),然后我对其进行归一化,然后应用单位向量的加权力,以将其移动一个单位到其目标点。