| 4388 | //------------------------------------------------------------------------------ |
| 4389 | |
| 4390 | void CleanPolygon(const Path& in_poly, Path& out_poly, double distance) |
| 4391 | { |
| 4392 | //distance = proximity in units/pixels below which vertices |
| 4393 | //will be stripped. Default ~= sqrt(2). |
| 4394 | |
| 4395 | size_t size = in_poly.size(); |
| 4396 | |
| 4397 | if (size == 0) |
| 4398 | { |
| 4399 | out_poly.clear(); |
| 4400 | return; |
| 4401 | } |
| 4402 | |
| 4403 | OutPt* outPts = new OutPt[size]; |
| 4404 | for (size_t i = 0; i < size; ++i) |
| 4405 | { |
| 4406 | outPts[i].Pt = in_poly[i]; |
| 4407 | outPts[i].Next = &outPts[(i + 1) % size]; |
| 4408 | outPts[i].Next->Prev = &outPts[i]; |
| 4409 | outPts[i].Idx = 0; |
| 4410 | } |
| 4411 | |
| 4412 | double distSqrd = distance * distance; |
| 4413 | OutPt* op = &outPts[0]; |
| 4414 | while (op->Idx == 0 && op->Next != op->Prev) |
| 4415 | { |
| 4416 | if (PointsAreClose(op->Pt, op->Prev->Pt, distSqrd)) |
| 4417 | { |
| 4418 | op = ExcludeOp(op); |
| 4419 | size--; |
| 4420 | } |
| 4421 | else if (PointsAreClose(op->Prev->Pt, op->Next->Pt, distSqrd)) |
| 4422 | { |
| 4423 | ExcludeOp(op->Next); |
| 4424 | op = ExcludeOp(op); |
| 4425 | size -= 2; |
| 4426 | } |
| 4427 | else if (SlopesNearCollinear(op->Prev->Pt, op->Pt, op->Next->Pt, distSqrd)) |
| 4428 | { |
| 4429 | op = ExcludeOp(op); |
| 4430 | size--; |
| 4431 | } |
| 4432 | else |
| 4433 | { |
| 4434 | op->Idx = 1; |
| 4435 | op = op->Next; |
| 4436 | } |
| 4437 | } |
| 4438 | |
| 4439 | if (size < 3) size = 0; |
| 4440 | out_poly.resize(size); |
| 4441 | for (size_t i = 0; i < size; ++i) |
| 4442 | { |
| 4443 | out_poly[i] = op->Pt; |
| 4444 | op = op->Next; |
| 4445 | } |
| 4446 | delete [] outPts; |
| 4447 | } |
no test coverage detected