Moving object collisions detection

edited March 2018 in Questions about Code

Hi, I want to simulate moving cars at intersection and I have problem to avoid moving cars collisions. I have two types of moving object. Type 1 is moving object from left to right direction and Type 2 is moving object from right to left. Cars in Type 1 move straight and turn right, and Cars in Type 2 do the same thing. I want to detect and avoid collisions between cars from Type 1 and Type 2. The idea is when car(s) in Type 1 enter to intersection and detect there is/are car(s) in intersection area the cars stop and wait until there is no car in the intersection from opposite direction then they can turn right, and this goes for the opposite moving object too

Here is my code which consists of road geometry and moving cars from both directions. Hope you can give me suggestion to solve the problem. I'm sorry this is a long code because I am confused to make it short.. Thanks for the attention

  //create list of cars
ArrayList<Car> listCar; //listcar left
ArrayList<Car> listCar_right; //listcar right
ArrayList<Car> listCar_top; //listcar top
ArrayList<Car> listCar_buttom; //listcar buttom

float detik;
float timer;
int[] output_car; //menyimpan kendaraan yang keluar persimpangan

//create two traffic light
Light l = new Light(260, 200, "v");
//Light l2 = new Light(510, 550, "h");


float car_width = 50;
float car_height = 70;
float right_lane = 325; //aslinya 430
float left_lane = 325;

//floatersection boundaries
float inter_st = 300;
float inter_end = 500;
//float time = second();
float back = 450;

void setup() {
  //size of canvas
  size(800, 800);

  //create array output
  output_car = new int[4];

  //create list of cars
  listCar = new ArrayList();
  listCar_right = new ArrayList();
}

void drawRoad() {
  fill(120);
  noStroke();

  //road
  rect(0, 300, width, 200);
  rect(300, 0, 200, height);

  fill(240, 240, 0); //yellow line
  rect(0, 395, 300, 10); //left 
  rect(395, 0, 10, 300); //top 
  rect(395, 500, 10, 300); //bottom
  rect(500, 395, 300, 10); //right

  fill(240);
  rect(300, 295, 200, 5);
  rect(300, 500, 200, 5);
  rect(295, 300, 5, 200);
  rect(500, 300, 5, 200);
}

void draw() {
  background(40,100,0);
  drawRoad();
  l.drawLight();
  lightSync();

  detik = second();
  fill(255);
  text("s ="+second() +"Millis="+millis()+  "   timer="+timer, 20, 20);
  text("Right="+output_car[0], 20, 35);
  text("Left="+output_car[1], 20, 50);

////////////////car from left
  for(int i=0;i<listCar.size();i++){
    float d;
    Car car1 = (Car)listCar.get(i);
    //car1.drawCar();

    //find distanct each car
    if(i == 0){ //kalau mobil pertama
        //car1.setDx(3);
        d = 4;
    }
    else{
        //get previous position
        Car car_prev = listCar.get(i-1);

        //get position 2 following cars        
        float posX1 = car_prev.getX();
        float posX2 = car1.getX() + 60;

        //get distance = d
        d = posX1 - posX2;

        if(d<0){
          d = 4;
        }
    }


    whatdo(car1, l, inter_st, 1, d);

    println("car="+ i +"dx="+car1.getDx() + " px="+car1.getX() + "d=" +d );
    //count the leaving car
    count_car(car1, inter_end, 0);

  } //end car from left

////////////////car from right
  for(int i=0;i<listCar_right.size();i++){
    float d;
    Car car1 = (Car)listCar_right.get(i);
    car1.drawCar();

    //find distanct each car
    if(i == 0){ //kalau mobil pertama
        //car1.setDx(-0.1);
        d = -4;
    }
    else{
        //get previous position
        Car car_prev = listCar_right.get(i-1);

        //get position 2 following cars        
        float posX1 = car_prev.getX() + 60;
        float posX2 = car1.getX();

        //get distance
        d = (posX2 - posX1)*(-1);
    }

    whatdo(car1, l, inter_end, -1, d);

    //println("car="+ i +"dx="+car1.getDx() + " px="+car1.getX() + "d=" +d );

    //count the leaving car
    count_car(car1, inter_st, 1);

  } //end car from right


  if(itstime()){
    listCar.add(new Car(-40, 360, 50, 30, random_color(255), "h", 1, round(random(1,2)), 0, round(random(1,2)))); //x, y, w, h, c, dir, direction, dx, dy, turn
    listCar_right.add(new Car(800, 460, 50, 30, random_color(255), "h", -1, round(random(-2,-1)), 0, 1));
    int ran = int(random(1000,1500));
    timer = timer + ran;
  }

}

boolean itstime(){
  return millis() >= timer;
}


//count car leave the intersection
void count_car(Car c, float end_intersection, int index){
  float pos;

  if(c.getDir() == "h"){ //jika horizontal
      pos = c.getX();    
  }else{
      pos = c.getY(); 
  }

  if(c.getDirection() > 0){ //jika left to right
      if(pos > end_intersection){
      if(c.getFlag() == 0){
        output_car[index]+=1;
      }
      c.setFlag(1);
   }
  }
  else{
    if(pos < end_intersection){
      if(c.getFlag() == 0){
        output_car[index]+=1;
      }
      c.setFlag(1);
   }
  }
}

color random_color(float v) {
  return color(random(v), random(v), random(v));
}

void turn_right_from_left(Car c, float d, String light){
println("dy="+c.getDy());

      if(c.getState() == 0 && c.getX() >= 300){ 
        if(c.getTurn() == 1){
          c.setState(0);
        }else{
          c.setState(1);
          c.setTime(millis());  
        }
      }

      if ( c.getState() == 1) {    
          if ( millis() - c.getTime() >= 2000 ) {
            c.setState(2);
            c.setX(0);
            c.setY(540);
          } else {
            //cek apakah ada kendaraan yang masuk di persimpangan kalau ada berhenti
            pushMatrix();
            translate(300, 540); //x ditranslasikan 300, y ditransalasikan 360 + jumlah putaran 150 + lebar kendaraan 30 = 
            rotate(map((millis() - c.getTime())%2000, 0, 2000, -HALF_PI, 0));
            fill(c.getC());
            rect(150, 0, 30, 50);
            popMatrix();
          }
        }

        if(c.getState() == 0){
          //harus dicek durasi dulu

          if(light.equals("green")){
               if(c.getDx() >= c.getVmax()){ //dicek apakah kecepatan lebih dari Vmax
                  c.setDx(0);
               }else{
                  c.setDx(1);
               } 
               c.drawCar();
               c.move(c.getDx(),c.getDy());

          }else{
            if(c.getDx() < d){
              if(c.getDx() >= c.getVmax()){ //dicek apakah kecepatan lebih dari Vmax
                  c.setDx(0);
               }else{
                  c.setDx(1);
               } 
               c.drawCar();
               if(c.getPos() >= 240){
                 c.move(0,0);
               }else{
                 c.move(c.getDx(),c.getDy());
               }

            } else{
              c.drawCar();
              c.move(d,0);
            }
          }
        }

        if(c.getState() == 2){
          pushMatrix();
          fill(c.getC());
          translate(450, 0); //x ditambah 150 & y ditambah 150 + lebar kendaraan(30)

          //cek v
          if(c.getDy() >= c.getVmax()){ //dicek apakah kecepatan lebih dari Vmax
              c.setDy(0);
           }else{
              c.setDy(1);
           }

          rect(c.getX(), c.getY(), 30, 50); 
          c.move(0,c.getDy());
          popMatrix();
        }
}

void whatdo(Car c, Light l, float intersection_start, float direction, float d ) {
  switch(l.getState()) {

    case "green":
      if(direction > 0){ //if direction 1 in green time
        turn_right_from_left(c, d, l.getState());
      }

      else{ //if direction -1 in green time
        if(c.getDx() > d){ //jika kecepatan kendaraan kurang dari distance        
            if(c.getDx() > c.getVmax()){ //dicek apakah kecepatan lebih dari Vmax
              c.setDx(-1);
            }else{
              c.setDx(0);
            } 
            c.move(c.getDx(),c.getDy());
         }
         else{
            c.move(d,0); //kurangi kecepatan
         }
      }
    break;

    case "red":

      if(direction > 0){ 
        turn_right_from_left(c, d, l.getState());   
      } //end of direction 1

      else{ //if direction -1
        if (c.getPos() <= intersection_start || c.getPos() > intersection_start + 10){
          if(c.getDx() > d){ //jika kecepatan kendaraan kurang dari distance        
            if(c.getDx() > c.getVmax()){ //dicek apakah kecepatan lebih dari Vmax
              c.setDx(-1);
            }else{
              c.setDx(0);              
            } 
            c.move(c.getDx(),c.getDy());
         }
         else{
            c.move(d,0); //kurangi kecepatan
         }
        }else{
          c.move(0,0);
        }
      } //end of direction -1

    break;
  }
}

void lightSync() {
  int time = frameCount/60;
  int fps = time%30;

  if (fps == 0) {
    l.toggleLight("green");
  } 
  else if (fps == 7) {
    l.toggleLight("red");
  }
  else if (fps == 10) {
    l.toggleLight("green");
  }
  else if (fps == 15) {
    l.toggleLight("red");
  }
  else if (fps == 20) {
    l.toggleLight("green");
  }
  else if (fps == 25) {
    l.toggleLight("green");
  }
}

//CAR CLASS
class Car {
  float x, y; //x position, y position
  float w, h; //weight, height/lenght
  color c; //color
  String dir; // h = horizontal, v = vertical
  int direction; // 1 = left-to-right, 2 = right-to-left
  int flag; //car status
  float dx, dy; //dx = x velocity, dy = y velocity
  int turn; //turn=> 1 = Straight, 2 = right, 3 = left
  int vmax;
  int state, time; 

  Car(float x, float y, float w, float h, color c, String dir, int direction, float dx, float dy, int turn) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.c = c;
    this.dir = dir;
    this.direction = direction;
    this.flag = 0;
    this.dx = dx;
    this.dy = dy;
    this.turn = turn;
    this.vmax = 4;
    state = 0;
    time = -1;
  }

  void drawCar() {
    fill(c);
    rect(x, y, w, h); 
  }

  int getState(){
    return state;
  }

  void setState(int state){
    this.state = state;
  }

  int getTime(){
    return time;
  }

  void setTime(int time){
    this.time = time;
  }

  int getVmax(){
    if(getDirection() == -1){
      vmax = vmax * -1;
    }

    return vmax;
  }

  color getC(){
    return c;
  }

  int getTurn(){
    return turn;
  }

  String getDir(){
    return dir;
  }

  int getDirection(){
    return direction;
  }

  float getX(){
    return this.x; 
  }

  float getY(){
    return this.y; 
  }


  void setX(int x){
    this.x = x;
  }

  void setY(int y){
    this.y = y;
  }

  float getPos(){
    if (this.dir.equals("h")){
       return x; 
     }else{
       return y;
     } 
  }

  float getDx(){
    return dx;
  }

  float getDy(){
    return dy;
  }

  void setDx(float distX){
    dx = this.dx + distX;
  }

  void setDy(float distY){
    dy = this.dy + distY;
  }

  float get_width(){
    return w;
  }

  void setD(int dx, int dy){
    if((this.dir.equals("h") & direction > 0) | (this.dir.equals("v") & direction > 0)){
        if(dx >= 3 || dy >= 3){
            dx = 3;
            dy = 3;
        }else{
            x = this.x + dx;
            y = this.y + dy;
        }
    }else if((this.dir.equals("h") & direction < 0) | (this.dir.equals("v") & direction < 0)){
        if(dx <= -3 || dy <= -3){
            dx = -3;
            dy = -3;
        }else{
            x = this.x + dx;
            y = this.y + dy;
        }
    }
  }

  void setDist(float dx){
     dx = this.dx + dx;
  }

  void setZero(){
    dx = 0;
  }

  void move() {
    this.x = this.x + this.dx;
    this.y = this.y + this.dy;  
  }

  //with parameter
  void move(float dx, float dy) {
    this.dx = dx;
    this.dy = dy;

    this.x = this.x + this.dx;
    this.y = this.y + this.dy;
  }

  //get flag
  int getFlag(){
    return flag;
  }

  //set flag
  void setFlag(int flag){
      this.flag = flag;
  }
} //END CAR CLASS


//CLASS LIGHT
class Light {
  String col, dir;
  float x, y;
  Light(float x, float y, String dir) {
    this.x = x;
    this.y = y;
    this.col = "red";
    this.dir = dir;
  }
  void drawLight() {
    fill(200);
    noStroke();
    rect(this.x, this.y, 30, 90);
    if (this.col.equals("red")) {
      fill(250, 0, 0);
    } else {
      fill(100);
    }
    ellipse(this.x+15, this.y+15, 20, 20);
    if (this.col.equals("yellow")) {
      fill(250, 250, 0);
    } else {
      fill(100);
    }
    ellipse(this.x+15, this.y+45, 20, 20);
    if (this.col.equals("green")) {
      fill(0, 250, 0);
    } else {
      fill(100);
    }
    ellipse(this.x+15, this.y+75, 20, 20);
    if (dir.equals("v")) {
      fill(0);
      rect(this.x, this.y-20, 25, 5);
      triangle(this.x+25, this.y-25, this.x+25, this.y-10, this.x+32, this.y-18);
    } else {
      fill(0);
      rect(this.x+10, this.y-40, 5, 25);
      triangle(this.x+5, this.y-40, this.x+12, this.y-47, this.x+20, this.y-40);
    }
  }

  void toggleLight(String col) {
    if (col.equals("red") || col.equals("yellow") || col.equals("green")) {
      this.col=col;
    }
  }


  String getState() {
    return this.col;
  }
}

Answers

  • I update the code but still can not avoid the car collision from different arraylist .. is there anyone that can help me.. please

Sign In or Register to comment.