MCPcopy Create free account
hub / github.com/OpenOrienteering/mapper / executeForLine

Method executeForLine

src/core/objects/boolean_tool.cpp:446–527  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

444}
445
446void BooleanTool::executeForLine(const PathObject* area, const PathObject* line, BooleanTool::PathObjects& out_objects) const
447{
448 if (op != BooleanTool::Intersection && op != BooleanTool::Difference)
449 {
450 Q_ASSERT_X(false, "BooleanTool::executeForLine", "Only intersection and difference are supported.");
451 return; // no-op in release build
452 }
453 if (line->parts().size() != 1)
454 {
455 Q_ASSERT_X(false, "BooleanTool::executeForLine", "Only single-part lines are supported.");
456 return; // no-op in release build
457 }
458
459 // Calculate all intersection points of line with the area path
460 PathObject::Intersections intersections;
461 line->calcAllIntersectionsWith(area, intersections);
462 intersections.normalize();
463
464 PathObject* first_segment = nullptr;
465 PathObject* last_segment = nullptr;
466
467 const auto& part = line->parts().front();
468 const auto& path_coords = part.path_coords;
469
470 // Only one segment?
471 if (intersections.empty())
472 {
473 auto middle_length = part.length();
474 auto middle = SplitPathCoord::at(path_coords, middle_length);
475 if (area->isPointInsideArea(middle.pos) == (op == BooleanTool::Intersection))
476 out_objects.push_back(line->duplicate());
477 return;
478 }
479
480 // First segment
481 auto middle_length = intersections[0].length / 2;
482 auto middle = SplitPathCoord::at(path_coords, middle_length);
483 if (area->isPointInsideArea(middle.pos) == (op == BooleanTool::Intersection))
484 {
485 PathObject* segment = line->duplicate();
486 segment->changePathBounds(0, 0.0, intersections[0].length);
487 first_segment = segment;
488 }
489
490 // Middle segments
491 for (std::size_t i = 0; i < intersections.size() - 1; ++i)
492 {
493 middle_length = (intersections[i].length + intersections[i+1].length) / 2;
494 auto middle = SplitPathCoord::at(path_coords, middle_length);
495 if (area->isPointInsideArea(middle.pos) == (op == BooleanTool::Intersection))
496 {
497 PathObject* segment = line->duplicate();
498 segment->changePathBounds(0, intersections[i].length, intersections[i+1].length);
499 out_objects.push_back(segment);
500 }
501 }
502
503 // Last segment

Callers 3

operator()Method · 0.80
finishCuttingAreaMethod · 0.80
processMethod · 0.80

Calls 11

isPointInsideAreaMethod · 0.80
changePathBoundsMethod · 0.80
backMethod · 0.80
connectPathPartsMethod · 0.80
sizeMethod · 0.45
normalizeMethod · 0.45
emptyMethod · 0.45
lengthMethod · 0.45
duplicateMethod · 0.45
isClosedMethod · 0.45

Tested by

no test coverage detected