/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Copyright 2010-2015 Danny Robson */ #ifndef __UTIL_REGION_HPP #define __UTIL_REGION_HPP #include "extent.hpp" #include "point.hpp" #include "vector.hpp" #include "types/traits.hpp" #include namespace util { /** * A two-dimensional rectangle, with size and position. */ template struct region { using extent_t = util::extent; using point_t = util::point; using value_type = T; //--------------------------------------------------------------------- static constexpr size_t dimension = S; static constexpr size_t elements = extent_t::elements + point_t::elements; point_t p; extent_t e; //--------------------------------------------------------------------- region () = default; explicit region (extent_t); region (point_t, extent_t); region (point_t, point_t); //--------------------------------------------------------------------- template constexpr region cast (void) const; //--------------------------------------------------------------------- T area (void) const; T diameter (void) const; extent_t magnitude (void) const; extent_t magnitude (extent_t); void scale (T factor); bool empty (void) const; //--------------------------------------------------------------------- point_t base (void) const; point_t away (void) const; point_t centre (void) const; point_t closest (point_t) const; //--------------------------------------------------------------------- // Point and region relation queries bool includes (point_t) const; // inclusive of borders bool contains (point_t) const; // exclusive of borders bool intersects (region) const; // exclusive of borders bool has (point_t) const noexcept; // inclusive of top and left borders // Move a point to be within the region bounds void constrain (point_t&) const; point_t constrained (point_t) const; // Compute binary region combinations region intersection (region) const; // Test if a region lies completely within our space bool encloses (region) const noexcept; //--------------------------------------------------------------------- // Compute a region `mag` units into the region region inset (T mag) const; region inset (vector mag) const; region expand (T mag) const; region expand (vector) const; // arithmetic operators region operator+ (vector) const; region operator- (vector) const; // Logical comparison operators bool operator ==(region rhs) const; bool operator !=(region rhs) const { return !(*this == rhs); } // Utility constants static constexpr region max (void); static constexpr region unit (void); void sanity (void) const; }; /////////////////////////////////////////////////////////////////////////// /// constructs the minimal region that encompasses a region and a point. template region make_union (region r, point p) { const auto p0 = select (r.p < p, r.p, p); const auto p1 = select (r.away () > p, r.away (), p); return { p0, p1 }; } template using region2 = region<2,T>; template using region3 = region<3,T>; using region2u = region2; using region2i = region2; using region2f = region2; using region2d = region2; template std::ostream& operator<< (std::ostream&, const util::region&); } #include "region.ipp" #endif