我正在查看boids的一些伪代码,并用C ++编写。但是,我发现boids偶尔会相互碰撞。考虑到伪代码的简单性,我认为我已经正确编程了。然而,当我显示所有boids的位置时,其中一些具有相同的坐标。
链接中的伪代码:
PROCEDURE rule2(boid bJ)
Vector c = 0;
FOR EACH BOID b
IF b != bJ THEN
IF |b.position - bJ.position| < 100 THEN
c = c - (b.position - bJ.position)
END IF
END IF
END
RETURN c
END PROCEDURE
我的代码是:
std::pair <signed int, signed int> keep_distance(std::vector <Boid> & boids, Boid & boid){
signed int dx = 0;
signed int dy = 0;
for(Boid & b : boids){
if (boid != b){ // this checks an "id" number, not location
if (b.dist(boid) < MIN_DIST){
dx -= b.get_x() - boid.get_x();
dy -= b.get_y() - boid.get_y();
}
}
}
return std::pair <signed int, signed int> (dx, dy);
}
带
MIN_DIST = 100;
unsigned int Boid::dist(const Boid & b){
return (unsigned int) sqrt((b.x - x) * (b.x - x) + (b.y - y) * (b.y - y));
}
这两个代码之间唯一的主要区别应该是代替vector c
,而是使用组件代替。
我用来移动每个boid的函数的顺序是:
center_of_mass(boids, new_boids[i]); // rule 1
match_velocity(boids, new_boids[i]); // rule 3
keep_within_bound(new_boids[i]);
tendency_towards_place(new_boids[i], mouse_x, mouse_y);
keep_distance(boids, new_boids[i]); // rule 2
有什么东西显而易见吗?也许是一些愚蠢的矢量算术我做错了?
答案 0 :(得分:3)
规则并没有说boids不会碰撞。他们只是不想。 :)
正如您在此代码段中看到的那样:
FOR EACH BOID b
v1 = rule1(b)
v2 = rule2(b)
v3 = rule3(b)
b.velocity = b.velocity + v1 + v2 + v3
b.position = b.position + b.velocity
END
没有检查以确保它们不会发生碰撞。如果这些数字不合适,它们仍然会发生碰撞。
话虽如此,如果你为多个boids获得完全相同的位置,但仍然不太可能。它会指出编程错误。
答案 1 :(得分:2)
在文章的后面他有这段代码:
ROCEDURE move_all_boids_to_new_positions()
Vector v1, v2, v3, ...
Integer m1, m2, m3, ...
Boid b
FOR EACH BOID b
v1 = m1 * rule1(b)
v2 = m2 * rule2(b)
v3 = m3 * rule3(b)
b.velocity = b.velocity + v1 + v2 + v3 + ...
b.position = b.position + b.velocity
END
END PROCEDURE
(虽然实际上我会使m1成为double
而不是Integer
)如果rule1
是命名不佳的规则,使得boids试图避免彼此,只需增加值m1
他们会相互转得更快。此外,增加MIN_DIST
会导致他们注意到他们即将相互碰撞,并且降低他们的最大速度(函数vlim
中的limit_velocity
)将允许他们做出反应更接近碰撞。
正如其他人所提到的那样,没有什么能够100%保证不会发生碰撞,但这些调整会减少碰撞的可能性。