I have a Box2D world with circles representing pedestrians and squares representing buildings, I have an algorithm which finds the nearest building and then it will turn at the edge but I have a problem that it will turn when it is exactly in the middle between the buildings, so the algorithm kind of works but not the way I want it
def pedestrian_walk(pedestrian, buildings):
## Find the building nearest to the pedestrian
list_of_distances = []
for building in buildings:
list_of_distances.append(np.sqrt((pedestrian.body.position[0] - building.footprint.position[0])**2 + (pedestrian.body.position[1] - building.footprint.position[1])**2))
pedestrian.nearest_building= list_of_distances.index(min(list_of_distances))
#print(f"Nearest builing index is: {pedestrian.nearest_building}")
building = buildings[pedestrian.nearest_building]
#Pedestrian walks around the left side of the nearest building
if pedestrian.body.position[0] <= building.position[0] and building.position[1] - building.shape[1] <= pedestrian.position[1] <= building.position[1] + 1.05*building.shape[1]:
pedestrian.body.__SetLinearVelocity(b2Vec2(0,pedestrian.ped_velocity))
print("1st if")
#Pedestrian walks around the right side of the nearest building
elif pedestrian.body.position[0] > building.position[0] and building.position[1] - building.shape[1] <= pedestrian.position[1]<= building.position[1] + 1.05*building.shape[1]:
pedestrian.body.__SetLinearVelocity(b2Vec2(0,-pedestrian.ped_velocity))
print("2nd if")
#Pedestrian walks around the upper side of the nearest building
elif pedestrian.body.position[1] > building.position[1] and building.position[0] - building.shape[0] <= pedestrian.position[0] <= building.position[0] + 1.05*building.shape[0]:
pedestrian.body.__SetLinearVelocity(b2Vec2(pedestrian.ped_velocity,0))
print("3rd if")
#Pedestrian walks around the lower side of the nearest building
elif pedestrian.body.position[1] <= building.position[1] and building.position[0] - building.shape[0] <= pedestrian.position[0] <= building.position[0] + 1.05*building.shape[0]:
pedestrian.body.__SetLinearVelocity(b2Vec2(-pedestrian.ped_velocity,0))
print("4th if")
I call the function in pygame main game loop and it works OK:
Skyscrapers = create four buildings
while running:
...
while k <= MAX_AMOUNT_PEDESTRIANS:
random_skyscraper = random.choice(skyscrapers) #Randomly choose a skyscraper next to which a pedestrian is generated
skyscraper_to_walk_around.append(random_skyscraper)
new_walker = Pedestrian(box2world, position = (random_skyscraper.position[0] -random.randint(-random_skyscraper.shape[0],random_skyscraper.shape[0]),\
random_skyscraper.position[1] -random.randint(-random_skyscraper.shape[1],random_skyscraper.shape[1])))
walkers.append(new_walker)
positive_negative.append([-1,1][random.randrange(2)])
k = k+1
for ped in range(MAX_AMOUNT_PEDESTRIANS):
pedestrian_walk(walkers[ped],skyscrapers)
And if possible I would have another request, is there any more "pythonic" way how to make the code simpler or cleaner (but this is a secondary problem, I need to solve the turning first)? Thank you very much
EDIT: The main idea behind my code is this: I have classes Pedestrian and Building, Pedestrians are dynamic bodies and buildings are static bodies. I need pedestrians to move around its nearest building and cross "streets" (I tried to find working algorithm in my previous question "Rolling a circle around a square" where you can find my definition of both classes. I was able to kind of solve the rolling problem, it is not working perfectly but satisfactorily
The problem is that when the pedestrian tries to cross the "street" and it gets exactly in the middle between the two buildings it does not move still forward to the second building, but it turns by 90° and it goes "in the middle of a road"
The problem is in the if statement when it changes the nearest building parameter it also skips from let's say 1st if to 3rd if... I do not know how to fix it
I did my best to made myself clear, but if any questions about my code remain I could post my code (I tried to avoid that because it is not very short code)
I tried to change my code in the function for the nearest building as recommended in a comment below but unfortunately, it did not work
Image: Here is an image of what it is doing now, I want the yellow circles ("pedestrians") to walk around those blue squares ("buildings") within limits given by those blue lines ("fences"). I want pedestrians to find their nearest building (that works OK) and then walk around the building, or at least turn when they reach the corner of the nearest building, but as you can see the pedestrians change their direction at the moment when "nearest_building" parameter is changed... It is clearly visible that they are walking down in the middle of a "street"... that's wrong