1 /*M/////////////////////////////////////////////////////////////////////////////////////// 2 // 3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 // 5 // By downloading, copying, installing or using the software you agree to this license. 6 // If you do not agree to this license, do not download, install, 7 // copy or use the software. 8 // 9 // 10 // License Agreement 11 // For Open Source Computer Vision Library 12 // 13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. 14 // Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved. 15 // Third party copyrights are property of their respective owners. 16 // 17 // @Authors 18 // Nghia Ho, nghiaho12 (at) yahoo.com 19 // 20 // Redistribution and use in source and binary forms, with or without modification, 21 // are permitted provided that the following conditions are met: 22 // 23 // * Redistribution's of source code must retain the above copyright notice, 24 // this list of conditions and the following disclaimer. 25 // 26 // * Redistribution's in binary form must reproduce the above copyright notice, 27 // this list of conditions and the following disclaimer in the documentation 28 // and/or other materials provided with the distribution. 29 // 30 // * The name of OpenCV Foundation may not be used to endorse or promote products 31 // derived from this software without specific prior written permission. 32 // 33 // This software is provided by the copyright holders and contributors "as is" and 34 // any express or implied warranties, including, but not limited to, the implied 35 // warranties of merchantability and fitness for a particular purpose are disclaimed. 36 // In no event shall the OpenCV Foundation or contributors be liable for any direct, 37 // indirect, incidental, special, exemplary, or consequential damages 38 // (including, but not limited to, procurement of substitute goods or services; 39 // loss of use, data, or profits; or business interruption) however caused 40 // and on any theory of liability, whether in contract, strict liability, 41 // or tort (including negligence or otherwise) arising in any way out of 42 // the use of this software, even if advised of the possibility of such damage. 43 // 44 //M*/ 45 46 #include "test_precomp.hpp" 47 48 using namespace cv; 49 using namespace std; 50 51 #define ACCURACY 0.00001 52 53 class CV_RotatedRectangleIntersectionTest: public cvtest::ArrayTest 54 { 55 public: 56 57 protected: 58 void run (int); 59 60 private: 61 void test1(); 62 void test2(); 63 void test3(); 64 void test4(); 65 void test5(); 66 void test6(); 67 void test7(); 68 void test8(); 69 void test9(); 70 }; 71 72 void CV_RotatedRectangleIntersectionTest::run(int) 73 { 74 // See pics/intersection.png for the scenarios we are testing 75 76 // Test the following scenarios: 77 // 1 - no intersection 78 // 2 - partial intersection, rectangle translated 79 // 3 - partial intersection, rectangle rotated 45 degree on the corner, forms a triangle intersection 80 // 4 - full intersection, rectangles of same size directly on top of each other 81 // 5 - partial intersection, rectangle on top rotated 45 degrees 82 // 6 - partial intersection, rectangle on top of different size 83 // 7 - full intersection, rectangle fully enclosed in the other 84 // 8 - partial intersection, rectangle corner just touching. point contact 85 // 9 - partial intersetion. rectangle side by side, line contact 86 87 test1(); 88 test2(); 89 test3(); 90 test4(); 91 test5(); 92 test6(); 93 test7(); 94 test8(); 95 test9(); 96 } 97 98 void CV_RotatedRectangleIntersectionTest::test1() 99 { 100 // no intersection 101 102 RotatedRect rect1, rect2; 103 104 rect1.center.x = 0; 105 rect1.center.y = 0; 106 rect1.size.width = 2; 107 rect1.size.height = 2; 108 rect1.angle = 12.0f; 109 110 rect2.center.x = 10; 111 rect2.center.y = 10; 112 rect2.size.width = 2; 113 rect2.size.height = 2; 114 rect2.angle = 34.0f; 115 116 vector<Point2f> vertices; 117 118 int ret = rotatedRectangleIntersection(rect1, rect2, vertices); 119 120 CV_Assert(ret == INTERSECT_NONE); 121 CV_Assert(vertices.empty()); 122 } 123 124 void CV_RotatedRectangleIntersectionTest::test2() 125 { 126 // partial intersection, rectangles translated 127 128 RotatedRect rect1, rect2; 129 130 rect1.center.x = 0; 131 rect1.center.y = 0; 132 rect1.size.width = 2; 133 rect1.size.height = 2; 134 rect1.angle = 0; 135 136 rect2.center.x = 1; 137 rect2.center.y = 1; 138 rect2.size.width = 2; 139 rect2.size.height = 2; 140 rect2.angle = 0; 141 142 vector<Point2f> vertices; 143 144 int ret = rotatedRectangleIntersection(rect1, rect2, vertices); 145 146 CV_Assert(ret == INTERSECT_PARTIAL); 147 CV_Assert(vertices.size() == 4); 148 149 vector<Point2f> possibleVertices(4); 150 151 possibleVertices[0] = Point2f(0.0f, 0.0f); 152 possibleVertices[1] = Point2f(1.0f, 1.0f); 153 possibleVertices[2] = Point2f(0.0f, 1.0f); 154 possibleVertices[3] = Point2f(1.0f, 0.0f); 155 156 for( size_t i = 0; i < vertices.size(); i++ ) 157 { 158 double bestR = DBL_MAX; 159 160 for( size_t j = 0; j < possibleVertices.size(); j++ ) 161 { 162 double dx = vertices[i].x - possibleVertices[j].x; 163 double dy = vertices[i].y - possibleVertices[j].y; 164 double r = sqrt(dx*dx + dy*dy); 165 166 bestR = std::min(bestR, r); 167 } 168 169 CV_Assert(bestR < ACCURACY); 170 } 171 } 172 173 void CV_RotatedRectangleIntersectionTest::test3() 174 { 175 // partial intersection, rectangles rotated 45 degree on the corner, forms a triangle intersection 176 RotatedRect rect1, rect2; 177 178 rect1.center.x = 0; 179 rect1.center.y = 0; 180 rect1.size.width = 2; 181 rect1.size.height = 2; 182 rect1.angle = 0; 183 184 rect2.center.x = 1; 185 rect2.center.y = 1; 186 rect2.size.width = sqrt(2.0f); 187 rect2.size.height = 20; 188 rect2.angle = 45.0f; 189 190 vector<Point2f> vertices; 191 192 int ret = rotatedRectangleIntersection(rect1, rect2, vertices); 193 194 CV_Assert(ret == INTERSECT_PARTIAL); 195 CV_Assert(vertices.size() == 3); 196 197 vector<Point2f> possibleVertices(3); 198 199 possibleVertices[0] = Point2f(1.0f, 1.0f); 200 possibleVertices[1] = Point2f(0.0f, 1.0f); 201 possibleVertices[2] = Point2f(1.0f, 0.0f); 202 203 for( size_t i = 0; i < vertices.size(); i++ ) 204 { 205 double bestR = DBL_MAX; 206 207 for( size_t j = 0; j < possibleVertices.size(); j++ ) 208 { 209 double dx = vertices[i].x - possibleVertices[j].x; 210 double dy = vertices[i].y - possibleVertices[j].y; 211 double r = sqrt(dx*dx + dy*dy); 212 213 bestR = std::min(bestR, r); 214 } 215 216 CV_Assert(bestR < ACCURACY); 217 } 218 } 219 220 void CV_RotatedRectangleIntersectionTest::test4() 221 { 222 // full intersection, rectangles of same size directly on top of each other 223 224 RotatedRect rect1, rect2; 225 226 rect1.center.x = 0; 227 rect1.center.y = 0; 228 rect1.size.width = 2; 229 rect1.size.height = 2; 230 rect1.angle = 0; 231 232 rect2.center.x = 0; 233 rect2.center.y = 0; 234 rect2.size.width = 2; 235 rect2.size.height = 2; 236 rect2.angle = 0; 237 238 vector<Point2f> vertices; 239 240 int ret = rotatedRectangleIntersection(rect1, rect2, vertices); 241 242 CV_Assert(ret == INTERSECT_FULL); 243 CV_Assert(vertices.size() == 4); 244 245 vector<Point2f> possibleVertices(4); 246 247 possibleVertices[0] = Point2f(-1.0f, 1.0f); 248 possibleVertices[1] = Point2f(1.0f, -1.0f); 249 possibleVertices[2] = Point2f(-1.0f, -1.0f); 250 possibleVertices[3] = Point2f(1.0f, 1.0f); 251 252 for( size_t i = 0; i < vertices.size(); i++ ) 253 { 254 double bestR = DBL_MAX; 255 256 for( size_t j = 0; j < possibleVertices.size(); j++ ) 257 { 258 double dx = vertices[i].x - possibleVertices[j].x; 259 double dy = vertices[i].y - possibleVertices[j].y; 260 double r = sqrt(dx*dx + dy*dy); 261 262 bestR = std::min(bestR, r); 263 } 264 265 CV_Assert(bestR < ACCURACY); 266 } 267 } 268 269 void CV_RotatedRectangleIntersectionTest::test5() 270 { 271 // partial intersection, rectangle on top rotated 45 degrees 272 273 RotatedRect rect1, rect2; 274 275 rect1.center.x = 0; 276 rect1.center.y = 0; 277 rect1.size.width = 2; 278 rect1.size.height = 2; 279 rect1.angle = 0; 280 281 rect2.center.x = 0; 282 rect2.center.y = 0; 283 rect2.size.width = 2; 284 rect2.size.height = 2; 285 rect2.angle = 45.0f; 286 287 vector<Point2f> vertices; 288 289 int ret = rotatedRectangleIntersection(rect1, rect2, vertices); 290 291 CV_Assert(ret == INTERSECT_PARTIAL); 292 CV_Assert(vertices.size() == 8); 293 294 vector<Point2f> possibleVertices(8); 295 296 possibleVertices[0] = Point2f(-1.0f, -0.414214f); 297 possibleVertices[1] = Point2f(-1.0f, 0.414214f); 298 possibleVertices[2] = Point2f(-0.414214f, -1.0f); 299 possibleVertices[3] = Point2f(0.414214f, -1.0f); 300 possibleVertices[4] = Point2f(1.0f, -0.414214f); 301 possibleVertices[5] = Point2f(1.0f, 0.414214f); 302 possibleVertices[6] = Point2f(0.414214f, 1.0f); 303 possibleVertices[7] = Point2f(-0.414214f, 1.0f); 304 305 for( size_t i = 0; i < vertices.size(); i++ ) 306 { 307 double bestR = DBL_MAX; 308 309 for( size_t j = 0; j < possibleVertices.size(); j++ ) 310 { 311 double dx = vertices[i].x - possibleVertices[j].x; 312 double dy = vertices[i].y - possibleVertices[j].y; 313 double r = sqrt(dx*dx + dy*dy); 314 315 bestR = std::min(bestR, r); 316 } 317 318 CV_Assert(bestR < ACCURACY); 319 } 320 } 321 322 void CV_RotatedRectangleIntersectionTest::test6() 323 { 324 // 6 - partial intersection, rectangle on top of different size 325 326 RotatedRect rect1, rect2; 327 328 rect1.center.x = 0; 329 rect1.center.y = 0; 330 rect1.size.width = 2; 331 rect1.size.height = 2; 332 rect1.angle = 0; 333 334 rect2.center.x = 0; 335 rect2.center.y = 0; 336 rect2.size.width = 2; 337 rect2.size.height = 10; 338 rect2.angle = 0; 339 340 vector<Point2f> vertices; 341 342 int ret = rotatedRectangleIntersection(rect1, rect2, vertices); 343 344 CV_Assert(ret == INTERSECT_PARTIAL); 345 CV_Assert(vertices.size() == 4); 346 347 vector<Point2f> possibleVertices(4); 348 349 possibleVertices[0] = Point2f(1.0f, 1.0f); 350 possibleVertices[1] = Point2f(1.0f, -1.0f); 351 possibleVertices[2] = Point2f(-1.0f, -1.0f); 352 possibleVertices[3] = Point2f(-1.0f, 1.0f); 353 354 for( size_t i = 0; i < vertices.size(); i++ ) 355 { 356 double bestR = DBL_MAX; 357 358 for( size_t j = 0; j < possibleVertices.size(); j++ ) 359 { 360 double dx = vertices[i].x - possibleVertices[j].x; 361 double dy = vertices[i].y - possibleVertices[j].y; 362 double r = sqrt(dx*dx + dy*dy); 363 364 bestR = std::min(bestR, r); 365 } 366 367 CV_Assert(bestR < ACCURACY); 368 } 369 } 370 371 void CV_RotatedRectangleIntersectionTest::test7() 372 { 373 // full intersection, rectangle fully enclosed in the other 374 375 RotatedRect rect1, rect2; 376 377 rect1.center.x = 0; 378 rect1.center.y = 0; 379 rect1.size.width = 12.34f; 380 rect1.size.height = 56.78f; 381 rect1.angle = 0; 382 383 rect2.center.x = 0; 384 rect2.center.y = 0; 385 rect2.size.width = 2; 386 rect2.size.height = 2; 387 rect2.angle = 0; 388 389 vector<Point2f> vertices; 390 391 int ret = rotatedRectangleIntersection(rect1, rect2, vertices); 392 393 CV_Assert(ret == INTERSECT_FULL); 394 CV_Assert(vertices.size() == 4); 395 396 vector<Point2f> possibleVertices(4); 397 398 possibleVertices[0] = Point2f(1.0f, 1.0f); 399 possibleVertices[1] = Point2f(1.0f, -1.0f); 400 possibleVertices[2] = Point2f(-1.0f, -1.0f); 401 possibleVertices[3] = Point2f(-1.0f, 1.0f); 402 403 for( size_t i = 0; i < vertices.size(); i++ ) 404 { 405 double bestR = DBL_MAX; 406 407 for( size_t j = 0; j < possibleVertices.size(); j++ ) 408 { 409 double dx = vertices[i].x - possibleVertices[j].x; 410 double dy = vertices[i].y - possibleVertices[j].y; 411 double r = sqrt(dx*dx + dy*dy); 412 413 bestR = std::min(bestR, r); 414 } 415 416 CV_Assert(bestR < ACCURACY); 417 } 418 } 419 420 void CV_RotatedRectangleIntersectionTest::test8() 421 { 422 // full intersection, rectangle fully enclosed in the other 423 424 RotatedRect rect1, rect2; 425 426 rect1.center.x = 0; 427 rect1.center.y = 0; 428 rect1.size.width = 2; 429 rect1.size.height = 2; 430 rect1.angle = 0; 431 432 rect2.center.x = 2; 433 rect2.center.y = 2; 434 rect2.size.width = 2; 435 rect2.size.height = 2; 436 rect2.angle = 0; 437 438 vector<Point2f> vertices; 439 440 int ret = rotatedRectangleIntersection(rect1, rect2, vertices); 441 442 CV_Assert(ret == INTERSECT_PARTIAL); 443 CV_Assert(vertices.size() == 1); 444 445 double dx = vertices[0].x - 1; 446 double dy = vertices[0].y - 1; 447 double r = sqrt(dx*dx + dy*dy); 448 449 CV_Assert(r < ACCURACY); 450 } 451 452 void CV_RotatedRectangleIntersectionTest::test9() 453 { 454 // full intersection, rectangle fully enclosed in the other 455 456 RotatedRect rect1, rect2; 457 458 rect1.center.x = 0; 459 rect1.center.y = 0; 460 rect1.size.width = 2; 461 rect1.size.height = 2; 462 rect1.angle = 0; 463 464 rect2.center.x = 2; 465 rect2.center.y = 0; 466 rect2.size.width = 2; 467 rect2.size.height = 123.45f; 468 rect2.angle = 0; 469 470 vector<Point2f> vertices; 471 472 int ret = rotatedRectangleIntersection(rect1, rect2, vertices); 473 474 CV_Assert(ret == INTERSECT_PARTIAL); 475 CV_Assert(vertices.size() == 2); 476 477 vector<Point2f> possibleVertices(2); 478 479 possibleVertices[0] = Point2f(1.0f, 1.0f); 480 possibleVertices[1] = Point2f(1.0f, -1.0f); 481 482 for( size_t i = 0; i < vertices.size(); i++ ) 483 { 484 double bestR = DBL_MAX; 485 486 for( size_t j = 0; j < possibleVertices.size(); j++ ) 487 { 488 double dx = vertices[i].x - possibleVertices[j].x; 489 double dy = vertices[i].y - possibleVertices[j].y; 490 double r = sqrt(dx*dx + dy*dy); 491 492 bestR = std::min(bestR, r); 493 } 494 495 CV_Assert(bestR < ACCURACY); 496 } 497 } 498 499 TEST (Imgproc_RotatedRectangleIntersection, accuracy) { CV_RotatedRectangleIntersectionTest test; test.safe_run(); } 500