00001 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00002 #pragma implementation
00003 #endif
00004
00005
00006
00007
00008
00009
00010 #include "vgui_soview2D.h"
00011
00012 #include <vcl_cmath.h>
00013 #include <vcl_iostream.h>
00014
00015 #include <vgl/vgl_distance.h>
00016 #include <vnl/vnl_math.h>
00017 #include <vil/vil_image_view_base.h>
00018 #include <vil/vil_new.h>
00019 #include <vil1/vil1_image.h>
00020 #include <vgui/vgui_range_map_params.h>
00021 #include <vgui/vgui_gl.h>
00022 #include <vgui/vgui_style.h>
00023 #include <vgui/vgui_section_buffer.h>
00024 #include <vgui/internals/vgui_draw_line.h>
00025
00026
00027
00028 vcl_ostream& vgui_soview2D_point::print(vcl_ostream& s) const
00029 {
00030 s << "[ vgui_soview2D_point " << x << ',' << y << ' ';
00031 return vgui_soview2D::print(s) << " ]";
00032 }
00033
00034 void vgui_soview2D_point::draw() const
00035 {
00036 #if 0
00037 style->apply_point_size();
00038 #endif // 0
00039 glBegin(GL_POINTS);
00040 glVertex2f(x,y);
00041 glEnd();
00042 }
00043
00044 void vgui_soview2D_point::draw_select() const
00045 {
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 float const rad = 0.0001f;
00058 glBegin(GL_POLYGON);
00059 glVertex2f( x - rad, y - rad );
00060 glVertex2f( x + rad, y - rad );
00061 glVertex2f( x + rad, y + rad );
00062 glVertex2f( x - rad, y + rad );
00063 glEnd();
00064 }
00065
00066 float vgui_soview2D_point::distance_squared(float vx, float vy) const
00067 {
00068 float dx = x - vx;
00069 float dy = y - vy;
00070 return dx*dx + dy*dy;
00071 }
00072
00073 void vgui_soview2D_point::get_centroid(float* vx, float* vy) const
00074 {
00075 *vx = x;
00076 *vy = y;
00077 }
00078
00079 void vgui_soview2D_point::translate(float tx, float ty)
00080 {
00081 x += tx;
00082 y += ty;
00083 }
00084
00085
00086
00087 vcl_ostream& vgui_soview2D_lineseg::print(vcl_ostream& s) const
00088 {
00089 s << "[ vgui_soview2D_lineseg " << x0 << ',' << y0 << " -- " << x1 << ',' << y1 << ' ';
00090 return vgui_soview2D::print(s) << " ]";
00091 }
00092
00093 void vgui_soview2D_lineseg::draw() const
00094 {
00095 #ifdef DEBUG
00096 vcl_cerr << "vgui_soview2D_lineseg::draw() line id=" << id << '\n';
00097 #endif
00098
00099 #if 0
00100 glLineWidth(style->line_width);
00101 #endif // 0
00102 glBegin(GL_LINES);
00103 glVertex2f(x0,y0);
00104 glVertex2f(x1,y1);
00105 glEnd();
00106 }
00107
00108 float vgui_soview2D_lineseg::distance_squared(float vx, float vy) const
00109 {
00110
00111
00112
00113
00114
00115
00116 return (float)vgl_distance2_to_linesegment(x0, y0, x1, y1, vx, vy);
00117 }
00118
00119 void vgui_soview2D_lineseg::get_centroid(float* vx, float* vy) const
00120 {
00121 *vx = (x0 + x1) / 2;
00122 *vy = (y0 + y1) / 2;
00123 }
00124
00125 void vgui_soview2D_lineseg::translate(float tx, float ty)
00126 {
00127 x0 += tx;
00128 y0 += ty;
00129 x1 += tx;
00130 y1 += ty;
00131 }
00132
00133
00134
00135 vgui_soview2D_group::~vgui_soview2D_group()
00136 {
00137 for (unsigned int i=0; i< ls.size(); i++)
00138 if ( ls[i] )
00139 delete ls[i];
00140
00141
00142 ls.clear();
00143 }
00144
00145 void vgui_soview2D_group::set_style(const vgui_style_sptr& s)
00146 {
00147 for (unsigned int i=0; i< ls.size(); i++)
00148 if (!ls[i]->get_style())
00149 ls[i]->set_style(s);
00150
00151 vgui_soview::set_style( s);
00152 }
00153
00154 vcl_ostream& vgui_soview2D_group::print(vcl_ostream& s) const
00155 {
00156 s << "[ vgui_soview2D_group ";
00157
00158 for (unsigned int i=0; i< ls.size(); i++)
00159 ls[i]->print(s);
00160
00161 return vgui_soview2D::print(s) << " ]";
00162 }
00163
00164 void vgui_soview2D_group::draw() const
00165 {
00166 for (unsigned int i=0; i< ls.size(); i++)
00167 ls[i]->draw();
00168 }
00169
00170 void vgui_soview2D_group::draw_select() const
00171 {
00172 for (unsigned int i=0; i< ls.size(); i++)
00173 ls[i]->draw_select();
00174 }
00175
00176 float vgui_soview2D_group::distance_squared(float vx, float vy) const
00177 {
00178 if (ls.size() == 0)
00179 return -1e30f;
00180
00181 float min= ls[0]->distance_squared( vx, vy);
00182
00183 for (unsigned int i=1; i< ls.size(); i++)
00184 {
00185 float d= ls[i]->distance_squared( vx, vy);
00186 if ( d< min ) min= d;
00187 }
00188
00189 return min;
00190 }
00191
00192 void vgui_soview2D_group::get_centroid(float* vx, float* vy) const
00193 {
00194 *vx = 0;
00195 *vy = 0;
00196 const int n = ls.size();
00197
00198 for (int i=0; i < n; i++)
00199 {
00200 float cx, cy;
00201 ls[i]->get_centroid(&cx, &cy);
00202 *vx += cx;
00203 *vy += cy;
00204 }
00205
00206 float s = 1.0f/n;
00207 *vx *= s;
00208 *vy *= s;
00209 }
00210
00211 void vgui_soview2D_group::translate(float tx, float ty)
00212 {
00213 for (unsigned int i=0; i < ls.size(); i++)
00214 ls[i]->translate(tx, ty);
00215 }
00216
00217
00218
00219 vcl_ostream& vgui_soview2D_infinite_line::print(vcl_ostream& s) const
00220 {
00221 s << "[ vgui_soview2D_infinite_line " << a << ',' << b << ',' << c << ' ';
00222 return vgui_soview2D::print(s) << " ]";
00223 }
00224
00225 void vgui_soview2D_infinite_line::draw() const
00226 {
00227 vgui_draw_line(a, b, c);
00228 }
00229
00230 float vgui_soview2D_infinite_line::distance_squared(float vx, float vy) const
00231 {
00232 float tmp = a*vx + b*vy + c;
00233 return tmp*tmp/(a*a + b*b);
00234 }
00235
00236 void vgui_soview2D_infinite_line::get_centroid(float* vx, float* vy) const
00237 {
00238 *vx = 0;
00239 *vy = 0;
00240 }
00241
00242 void vgui_soview2D_infinite_line::translate(float tx, float ty)
00243 {
00244 c += a * tx + b * ty;
00245 }
00246
00247
00248
00249 const int vgui__CIRCLE2D_LIST = 1;
00250
00251 void vgui_soview2D_circle::compile()
00252 {
00253 glNewList(vgui__CIRCLE2D_LIST, GL_COMPILE);
00254 glBegin(GL_LINE_LOOP);
00255 for (unsigned int i=0;i<100;i++)
00256 {
00257 double angle = i*(2*vnl_math::pi/100);
00258 glVertex2d(vcl_cos(angle), vcl_sin(angle));
00259 }
00260 glEnd();
00261 glEndList();
00262 }
00263
00264
00265 vcl_ostream& vgui_soview2D_circle::print(vcl_ostream& s) const
00266 {
00267 s << "[ vgui_soview2D_circle " << x << ',' << y << " r" << r << ' ';
00268 return vgui_soview2D::print(s) << " ]";
00269 }
00270
00271 void vgui_soview2D_circle::draw() const
00272 {
00273 glBegin(GL_LINE_LOOP);
00274 for (unsigned int i=0;i<100;i++)
00275 {
00276 double angle = i*(2*vnl_math::pi/100);
00277 glVertex2d(x+r*vcl_cos(angle), y+r*vcl_sin(angle));
00278 }
00279 glEnd();
00280 }
00281
00282 float vgui_soview2D_circle::distance_squared(float vx, float vy) const
00283 {
00284 float dx = x - vx;
00285 float dy = y - vy;
00286
00287
00288 float dcentre = vcl_sqrt(dx*dx + dy*dy);
00289
00290
00291 float dcircum = dcentre - this->r;
00292
00293 return dcircum * dcircum;
00294 }
00295
00296 void vgui_soview2D_circle::get_centroid(float* vx, float* vy) const
00297 {
00298 *vx = x;
00299 *vy = y;
00300 }
00301
00302 void vgui_soview2D_circle::translate(float tx, float ty)
00303 {
00304 x += tx;
00305 y += ty;
00306 }
00307
00308
00309
00310 vcl_ostream& vgui_soview2D_ellipse::print(vcl_ostream& s) const
00311 {
00312 s << "[ vgui_soview2D_ellipse " << x << ',' << y
00313 << " w" << w << " h" << h << " phi" << phi << ' ';
00314 return vgui_soview2D::print(s) << " ]";
00315 }
00316
00317 void vgui_soview2D_ellipse::draw() const
00318 {
00319 double px, py;
00320
00321 glBegin(GL_LINE_LOOP);
00322 for (unsigned int i=0;i<100;i++)
00323 {
00324 double angle = i*(2*vnl_math::pi/100);
00325 px = w*vcl_cos(this->phi)*vcl_cos(angle) + h*vcl_sin(this->phi)*vcl_sin(angle);
00326 py = h*vcl_cos(this->phi)*vcl_sin(angle) - w*vcl_sin(this->phi)*vcl_cos(angle);
00327 glVertex2d(x+px, y+py);
00328 }
00329 glEnd();
00330 }
00331
00332
00333
00334 float vgui_soview2D_ellipse::distance_squared(float vx, float vy) const
00335 {
00336 return (vx - x)*(vx - x) + (vy - y)*(vy - y);
00337 }
00338
00339 void vgui_soview2D_ellipse::get_centroid(float* vx, float* vy) const
00340 {
00341 *vx = x;
00342 *vy = y;
00343 }
00344
00345 void vgui_soview2D_ellipse::translate(float tx, float ty)
00346 {
00347 x += tx;
00348 y += ty;
00349 }
00350
00351
00352
00353
00354 vgui_soview2D_linestrip::vgui_soview2D_linestrip(unsigned n_, float const *x_, float const *y_)
00355 : n(n_), x(new float[n]), y(new float[n])
00356 {
00357 for (unsigned i=0; i<n; ++i)
00358 {
00359 x[i] = x_[i];
00360 y[i] = y_[i];
00361 }
00362 }
00363
00364 vgui_soview2D_linestrip::~vgui_soview2D_linestrip()
00365 {
00366 n=0;
00367 delete [] x; x=0;
00368 delete [] y; y=0;
00369 }
00370
00371 void vgui_soview2D_linestrip::draw() const
00372 {
00373 glBegin(GL_LINE_STRIP);
00374 for (unsigned i=0; i<n; ++i)
00375 glVertex2f(x[i], y[i]);
00376 glEnd();
00377 }
00378
00379 vcl_ostream& vgui_soview2D_linestrip::print(vcl_ostream&s) const { return s << "[ a linestrip. FIXME ]"; }
00380
00381 float vgui_soview2D_linestrip::distance_squared(float vx, float vy) const
00382 {
00383 double tmp = vgl_distance_to_non_closed_polygon(x, y, this->n, vx, vy);
00384 return static_cast<float>(tmp*tmp);
00385 }
00386
00387 void vgui_soview2D_linestrip::get_centroid(float* vx, float* vy) const
00388 {
00389 *vx = 0;
00390 *vy = 0;
00391 for (unsigned i=0; i<n; ++i)
00392 {
00393 *vx += x[i];
00394 *vy += y[i];
00395 }
00396 float s = 1.0f / float(n);
00397 *vx *= s;
00398 *vy *= s;
00399 }
00400
00401 void vgui_soview2D_linestrip::translate(float tx, float ty)
00402 {
00403 for (unsigned i=0; i<n; ++i)
00404 {
00405 x[i] += tx;
00406 y[i] += ty;
00407 }
00408 }
00409
00410 void vgui_soview2D_linestrip::set_size(unsigned nn)
00411 {
00412 if (nn < n) { n = nn; return; }
00413
00414
00415 float *nx = new float[nn];
00416 float *ny = new float[nn];
00417 for (unsigned i=0; i<n; ++i)
00418 {
00419 nx[i] = x[i];
00420 ny[i] = y[i];
00421 }
00422
00423 n = nn;
00424 delete [] x; x = nx;
00425 delete [] y; y = ny;
00426 }
00427
00428
00429
00430 vgui_soview2D_polygon::vgui_soview2D_polygon(unsigned n_, float const *x_, float const *y_)
00431 : n(n_), x(new float[n]), y(new float[n])
00432 {
00433 for (unsigned i=0; i<n; ++i)
00434 {
00435 x[i] = x_[i];
00436 y[i] = y_[i];
00437 }
00438 }
00439
00440 vgui_soview2D_polygon::~vgui_soview2D_polygon()
00441 {
00442 n=0;
00443 delete [] x; x=0;
00444 delete [] y; y=0;
00445 }
00446
00447 void vgui_soview2D_polygon::draw() const
00448 {
00449 glBegin(GL_LINE_LOOP);
00450 for (unsigned i=0; i<n; ++i)
00451 glVertex2f(x[i], y[i]);
00452 glEnd();
00453 }
00454
00455 vcl_ostream& vgui_soview2D_polygon::print(vcl_ostream&s) const { return s << "[ a polygon. FIXME ]"; }
00456
00457 float vgui_soview2D_polygon::distance_squared(float vx, float vy) const
00458 {
00459 double tmp = vgl_distance_to_closed_polygon(x, y, this->n, vx, vy);
00460 return static_cast<float>(tmp*tmp);
00461 }
00462
00463 void vgui_soview2D_polygon::get_centroid(float* vx, float* vy) const
00464 {
00465 *vx = 0;
00466 *vy = 0;
00467 for (unsigned i=0; i<n; ++i)
00468 {
00469 *vx += x[i];
00470 *vy += y[i];
00471 }
00472 float s = 1.0f / float(n);
00473 *vx *= s;
00474 *vy *= s;
00475 }
00476
00477 void vgui_soview2D_polygon::translate(float tx, float ty)
00478 {
00479 for (unsigned i=0; i<n; ++i)
00480 {
00481 x[i] += tx;
00482 y[i] += ty;
00483 }
00484 }
00485
00486 void vgui_soview2D_polygon::set_size(unsigned nn)
00487 {
00488 if (nn < n) { n = nn; return; }
00489
00490
00491 float *nx = new float[nn];
00492 float *ny = new float[nn];
00493 for (unsigned i=0; i<n; ++i)
00494 {
00495 nx[i] = x[i];
00496 ny[i] = y[i];
00497 }
00498
00499 n = nn;
00500 delete [] x; x = nx;
00501 delete [] y; y = ny;
00502 }
00503
00504
00505
00506
00507 vgui_soview2D_image::vgui_soview2D_image( float in_x, float in_y,
00508 vil1_image const& img,
00509 bool in_blend,
00510 GLenum format,
00511 GLenum type )
00512 : x_( in_x ),
00513 y_( in_y ),
00514 w_( img.width() ),
00515 h_( img.height() ),
00516 blend_( in_blend ),
00517 buffer_( new vgui_section_buffer( 0, 0, w_, h_, format, type ) )
00518 {
00519 buffer_->apply( img , (vgui_range_map_params*) 0);
00520 }
00521
00522 vgui_soview2D_image::vgui_soview2D_image( float in_x, float in_y,
00523 vil_image_view_base const& img,
00524 bool in_blend,
00525 GLenum format,
00526 GLenum type )
00527 : x_( in_x ),
00528 y_( in_y ),
00529 w_( img.ni() ),
00530 h_( img.nj() ),
00531 blend_( in_blend ),
00532 buffer_( new vgui_section_buffer( 0, 0, w_, h_, format, type ) )
00533 {
00534 buffer_->apply( vil_new_image_resource_of_view( img ), (vgui_range_map_params*) 0);
00535 }
00536
00537 vgui_soview2D_image::~vgui_soview2D_image()
00538 {
00539 delete buffer_;
00540 }
00541
00542 void vgui_soview2D_image::draw() const
00543 {
00544
00545 GLboolean blend_on;
00546 glGetBooleanv( GL_BLEND, &blend_on );
00547
00548 if ( blend_ ) {
00549 glEnable( GL_BLEND );
00550 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00551 }
00552 else
00553 glDisable( GL_BLEND );
00554
00555 glTranslatef( x_, y_, 0.0f );
00556 buffer_->draw_as_image() || buffer_->draw_as_rectangle();
00557 glTranslatef( -x_, -y_, 0.0f );
00558
00559 if ( blend_on )
00560 glEnable( GL_BLEND );
00561 else
00562 glDisable( GL_BLEND );
00563 }
00564
00565 vcl_ostream& vgui_soview2D_image::print(vcl_ostream&s) const
00566 {
00567 return s << "[ vgui_soview2D_image "<<w_<<'x'<<h_<<", blend="<<blend_<<" ]";
00568 }
00569
00570 float vgui_soview2D_image::distance_squared(float vx, float vy) const
00571 {
00572 float dx = (x_ + (w_ / 2.0f)) - vx;
00573 float dy = (y_ + (h_ / 2.0f)) - vy;
00574 return dx*dx + dy*dy;
00575 }
00576
00577 void vgui_soview2D_image::get_centroid(float* vx, float* vy) const
00578 {
00579 float x1 = x_ + (w_ / 2.0f);
00580 float y1 = y_ + (h_ / 2.0f);
00581
00582 *vx = x1;
00583 *vy = y1;
00584 }
00585
00586 void vgui_soview2D_image::translate(float tx, float ty)
00587 {
00588 x_ += tx;
00589 y_ += ty;
00590 }