00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef COMPUTATIONAL_GEOMETRY_H
00032 #define COMPUTATIONAL_GEOMETRY_H
00033
00034 #include <cmath>
00035 #include <vector>
00036 #include <string>
00037 #include "AO_cpp.h"
00038 #include "three_frame.h"
00039
00040 namespace Arroyo {
00041
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 std::vector<Arroyo::three_point>
00058 get_line_segment_intersection(const three_point & a1,
00059 const three_point & a2,
00060 const three_point & b1,
00061 const three_point & b2);
00062
00063
00068
00069
00070
00071
00072 Arroyo::three_point get_ray_ray_intersection(
00073 const Arroyo::three_point & o_a,
00074 const Arroyo::three_vector & n_a,
00075 const Arroyo::three_point & o_b,
00076 const Arroyo::three_vector & n_b);
00077
00082
00083
00084
00085
00086 Arroyo::three_point get_ray_plane_intersection(
00087 const Arroyo::three_point & o_a,
00088 const Arroyo::three_vector & n_a,
00089 const Arroyo::three_point & o_b,
00090 const Arroyo::three_vector & n_b);
00091
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 double get_area_of_polygon(
00104 const std::vector<Arroyo::three_point> & polygon_vertices);
00105
00123 bool point_within_polygon(const three_point & tp,
00124 const vector<three_point> & vertices,
00125 bool & point_on_edge,
00126 bool & point_on_vertex);
00127
00130 bool point_within_polygon(
00131 const three_point & tp, const vector<three_point> & vtp);
00132
00149 vector<three_point> get_convex_polygon_intersection(
00150 const vector<three_point> & first_polygon_vertices,
00151 const vector<three_point> & second_polygon_vertices,
00152 int verbose = 0);
00153
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 vector<three_point> get_line_segment_circle_intersection(
00169 const three_point & a1,
00170 const three_point & a2,
00171 const three_point & circle_origin,
00172 const double & radius,
00173 vector<bool> & intersection_point_on_boundary,
00174 int verbose=0);
00175
00176
00191 vector<three_point> get_convex_polygon_circle_intersection(
00192 const vector<three_point> & polygon_vertices,
00193 const three_frame & circle_tf,
00194 double radius);
00195
00196
00207 template<class T>
00208 void convex_polygon_integration(const three_frame & tf,
00209 const vector<three_point> & polygon_vertices,
00210 T & x_intgrl,
00211 T & y_intgrl,
00212 int verbose = 0){
00213 try{
00214 x_intgrl = y_intgrl = 0;
00215 int nvertices = polygon_vertices.size();
00216
00217
00218 if(nvertices<=2) return;
00219
00220 double slope_b, slope_c;
00221 double intercept_b, intercept_c;
00222 double x_a, y_a, x_b, y_b, x_c, y_c;
00223 double last_x_b, last_y_b, last_x_c, last_y_c;
00224 double xmin, ymin, xmax, ymax;
00225 double sign;
00226 int index;
00227 double tmp;
00228
00230
00232
00233 index = 0;
00234 x_a = polygon_vertices[0].x(tf);
00235 for(int i=1; i<nvertices; i++){
00236 tmp = polygon_vertices[i].x(tf);
00237 if(tmp<x_a){
00238 index = i;
00239 x_a = tmp;
00240 }
00241 }
00242 int indexb=index, indexc=index;
00243
00244 do {
00245 indexb = (indexb+1)%nvertices;
00246 x_b = polygon_vertices[indexb].x(tf);
00247 } while((x_b-x_a)<three_frame::precision);
00248
00249 do {
00250 indexc = (indexc-1+nvertices)%nvertices;
00251 x_c = polygon_vertices[indexc].x(tf);
00252 } while((x_c-x_a)<three_frame::precision);
00253
00254 sign = 1;
00255 if(polygon_vertices[indexc].y(tf)>polygon_vertices[indexb].y(tf))
00256 sign = -1;
00257
00258 if(verbose) cerr << "x input indices " << indexb
00259 << "\t" << indexc << endl;
00260
00261 while(1){
00262 if(indexb==indexc) break;
00263
00264 y_b = polygon_vertices[indexb].y(tf);
00265 last_x_b = polygon_vertices[(indexb-1+nvertices)%nvertices].x(tf);
00266 last_y_b = polygon_vertices[(indexb-1+nvertices)%nvertices].y(tf);
00267
00268 slope_b = (y_b-last_y_b)/(x_b-last_x_b);
00269 intercept_b = y_b - slope_b*x_b;
00270
00271 y_c = polygon_vertices[indexc].y(tf);
00272 last_x_c = polygon_vertices[(indexc+1)%nvertices].x(tf);
00273 last_y_c = polygon_vertices[(indexc+1)%nvertices].y(tf);
00274
00275 slope_c = (y_c-last_y_c)/(x_c-last_x_c);
00276 intercept_c = y_c - slope_c*x_c;
00277
00278 xmin = last_x_b > last_x_c ? last_x_b : last_x_c;
00279 xmax = x_b < x_c ? x_b : x_c;
00280 ymin = y_b;
00281 ymax = y_c;
00282 if(y_b>y_c){
00283 ymin = y_c;
00284 ymax = y_b;
00285 }
00286
00287 x_intgrl += sign*((slope_b-slope_c)*(xmax*xmax*xmax - xmin*xmin*xmin)/3.0 +
00288 (intercept_b - intercept_c)*(xmax*xmax - xmin*xmin)/2.0);
00289
00290 if(verbose){
00291 cerr << "\tindices " << indexb << "\t" << indexc << endl;
00292 cerr << "\tlast indices " << (indexb-1+nvertices)%nvertices
00293 << "\t" << (indexc+1)%nvertices << endl;
00294 cerr << "\tb coords " << x_b << ", " << y_b << "\t"
00295 << " c coords " << x_c << ", " << y_c << endl;
00296 cerr << "\tlast b coords " << last_x_b << ", " << last_y_b << "\t"
00297 << " last c coords " << last_x_c << ", " << last_y_c << endl;
00298 cerr << "\tx min " << xmin << "\tx max " << xmax << endl;
00299 cerr << "\tsign " << sign << "\tslopes " << slope_b << "\t"
00300 << slope_c << endl;
00301 cerr << "\tintercepts " << intercept_b << "\t" << intercept_c << endl;
00302 cerr << "\tintgrl " << x_intgrl << endl;
00303 }
00304
00305 if(fabs(x_b-x_c)<three_frame::precision){
00306 indexb = (indexb+1)%nvertices;
00307 if(indexb==indexc) break;
00308 indexc = (indexc-1+nvertices)%nvertices;
00309 } else if(x_b<x_c){
00310 indexb = (indexb+1)%nvertices;
00311 } else {
00312 indexc = (indexc-1+nvertices)%nvertices;
00313 }
00314 if(verbose)
00315 cerr << "\tupdated indices " << indexb << "\t"
00316 << indexc << "\t" << y_intgrl << endl;
00317 }
00318
00319
00321
00323
00324 index = 0;
00325 y_a = polygon_vertices[0].y(tf);
00326 for(int i=1; i<nvertices; i++){
00327 tmp = polygon_vertices[i].y(tf);
00328 if(tmp<y_a){
00329 index = i;
00330 y_a = tmp;
00331 }
00332 }
00333 indexb=index;
00334 indexc=index;
00335
00336 do {
00337 indexb = (indexb+1)%nvertices;
00338 y_b = polygon_vertices[indexb].y(tf);
00339 } while((y_b-y_a)<three_frame::precision);
00340
00341 do {
00342 indexc = (indexc-1+nvertices)%nvertices;
00343 y_c = polygon_vertices[indexc].y(tf);
00344 } while((y_c-y_a)<three_frame::precision);
00345
00346 sign = 1;
00347 if(polygon_vertices[indexc].x(tf)>polygon_vertices[indexb].x(tf))
00348 sign = -1;
00349
00350 if(verbose) cerr << "y input indices " << indexb << "\t" << indexc << endl;
00351
00352 while(1){
00353 if(indexb==indexc) break;
00354
00355 x_b = polygon_vertices[indexb].x(tf);
00356 last_x_b = polygon_vertices[(indexb-1+nvertices)%nvertices].x(tf);
00357 last_y_b = polygon_vertices[(indexb-1+nvertices)%nvertices].y(tf);
00358
00359 slope_b = (x_b-last_x_b)/(y_b-last_y_b);
00360 intercept_b = x_b - slope_b*y_b;
00361
00362 x_c = polygon_vertices[indexc].x(tf);
00363 last_x_c = polygon_vertices[(indexc+1)%nvertices].x(tf);
00364 last_y_c = polygon_vertices[(indexc+1)%nvertices].y(tf);
00365
00366 slope_c = (x_c-last_x_c)/(y_c-last_y_c);
00367 intercept_c = x_c - slope_c*y_c;
00368
00369 ymin = last_y_b > last_y_c ? last_y_b : last_y_c;
00370 ymax = y_b < y_c ? y_b : y_c;
00371 xmin = x_b;
00372 xmax = x_c;
00373 if(x_b>x_c){
00374 xmin = x_c;
00375 xmax = x_b;
00376 }
00377
00378 y_intgrl += sign*((slope_b-slope_c)*(ymax*ymax*ymax - ymin*ymin*ymin)/3.0 +
00379 (intercept_b - intercept_c)*(ymax*ymax - ymin*ymin)/2.0);
00380
00381 if(verbose){
00382 cerr << "\tindices " << indexb << "\t" << indexc << endl;
00383 cerr << "\tlast indices " << (indexb-1+nvertices)%nvertices
00384 << "\t" << (indexc+1)%nvertices << endl;
00385 cerr << "\tb coords " << x_b << ", " << y_b << "\t"
00386 << " c coords " << x_c << ", " << y_c << endl;
00387 cerr << "\tlast b coords " << last_x_b << ", " << last_y_b << "\t"
00388 << " last c coords " << last_x_c << ", " << last_y_c << endl;
00389 cerr << "\ty min " << ymin << "\ty max " << ymax << endl;
00390 cerr << "\tsign " << sign << "\tslopes " << slope_b << "\t"
00391 << slope_c << endl;
00392 cerr << "\tintercepts " << intercept_b << "\t" << intercept_c << endl;
00393 cerr << "\tintgrl " << y_intgrl << endl;
00394 }
00395
00396 if(fabs(y_b-y_c)<three_frame::precision){
00397 indexb = (indexb+1)%nvertices;
00398 if(indexb==indexc) break;
00399 indexc = (indexc-1+nvertices)%nvertices;
00400 } else if(y_b<y_c){
00401 indexb = (indexb+1)%nvertices;
00402 } else {
00403 indexc = (indexc-1+nvertices)%nvertices;
00404 }
00405 if(verbose)
00406 cerr << "\tupdated indices " << indexb << "\t"
00407 << indexc << "\t" << y_intgrl << endl;
00408 }
00409
00410 if(verbose)
00411 cerr << "returning " << x_intgrl << "\t" << y_intgrl << endl << endl;
00412 } catch(...) {
00413 cerr << "convex_polygon_integration error\n";
00414 throw(string("convex_polygon_integration"));
00415 }
00416 }
00417 }
00418
00419 #endif