📄 visual.cc
字号:
if( fabs( ang ) < self().vis_angle * 0.5 ) { double qstep = self().distQStep(); double quant_dist = calcQuantDist( un_quant_dist, qstep ); double prob = ( ( quant_dist - TEAM_FAR_LENGTH ) / ( TEAM_TOOFAR_LENGTH - TEAM_FAR_LENGTH ) ); if( decide( prob ) ) { serializer().serializeVisualObject( transport(), calcTFarName( player ), calcDegDir( ang ) ); } else { prob = ( ( quant_dist - UNUM_FAR_LENGTH ) / ( UNUM_TOOFAR_LENGTH - UNUM_FAR_LENGTH ) ); if( decide( prob ) ) { serializer().serializeVisualObject( transport(), calcUFarName( player ), calcDegDir( ang ) ); } else { serializer().serializeVisualObject( transport(), calcName( player ), calcDegDir( ang ) ); } } } else if( un_quant_dist <= self().vis_distance ) { serializer().serializeVisualObject( transport(), calcCloseName( player ), calcDegDir( ang ) ); } } void VisualSenderPlayerV1::sendHighPlayer( const Player& player ) { double ang = calcRadDir( player ); double un_quant_dist = calcUnQuantDist( player ); double qstep = self().distQStep(); double quant_dist = calcQuantDist( un_quant_dist, qstep ); if( fabs( ang ) < self().vis_angle * 0.5 ) { double prob = ( ( quant_dist - TEAM_FAR_LENGTH ) / ( TEAM_TOOFAR_LENGTH - TEAM_FAR_LENGTH ) ); if( decide( prob ) ) { serializer().serializeVisualObject( transport(), calcTFarName( player ), quant_dist, calcDegDir( ang ) ); } else { prob = ( ( quant_dist - UNUM_FAR_LENGTH ) / ( UNUM_TOOFAR_LENGTH - UNUM_FAR_LENGTH ) ); if( decide( prob ) ) { serializePlayer( player, calcUFarName( player ), quant_dist, calcDegDir( ang ) ); } else { double dist_chg, dir_chg; calcVel ( player.vel, player.pos, un_quant_dist, quant_dist, dist_chg, dir_chg ); serializePlayer( player, calcName( player ), quant_dist, calcDegDir( ang ), dist_chg, dir_chg ); } } } else if( un_quant_dist <= player.vis_distance ) { serializer().serializeVisualObject( transport(), calcCloseName( player ), quant_dist, calcDegDir( ang ) ); } } bool VisualSenderPlayerV1::sendLine( const PObject& line ) { /*! the angle of an outward pointing normal ( 90degs to ) to the line */ double line_normal; //! perp distance of the player from the line double player_2_line; //! the x of y value of where the line starts double line_start; //! the x or y value of where the line stops double line_stop; //! a flag to specify if the line is vertical or horizontal bool vert; /*! be very carefull here. The lines pos.x is actually it's distance from the center of the field, not neccesarily it's x position. */ //! left line if( line.pos.x == -PITCH_LENGTH*0.5 ) { line_normal = PI; if( self().pos.x < line.pos.x ) line_normal = 0.0; player_2_line = line.pos.x - self().pos.x; line_start = -PITCH_WIDTH*0.5; line_stop = PITCH_WIDTH*0.5; vert = true; } //! right line else if( line.pos.x == PITCH_LENGTH*0.5 ) { line_normal = 0.0; if( self().pos.x > line.pos.x ) line_normal = PI; player_2_line = line.pos.x - self().pos.x; line_start = -PITCH_WIDTH*0.5; line_stop = PITCH_WIDTH*0.5; vert = true; } //! top line else if( line.pos.x == -PITCH_WIDTH*0.5 ) { line_normal = -PI*0.5; if( self().pos.y < line.pos.x ) line_normal = PI*0.5; player_2_line = line.pos.x - self().pos.y; line_start = -PITCH_LENGTH*0.5; line_stop = PITCH_LENGTH*0.5; vert = false; } //! bottom line else if( line.pos.x == PITCH_WIDTH*0.5 ) { line_normal = PI*0.5; if( self().pos.y > line.pos.x ) line_normal = -PI*0.5; player_2_line = line.pos.x - self().pos.y; line_start = -PITCH_LENGTH*0.5; line_stop = PITCH_LENGTH*0.5; vert = false; } else { std::cerr << __FILE__ << ": " << __LINE__ << ": Error, unknown line: " << line << std::endl; return false; } //! angle between the players line of sight and the line's normal double sight_2_line_ang = calcLineRadDir ( line_normal ); /*! if the angle between the line of sight and the line's norm is not within -90.0 and 90 degrees then the player is looking parallel or away from the line, thus it cannot be visible. */ if( fabs( sight_2_line_ang ) >= PI*0.5 ) { return false; } /*! this gives us the x or y offset from the player for where their line of sight intersects the line */ double line_intersect = player_2_line * tan( sight_2_line_ang ); /*! this calculates the actual x or y value for where the line of sight intersects the line. Because the y axis is inverted, we need to use -line_intersect if the line is vertical. */ if( vert ) line_intersect = self().pos.y - line_intersect; else line_intersect += self().pos.x; /*! If the point that the players line of sight intersects the line beyond it's beginning or end then the player wont see this line */ if( line_intersect < line_start || line_intersect > line_stop ) { return false; } serializeLine( calcName( line ), calcLineDir( sight_2_line_ang ), sight_2_line_ang, player_2_line ); return true; } void VisualSenderPlayerV1::serializeLowLine( const char* name, int dir, double, double ) { serializer().serializeVisualObject( transport(), name, dir ); } void VisualSenderPlayerV1::serializeHighLine( const char* name, int dir, double sight_2_line_ang, double player_2_line ) { double dist = calcLineDist( sight_2_line_ang, player_2_line, self().landDistQStep() ); serializer().serializeVisualObject( transport(), name, dist, dir ); } double VisualSenderPlayerV1::calcRadDir( const PObject& obj ) { return normalize_angle( self().vangle( obj ) - self().angle_neck_committed ); } int VisualSenderPlayerV1::calcDegDir( double rad_dir ) const { return rad2Deg( rad_dir ); } double VisualSenderPlayerV1::calcLineRadDir( double line_normal ) const { return normalize_angle( line_normal - self().angle - self().angle_neck_committed ); } int VisualSenderPlayerV1::calcLineDir( double sight_2_line_ang ) const { if( sight_2_line_ang > 0 ) return rad2Deg( sight_2_line_ang - PI*0.5 ); else return rad2Deg( sight_2_line_ang + PI*0.5 ); } double VisualSenderPlayerV1::calcUnQuantDist( const PObject& obj ) const { return self().pos.distance( obj.pos ); } double VisualSenderPlayerV1::calcQuantDist( const double& dist, const double& qstep ) const { return Quantize( exp( Quantize( log( dist + EPS ), qstep ) ), 0.1 ); } double VisualSenderPlayerV1::calcLineDist( double sight_2_line_ang, double player_2_line, double qstep ) const { return Quantize( exp( Quantize( log( fabs( player_2_line / cos( sight_2_line_ang ) ) + EPS ), qstep ) ), 0.1 ); } void VisualSenderPlayerV1::calcVel( const PVector& obj_vel, const PVector& obj_pos, double un_quant_dist, double quant_dist, double& dist_chg, double& dir_chg ) const { if( un_quant_dist != 0.0 ) { double qstep_dir = self().dirQStep(); PVector vtmp = obj_vel - self().vel; PVector etmp = obj_pos - self().pos; etmp /= un_quant_dist; dist_chg = vtmp.x * etmp.x + vtmp.y * etmp.y; dir_chg = RAD2DEG * ( vtmp.y * etmp.x - vtmp.x * etmp.y ) / un_quant_dist; dir_chg = ( dir_chg == 0.0 ? 0.0 : Quantize ( dir_chg, qstep_dir ) ); dist_chg = ( quant_dist * Quantize ( dist_chg / un_quant_dist, 0.02 ) ); } else { dir_chg = 0.0; dist_chg = 0.0; } } bool VisualSenderPlayerV1::decide( double prob ) { if( prob >= 1.0 ) return true; else if( prob <= 0.0 ) return false; else { boost::bernoulli_distribution< random::DefaultRNG > decider( random::DefaultRNG::instance(), prob ); return decider(); } } void VisualSenderPlayerV1::serializePlayer( const Player&, const char* name, double dist, int dir, double dist_chg, double dir_chg ) { serializer().serializeVisualObject( transport(), name, dist, dir, dist_chg, dir_chg ); } void VisualSenderPlayerV1::serializePlayer( const Player&, const char* name, double dist, int dir ) { serializer().serializeVisualObject( transport(), name, dist, dir ); } int VisualSenderPlayerV1::rad2Deg( double rad ) const { return Rad2IDeg( rad ); } const char* VisualSenderPlayerV1::calcName( const PObject& obj ) const { return obj.name; } const char* VisualSenderPlayerV1::calcCloseName( const PObject& obj ) const { switch ( obj.getObjectType() ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -