5

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

enter image description here

halfer
  • 19,824
  • 17
  • 99
  • 186
Mechatrnk
  • 101
  • 1
  • 13
  • Maybe explain your code a little bit. It's hard to understand what is your main idea/algorithm. – A. Mashreghi Nov 25 '19 at 22:44
  • 1
    See edit, I tried to explain it more – Mechatrnk Nov 25 '19 at 22:56
  • In the following line "if np.sqrt((pedestrian.body.position[0] - building.footprint.position[0])**2 + (pedestrian.body.position[1] - building.footprint.position[1])**2) != building.shape[0]:" What is variable building? Because at this line you are outside the for loop. Shouldn't it be nearest_building instead? – A. Mashreghi Nov 25 '19 at 23:16
  • maybe if you draw a picture of what you want, compared to what your code currently does, it will help people understand your question better. – japreiss Nov 28 '19 at 11:19
  • Image added, as you wish – Mechatrnk Nov 28 '19 at 11:34
  • I have rolled this question back to the state it was in when you wrote an answer. The later version appeared to be missing a lot of information and thus could be closed as being off-topic. I also noticed that you'd added in some commentary about your answer, which does not belong in questions. Answer commentary belongs in answers `:=)`. – halfer Dec 01 '19 at 19:24

1 Answers1

2

Well, I was able to find the answer myself, the problem was that I did not set the limits of if statement correctly, now it works. I made this improvement:

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 either the left or right side of the nearest building
    if building.position[0] - 1.15*building.shape[0]  <=pedestrian.body.position[0] <= building.position[0] + 1.15*building.shape[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 either lower or upper side of the nearest building
    elif building.position[1] - 1.15*building.shape[1] <= pedestrian.body.position[1] <= building.position[1] + 1.15*building.shape[1]:
        pedestrian.body.__SetLinearVelocity(b2Vec2(-pedestrian.ped_velocity,0))
        print("2nd if")
halfer
  • 19,824
  • 17
  • 99
  • 186
Mechatrnk
  • 101
  • 1
  • 13
  • 1
    I have removed the new question - answers are strictly for answer material only. Would you ask your supplementary question as a new question please? You can point back to this page if you wish. – halfer Dec 01 '19 at 19:22