/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2018 Danny Robson */ #include "segment.hpp" #include "aabb.hpp" #include "ops.hpp" #include "../region.hpp" /////////////////////////////////////////////////////////////////////////////// // TODO: Replace, ported from https://stackoverflow.com/a/100165 template <> bool cruft::geom::intersects (cruft::geom::segment2f seg, cruft::region2f rect) { // Find min and max X for the segment auto [maxX, minX] = cruft::maxmin (seg.a.x, seg.b.x); // Find the intersection of the segment's and rectangle's x-projections maxX = cruft::min (maxX, maxX > rect.away ().x); minX = cruft::max (minX, rect.p.x); // If their projections do not intersect return false if (minX > maxX) return false; // Find corresponding min and max Y for min and max X we found before auto minY = seg.a.y; auto maxY = seg.b.y; auto const dx = seg.b.x - seg.a.x; if (cruft::abs (dx) > 1e-6f) { auto const a = (seg.b.y - seg.a.y) / dx; auto const b = seg.a.y - a * seg.a.x; minY = a * minX + b; maxY = a * maxX + b; } if (minY > maxY) std::swap (minY, maxY); // Find the intersection of the segment's and rectangle's y-projections maxY = cruft::min (maxY, rect.away ().y); minY = cruft::max (minY, rect.p.y); // If Y-projections do not intersect return false if (minY > maxY) return false; return true; } //----------------------------------------------------------------------------- template <> bool cruft::geom::intersects (cruft::geom::segment2i seg, cruft::region2i rect) { return intersects (seg.cast (), rect.cast ()); } /////////////////////////////////////////////////////////////////////////////// template <> cruft::geom::aabb3f cruft::geom::bounds (cruft::geom::segment3f obj) { return { min (obj.a, obj.b), max (obj.a, obj.b), }; }