// hw7vc.cpp //#include // not in this series #include #include #include #include #include "vc_delay.h" // or some delay routine #include "vc_plotd.h" // or some other plot package // simulation.h #ifdef VMS #define CLOCKS_PER_SEC CLK_TCK #endif int CLK_PER_SEC = CLOCKS_PER_SEC/2; // divide by bigger number for faster cars enum direction { north, east, south, west }; enum signal_state { green, yellow, red , none, stop }; float scale; // user must scale simulation to screen/window void initialize(void); int unique_id(void); void get_offsets(direction moving, float &x_offset, float &y_offset); // end simulation.h // simulation.cpp static int next_id = 0; void initialize(CDC *pDC) { INITIALIZE(pDC); } int unique_id(void) { next_id++; return next_id; } void get_offsets(direction moving, float &x_offset, float &y_offset) { switch( moving ) { case north: x_offset = 0.0F; y_offset = 1.0F; break; case east: x_offset = 1.0F; y_offset = 0.0F; break; case south: x_offset = 0.0F; y_offset = -1.0F; break; case west: x_offset = -1.0F; y_offset = 0.0F; } } // end simulation.cpp // vehicle.h // #include class vehicle { public: vehicle( float Alength, float Aweight, float Aaccel, float Adecell, float Aposition, float Aspeed, float Aspeed_limit, float Ax_base, float Ay_base, direction Amoving, float Asignal_pos, vehicle *Anext_ptr); void move(void); vehicle *next(void); void set_signal(signal_state Asignal); void draw(void); private: int id; float length; float weight; float accel; float decell; float position; float position_last; float speed; float speed_limit; float time_last_move; float x_base; float y_base; direction moving; signal_state signal; float signal_pos; vehicle *next_ptr; }; // end vehicle.h // vehicle.cpp vehicle::vehicle( float Alength, float Aweight, float Aaccel, float Adecell, float Aposition, float Aspeed, float Aspeed_limit, float Ax_base, float Ay_base, direction Amoving, float Asignal_pos, vehicle *Anext_ptr) { id = unique_id(); length = Alength; weight = Aweight; accel = Aaccel; decell = Adecell; position = Aposition; position_last = Aposition; speed = Aspeed; speed_limit = Aspeed_limit; time_last_move = (float)clock()/CLK_PER_SEC; x_base = Ax_base; y_base = Ay_base; moving = Amoving; signal = none; signal_pos = Asignal_pos; next_ptr = Anext_ptr; } void vehicle::move(void) { float delta_time; float separation = 16.0F/10.0F; // 16 feet per 10 feet per second float speed_temp; float position_temp; float stopping_distance; delta_time = (float)clock()/CLK_PER_SEC - time_last_move; if(delta_time > 4.0) delta_time = 4.0F; time_last_move = (float)clock()/CLK_PER_SEC; position_last = position; speed_temp = speed; // attempt normal movement, accelerate to speed limit if (speed_temp < speed_limit) // try to accelerate { speed_temp = speed + accel*delta_time; if (speed_temp > speed_limit) { speed_temp = speed_limit; } } position_temp = position + speed_temp*delta_time; // limit speed if necessary to keep distance from vehicle in front if (next_ptr != NULL) // check what is in front ( if any ) { if( position_temp + separation*speed_temp > next_ptr->position - next_ptr->length) { speed_temp = speed; position_temp = position + speed_temp*delta_time; if (position_temp + separation*speed_temp > next_ptr->position - next_ptr->length) { // must slow down to keep distance from vehicle in front if (speed > 0.0F) // can not back up { speed_temp = speed - decell*delta_time; if (speed_temp < 0.0F) { speed_temp = 0.0F; } } position_temp = position + speed_temp*delta_time; } } } position_temp = position + speed_temp*delta_time; // if signal is red, yellow or stop in range, must decelerate switch (signal) { case red: case yellow: case stop: if (speed_temp >= speed) { stopping_distance = 0.5F * speed_temp * speed_temp / decell; if (stopping_distance > signal_pos-position_temp) { if (speed > 0.0F) // can not back up { speed_temp = speed - decell*delta_time; if (speed_temp < 0.0F) { speed_temp = 0.0F; } } position_temp = position + speed_temp*delta_time; } } } position = position_temp; speed = speed_temp; draw(); } // end move vehicle *vehicle::next(void) { return next_ptr; } void vehicle::set_signal(signal_state Asignal) { signal = Asignal; } void vehicle::draw(void) { float x_offset; float y_offset; char any_string[4]; sprintf(any_string,"%d",id); get_offsets(moving, x_offset, y_offset); if (position_last < signal_pos) { WRITE_TEXT(x_base+x_offset*position_last/scale, y_base+y_offset*position_last/scale, any_string, CLEAR_FILL); } if (position < signal_pos) { WRITE_TEXT(x_base+x_offset*position/scale, y_base+y_offset*position/scale, any_string, OUTLINE); } } // end draw // end vehicle.cpp void hw7vc(CDC *pDC) { int i; vehicle *vehicle_list = NULL; printf("hw7 running \n"); // debug to a terminal window, if any delay(1); initialize(pDC); scale = 50.0F; vehicle_list = new vehicle(16.0F, 3000.0F, 8.0F, 9.0F, 0.0F, 0.0F, 88.0F, -38.0F, 0.0F, east, 75.0F*scale, vehicle_list); vehicle_list->set_signal(stop); for( i=0; i<4; i++) { delay(1); vehicle_list->move(); PRINT(); } vehicle_list = new vehicle( 16.0F, 3000.0F, 7.0F, 9.0F, 0.0F, 0.0F, 88.0F, -38.0F, 0.0F, east, 75.0F*scale, vehicle_list); for( i=0; i<4; i++) { delay(1); (vehicle_list->next())->move(); vehicle_list->move(); PRINT(); } vehicle_list = new vehicle(16.0F, 3000.0F, 6.0F, 9.0F, 0.0F, 0.0F, 88.0F, -38.0F, 0.0F, east, 75.0F*scale, vehicle_list); for( i=1; i<30; i++) { delay(1); // Homework 7 use 'set_new_lane_data(0.0, 88.0, 0.0, 0.0, north, 75.0*scale)' // on one vehicle when i==10 ((vehicle_list->next())->next())->move(); (vehicle_list->next())->move(); vehicle_list->move(); PRINT(); } CLOSE(); printf("hw7 finished \n"); } // end hw7vc.cpp main for homework