| 442 | //------------------------------------------------------------------------------ |
| 443 | |
| 444 | bool ClipperBase::AddPolygon( const Polygon &pg, PolyType polyType) |
| 445 | { |
| 446 | int len = pg.size(); |
| 447 | if (len < 3) return false; |
| 448 | Polygon p(len); |
| 449 | p[0] = pg[0]; |
| 450 | int j = 0; |
| 451 | const long64 MaxVal = 1500000000; //~ Sqrt(2^63)/2 |
| 452 | |
| 453 | for (int i = 1; i < len; ++i) |
| 454 | { |
| 455 | if (Abs(pg[i].X) > MaxVal|| Abs(pg[i].Y) > MaxVal) |
| 456 | throw clipperException("Integer exceeds range bounds"); |
| 457 | else if (PointsEqual(p[j], pg[i])) continue; |
| 458 | else if (j > 0 && SlopesEqual(p[j-1], p[j], pg[i])) |
| 459 | { |
| 460 | if (PointsEqual(p[j-1], pg[i])) j--; |
| 461 | } else j++; |
| 462 | p[j] = pg[i]; |
| 463 | } |
| 464 | if (j < 2) return false; |
| 465 | |
| 466 | len = j+1; |
| 467 | for (;;) |
| 468 | { |
| 469 | //nb: test for point equality before testing slopes ... |
| 470 | if (PointsEqual(p[j], p[0])) j--; |
| 471 | else if (PointsEqual(p[0], p[1]) || SlopesEqual(p[j], p[0], p[1])) |
| 472 | p[0] = p[j--]; |
| 473 | else if (SlopesEqual(p[j-1], p[j], p[0])) j--; |
| 474 | else if (SlopesEqual(p[0], p[1], p[2])) |
| 475 | { |
| 476 | for (int i = 2; i <= j; ++i) p[i-1] = p[i]; |
| 477 | j--; |
| 478 | } |
| 479 | //exit loop if nothing is changed or there are too few vertices ... |
| 480 | if (j == len-1 || j < 2) break; |
| 481 | len = j +1; |
| 482 | } |
| 483 | if (len < 3) return false; |
| 484 | |
| 485 | //create a new edge array ... |
| 486 | TEdge *edges = new TEdge [len]; |
| 487 | m_edges.push_back(edges); |
| 488 | |
| 489 | //convert vertices to a double-linked-list of edges and initialize ... |
| 490 | edges[0].xcurr = p[0].X; |
| 491 | edges[0].ycurr = p[0].Y; |
| 492 | InitEdge(&edges[len-1], &edges[0], &edges[len-2], p[len-1], polyType); |
| 493 | for (int i = len-2; i > 0; --i) |
| 494 | InitEdge(&edges[i], &edges[i+1], &edges[i-1], p[i], polyType); |
| 495 | InitEdge(&edges[0], &edges[1], &edges[len-1], p[0], polyType); |
| 496 | |
| 497 | //reset xcurr & ycurr and find 'eHighest' (given the Y axis coordinates |
| 498 | //increase downward so the 'highest' edge will have the smallest ytop) ... |
| 499 | TEdge *e = &edges[0]; |
| 500 | TEdge *eHighest = e; |
| 501 | do |
no test coverage detected