2 ///////////////////////////////////////////////////////////////////////////
3 // This program is free software: you can redistribute it and/or modify //
4 // it under the terms of the version 3 of the GNU General Public License //
5 // as published by the Free Software Foundation. //
7 // This program is distributed in the hope that it will be useful, but //
8 // WITHOUT ANY WARRANTY; without even the implied warranty of //
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
10 // General Public License for more details. //
12 // You should have received a copy of the GNU General Public License //
13 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
15 // Written by Francois Fleuret, (C) IDIAP //
16 // Contact <francois.fleuret@idiap.ch> for comments & bug reports //
17 ///////////////////////////////////////////////////////////////////////////
24 memset(this, 0, sizeof(*this));
27 void Pose::horizontal_flip(scalar_t scene_width) {
28 _head_xc = scene_width - 1 - _head_xc;
29 _belly_xc = scene_width - 1 - _belly_xc;
32 void Pose::translate(scalar_t dx, scalar_t dy) {
33 _bounding_box_xmin += dx;
34 _bounding_box_ymin += dy;
35 _bounding_box_xmax += dx;
36 _bounding_box_ymax += dy;
43 void Pose::scale(scalar_t factor) {
44 _bounding_box_xmin *= factor;
45 _bounding_box_ymin *= factor;
46 _bounding_box_xmax *= factor;
47 _bounding_box_ymax *= factor;
50 _head_radius *= factor;
55 const scalar_t tolerance_scale_ratio_for_hit = 1.5;
56 const scalar_t tolerance_distance_factor_for_hit = 1.0;
58 bool Pose::hit(int level, Pose *pose) {
62 if(_head_radius/pose->_head_radius > tolerance_scale_ratio_for_hit ||
63 pose->_head_radius/_head_radius > tolerance_scale_ratio_for_hit)
66 scalar_t sq_delta = _head_radius * pose->_head_radius * sq(tolerance_distance_factor_for_hit);
70 if(sq(_head_xc - pose->_head_xc) + sq(_head_yc - pose->_head_yc) > sq_delta)
73 if(level == 0) return true;
77 if(sq(_belly_xc - pose->_belly_xc) + sq(_belly_yc - pose->_belly_yc) > 4 * sq_delta)
80 if(level == 1) return true;
82 cerr << "Hit criterion is undefined for level " << level << endl;
87 const scalar_t tolerance_scale_ratio_for_collide = 1.2;
88 const scalar_t tolerance_distance_factor_for_collide = 0.25;
90 bool Pose::collide(int level, Pose *pose) {
94 if(_head_radius/pose->_head_radius > tolerance_scale_ratio_for_collide ||
95 pose->_head_radius/_head_radius > tolerance_scale_ratio_for_collide)
98 scalar_t sq_delta = _head_radius * pose->_head_radius * sq(tolerance_distance_factor_for_collide);
102 if(sq(_head_xc - pose->_head_xc) + sq(_head_yc - pose->_head_yc) <= sq_delta)
105 if(level == 0) return false;
109 if(sq(_belly_xc - pose->_belly_xc) + sq(_belly_yc - pose->_belly_yc) <= sq_delta)
112 if(level == 1) return false;
114 cerr << "Colliding criterion is undefined for level " << level << endl;
119 void Pose::draw(int thickness, int r, int g, int b, int level, RGBImage *image) {
120 // Draw the head circle
122 image->draw_ellipse(thickness, r, g, b,
123 _head_xc, _head_yc, _head_radius, _head_radius, 0);
127 scalar_t vx = _belly_xc - _head_xc, vy = _belly_yc - _head_yc;
128 scalar_t l = sqrt(vx * vx + vy * vy);
132 scalar_t belly_radius = 12 + thickness / 2;
134 if(l > _head_radius + thickness + belly_radius) {
135 image->draw_line(thickness, r, g, b,
136 _head_xc + vx * (_head_radius + thickness/2),
137 _head_yc + vy * (_head_radius + thickness/2),
138 _belly_xc - vx * (belly_radius - thickness/2),
139 _belly_yc - vy * (belly_radius - thickness/2));
142 // An ugly way to make a filled disc
143 for(scalar_t u = 0; u < belly_radius; u += thickness / 2) {
144 image->draw_ellipse(thickness, r, g, b, _belly_xc, _belly_yc, u, u, 0);
150 void Pose::print(ostream *out) {
151 (*out) << " _head_xc " << _head_xc << endl;
152 (*out) << " _head_yc " << _head_yc << endl;
153 (*out) << " _head_radius " << _head_radius << endl;
154 (*out) << " _belly_xc " << _belly_xc << endl;
155 (*out) << " _belly_yc " << _belly_yc << endl;
158 void Pose::write(ostream *out) {
159 write_var(out, &_bounding_box_xmin);
160 write_var(out, &_bounding_box_ymin);
161 write_var(out, &_bounding_box_xmax);
162 write_var(out, &_bounding_box_ymax);
163 write_var(out, &_head_xc); write_var(out, &_head_yc);
164 write_var(out, &_head_radius);
165 write_var(out, &_belly_xc);
166 write_var(out, &_belly_yc);
169 void Pose::read(istream *in) {
170 read_var(in, &_bounding_box_xmin);
171 read_var(in, &_bounding_box_ymin);
172 read_var(in, &_bounding_box_xmax);
173 read_var(in, &_bounding_box_ymax);
174 read_var(in, &_head_xc); read_var(in, &_head_yc);
175 read_var(in, &_head_radius);
176 read_var(in, &_belly_xc);
177 read_var(in, &_belly_yc);