Avoiding walls instead of bouncing?
in
Programming Questions
•
1 years ago
I'm completely new to Processing and most programming, so I don't even know how to begin coding for what I'm trying to accomplish. I'm making a Boids variant where I have an object that moves semi-randomly in a circular container.
When the object reaches one of the container walls, I want it to turn either left or right in a smooth arc of about 90 degrees in order to avoid the wall instead of immediately reversing directions like a bounce program.
This is my code so far, and I have my questions are in the comments on line 99 in order to avoid repeating myself. ANY advice or tutorials that could get me on the right track would be greatly appreciated, since I'm completely lost at this point.
- Cluster cluster;
- Stage stage;
- //PImage planarian;
- void setup() {
- size(600,600);
- cluster = new Cluster(); //Initialize the arrayList that contains all the moving objects
- stage = new Stage(width/2,height/2,250); //Draws a circular stage that contains the moving objects
- for (int i = 0; i < 1; i++) {
- cluster.addFworm(new Fworm(new PVector(width/2,height/2), 2.0f)); //Adds a new object to the arrayList (first boid
- //to the flock)
- }
- //planarian = loadImage("testW.png");
- }
- void draw() {
- background(220);
- stage.display();
- cluster.run(); //animates every object in the ArrayList
- }
- class Stage {
- float x;
- float y;
- float r;
- Stage(float x_, float y_, float r_){
- x = x_;
- y = y_;
- r = r_;
- }
- void display() {
- fill(240);
- noStroke();
- ellipse(x, y, r*2, r*2);
- }
- }
- class Cluster { //the 'flock' class from boids.
- ArrayList fworms; // contains all objects
- Cluster() {
- fworms = new ArrayList();
- }
- void run() {
- for (int i = 0; i < fworms.size(); i++) {
- Fworm f = (Fworm) fworms.get(i);
- f.run(fworms); //animates each individual object
- }
- }
- void addFworm(Fworm f) { //the add object function
- fworms.add(f);
- }
- }
- class Fworm {
- PVector loc;
- PVector vel;
- float max_wander_offset; //upper and lower ends of the range that generates a random number for changing
- float wander_theta; //the randomized value assigned to the velocity
- float wander_offset;
- float maxspeed; //prevents the velocity from steadily increasing
- float r;
- Fworm(PVector l, float ms) {
- loc = l.get();
- max_wander_offset = 0.1;
- wander_theta = random(TWO_PI);
- vel = new PVector();
- maxspeed = ms;
- r = 6.0;
- }
- void run(ArrayList fworms) {
- update();
- // borders(); <-- the now obsolete border checking function from Flocking
- render();
- }
- void update() {
- wander_offset = random(-max_wander_offset, max_wander_offset);
- wander_theta += wander_offset;
- vel.x += cos(wander_theta);
- vel.y += sin(wander_theta);
- vel.limit(maxspeed);
- if (dist(stage.x, stage.y, loc.x, loc.y) > 240) {
- loc.x = random((width/2)-150,(width/2)+150);
- loc.y = random((height/2)-150,(height/2)+150);
- //this is just a placeholder to test that the basic wall collision works. If the object's
- //distance from the center is greater than the radius, it places it within 150px of the center.
- //HERE'S WHAT I'M ASKING ABOUT: the object isn't supposed to 'bounce' when it hits a wall;
- //it is supposed to turn either left or right in a smooth arc of about 90 degrees in order to avoid it.
- //Here's my idea: whenever it reaches the limit, it checks left and right positions that are the same size
- //as the object itself and relative to its current heading [the object's current left and right, not a
- //global left and right.] The object will then turn towards and move to the position that isn't colliding
- //with the barrier, ceasing it's random movement temporarily. If both areas are clear, the object will
- //randomly choose between the two. Once the object has turned and arrived at the point, it resumes its
- //random motion.
- //With this object that moves by randomly adding X and Y values to its location, how can I determine the
- //values to its left and right?
- //How can I tell the object to move towards a certain point on the screen?*/
- //Am I thinking about this the right way? Are there any relevant examples out there???
- }
- loc.add(vel);
- print ("X Velocity:" + vel.x + " Y Velocity:" + vel.y);
- }
- void render() {
- float direction = vel.heading2D() + PI/2;
- fill(0); // the fill and stroke is only for the
- stroke(255); // temporary placeholder triangle
- pushMatrix();
- translate(loc.x,loc.y);
- rotate(direction);
- //image(planarian, 0, 0);
- beginShape(TRIANGLES); //I'm using the image above, but the triangles are just so anybody could test this
- vertex(0, -r*2);
- vertex(-r, r*2);
- vertex(r, r*2);
- endShape();
- popMatrix();
- }
- //This is just the old Boids collision detection, which won't be needed in this version
- /*void borders() { //this is just a placeholder to check the motion
- if (loc.x < -r) loc.x = width+r;
- if (loc.y < -r) loc.y = height+r;
- if (loc.x > width+r) loc.x = -r;
- if (loc.y > height+r) loc.y = -r;
- }*/
- }
1