Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
generic-rect.h
Go to the documentation of this file.
1/*
5 * Authors:
6 * Michael Sloan <mgsloan@gmail.com>
7 * Krzysztof KosiƄski <tweenk.pl@gmail.com>
8 * Copyright 2007-2011 Authors
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it either under the terms of the GNU Lesser General Public
12 * License version 2.1 as published by the Free Software Foundation
13 * (the "LGPL") or, at your option, under the terms of the Mozilla
14 * Public License Version 1.1 (the "MPL"). If you do not alter this
15 * notice, a recipient may use your version of this file under either
16 * the MPL or the LGPL.
17 *
18 * You should have received a copy of the LGPL along with this library
19 * in the file COPYING-LGPL-2.1; if not, output to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * You should have received a copy of the MPL along with this library
22 * in the file COPYING-MPL-1.1
23 *
24 * The contents of this file are subject to the Mozilla Public License
25 * Version 1.1 (the "License"); you may not use this file except in
26 * compliance with the License. You may obtain a copy of the License at
27 * http://www.mozilla.org/MPL/
28 *
29 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
30 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
31 * the specific language governing rights and limitations.
32 *
33 * Authors of original rect class:
34 * Lauris Kaplinski <lauris@kaplinski.com>
35 * Nathan Hurst <njh@mail.csse.monash.edu.au>
36 * bulia byak <buliabyak@users.sf.net>
37 * MenTaLguY <mental@rydia.net>
38 */
39
40#ifndef LIB2GEOM_SEEN_GENERIC_RECT_H
41#define LIB2GEOM_SEEN_GENERIC_RECT_H
42
43#include <limits>
44#include <iostream>
45#include <optional>
46#include <2geom/coord.h>
47
48namespace Geom {
49
50template <typename C>
51class GenericOptRect;
52
57template <typename C>
59 : CoordTraits<C>::RectOps
60{
65protected:
67public:
70 using D1ConstReference = CInterval const &;
71
74
75 GenericRect() = default;
77 GenericRect(CInterval const &a, CInterval const &b) : f{a, b} {}
79 GenericRect(CPoint const &a, CPoint const &b) : f{{a[X], b[X]}, {a[Y], b[Y]}} {}
81 GenericRect(C x0, C y0, C x1, C y1) : f{{x0, x1}, {y0, y1}} {}
89 template <typename InputIterator>
90 static CRect from_range(InputIterator start, InputIterator end) {
91 assert(start != end);
92 CPoint p1 = *start;
93 auto result = CRect(p1, p1);
94 for (++start; start != end; ++start) {
95 result.expandTo(*start);
96 }
97 return result;
98 }
100 static CRect from_array(CPoint const *c, unsigned n) {
101 return GenericRect<C>::from_range(c, c + n);
102 }
104 static CRect from_xywh(C x, C y, C w, C h) {
105 return GenericRect<C>::from_xywh(CPoint(x, y), CPoint(w, h));
106 }
108 static CRect from_xywh(CPoint const &xy, CPoint const &wh) {
109 return CRect(xy, xy + wh);
110 }
112 static CRect infinite() {
113 auto min = std::numeric_limits<C>::min();
114 auto max = std::numeric_limits<C>::max();
115 return CRect(min, min, max, max);
116 }
118
121 CInterval &operator[](unsigned i) { return f[i]; }
122 CInterval const &operator[](unsigned i) const { return f[i]; }
123 CInterval &operator[](Dim2 d) { return f[d]; }
124 CInterval const &operator[](Dim2 d) const { return f[d]; }
125
128 CPoint min() const { return CPoint(f[X].min(), f[Y].min()); }
131 CPoint max() const { return CPoint(f[X].max(), f[Y].max()); }
137 CPoint corner(unsigned i) const {
138 switch (i % 4) {
139 case 0: return CPoint(f[X].min(), f[Y].min());
140 case 1: return CPoint(f[X].max(), f[Y].min());
141 case 2: return CPoint(f[X].max(), f[Y].max());
142 default: return CPoint(f[X].min(), f[Y].max());
143 }
144 }
145
147 C top() const { return f[Y].min(); }
149 C bottom() const { return f[Y].max(); }
151 C left() const { return f[X].min(); }
153 C right() const { return f[X].max(); }
154
156 C width() const { return f[X].extent(); }
158 C height() const { return f[Y].extent(); }
160 Coord aspectRatio() const { return static_cast<Coord>(width()) / height(); }
161
165 CPoint dimensions() const { return CPoint(f[X].extent(), f[Y].extent()); }
167 CPoint midpoint() const { return CPoint(f[X].middle(), f[Y].middle()); }
168
170 C area() const { return f[X].extent() * f[Y].extent(); }
172 bool hasZeroArea() const { return f[X].isSingular() || f[Y].isSingular(); }
173
175 C maxExtent() const { return std::max(f[X].extent(), f[Y].extent()); }
177 C minExtent() const { return std::min(f[X].extent(), f[Y].extent()); }
178
180 C distanceSq(CPoint const &p) const {
181 return (p - clamp(p)).lengthSq();
182 }
183
185 CPoint clamp(CPoint const &p) const {
186 return CPoint(f[X].clamp(p[X]), f[Y].clamp(p[Y]));
187 }
190 if (!contains(p)) {
191 return clamp(p);
192 }
193 CPoint result = p;
194 C cx = f[X].nearestEnd(p[X]);
195 C cy = f[Y].nearestEnd(p[Y]);
196 if (std::abs(cx - p[X]) <= std::abs(cy - p[Y])) {
197 result[X] = cx;
198 } else {
199 result[Y] = cy;
200 }
201 return result;
202 }
204
207
208 bool intersects(GenericRect<C> const &r) const {
209 return f[X].intersects(r[X]) && f[Y].intersects(r[Y]);
210 }
212 bool contains(GenericRect<C> const &r) const {
213 return f[X].contains(r[X]) && f[Y].contains(r[Y]);
214 }
215
218 inline bool intersects(OptCRect const &r) const;
221 inline bool contains(OptCRect const &r) const;
222
224 bool contains(CPoint const &p) const {
225 return f[X].contains(p[X]) && f[Y].contains(p[Y]);
226 }
228
231
232 void setLeft(C val) {
233 f[X].setMin(val);
234 }
236 void setRight(C val) {
237 f[X].setMax(val);
238 }
240 void setTop(C val) {
241 f[Y].setMin(val);
242 }
244 void setBottom(C val) {
245 f[Y].setMax(val);
246 }
248 void setMin(CPoint const &p) {
249 f[X].setMin(p[X]);
250 f[Y].setMin(p[Y]);
251 }
253 void setMax(CPoint const &p) {
254 f[X].setMax(p[X]);
255 f[Y].setMax(p[Y]);
256 }
258 void expandTo(CPoint const &p) {
259 f[X].expandTo(p[X]);
260 f[Y].expandTo(p[Y]);
261 }
263 void unionWith(CRect const &b) {
264 f[X].unionWith(b[X]);
265 f[Y].unionWith(b[Y]);
266 }
269 void unionWith(OptCRect const &b);
270
276 void expandBy(C amount) {
277 expandBy(amount, amount);
278 }
279
284 void shrinkBy(C amount) { expandBy(-amount); }
285
291 void expandBy(C x, C y) {
292 f[X].expandBy(x);
293 f[Y].expandBy(y);
294 }
295
300 void shrinkBy(C x, C y) { expandBy(-x, -y); }
301
308 void expandBy(CPoint const &p) {
309 expandBy(p[X], p[Y]);
310 }
312
315
317 f[X] += p[X];
318 f[Y] += p[Y];
319 return *this;
320 }
323 f[X] -= p[X];
324 f[Y] -= p[Y];
325 return *this;
326 }
329 unionWith(o);
330 return *this;
331 }
333 unionWith(o);
334 return *this;
335 }
337 bool operator==(CRect const &o) const { return f[X] == o[X] && f[Y] == o[Y]; }
339};
340
345template <typename C>
347 : public std::optional<typename CoordTraits<C>::RectType>
348 , boost::equality_comparable< typename CoordTraits<C>::OptRectType
349 , boost::equality_comparable< typename CoordTraits<C>::OptRectType, typename CoordTraits<C>::RectType
350 , boost::orable< typename CoordTraits<C>::OptRectType
351 , boost::andable< typename CoordTraits<C>::OptRectType
352 , boost::andable< typename CoordTraits<C>::OptRectType, typename CoordTraits<C>::RectType
353 >>>>>
354{
360 using Base = std::optional<CRect>;
361public:
365
368 GenericOptRect() = default;
370 GenericOptRect(CPoint const &a, CPoint const &b) : Base(CRect(a, b)) {}
371 GenericOptRect(C x0, C y0, C x1, C y1) : Base(CRect(x0, y0, x1, y1)) {}
373 GenericOptRect(OptCInterval const &x_int, OptCInterval const &y_int) {
374 if (x_int && y_int) {
375 *this = CRect(*x_int, *y_int);
376 }
377 // else, stay empty.
378 }
379
388 template <typename InputIterator>
389 static OptCRect from_range(InputIterator start, InputIterator end) {
391 for (; start != end; ++start) {
392 result.expandTo(*start);
393 }
394 return result;
395 }
397
400
401 inline bool empty() const { return !*this; };
404 bool intersects(CRect const &r) const { return r.intersects(*this); }
407 bool contains(CRect const &r) const { return *this && (*this)->contains(r); }
408
412 bool intersects(OptCRect const &r) const { return *this && (*this)->intersects(r); }
416 bool contains(OptCRect const &r) const { return *this && (*this)->contains(r); }
417
420 bool contains(CPoint const &p) const { return *this && (*this)->contains(p); }
422
424 C area() const { return *this ? (*this)->area() : 0; }
426 bool hasZeroArea() const { return !*this || (*this)->hasZeroArea(); }
428 OptCRect regularized() const { return hasZeroArea() ? OptCRect() : *this; }
429
432
435 void unionWith(CRect const &b) {
436 if (*this) {
437 (*this)->unionWith(b);
438 } else {
439 *this = b;
440 }
441 }
446 void unionWith(OptCRect const &b) {
447 if (b) unionWith(*b);
448 }
452 void intersectWith(CRect const &b) {
453 if (!*this) return;
454 OptCInterval x = (**this)[X] & b[X], y = (**this)[Y] & b[Y];
455 if (x && y) {
456 *this = CRect(*x, *y);
457 } else {
458 *this = {};
459 }
460 }
464 void intersectWith(OptCRect const &b) {
465 if (b) {
466 intersectWith(*b);
467 } else {
468 *this = {};
469 }
470 }
474 void expandTo(CPoint const &p) {
475 if (*this) {
476 (*this)->expandTo(p);
477 } else {
478 *this = CRect(p, p);
479 }
480 }
482
485
487 unionWith(b);
488 return *this;
489 }
492 intersectWith(b);
493 return *this;
494 }
497 intersectWith(b);
498 return *this;
499 }
502 bool operator==(OptCRect const &other) const {
503 if (!*this != !other) return false;
504 return *this ? **this == *other : true;
505 }
506 bool operator==(CRect const &other) const {
507 if (!*this) return false;
508 return **this == other;
509 }
511};
512
513template <typename C>
514inline void GenericRect<C>::unionWith(OptCRect const &b) {
515 if (b) {
516 unionWith(*b);
517 }
518}
519template <typename C>
520inline bool GenericRect<C>::intersects(OptCRect const &r) const {
521 return r && intersects(*r);
522}
523template <typename C>
524inline bool GenericRect<C>::contains(OptCRect const &r) const {
525 return !r || contains(*r);
526}
527
528template <typename C>
529inline std::ostream &operator<<(std::ostream &out, GenericRect<C> const &r) {
530 return out << "Rect " << r[X] << " x " << r[Y];
531}
532
533template <typename C>
534inline std::ostream &operator<<(std::ostream &out, GenericOptRect<C> const &r) {
535 return r ? (out << *r) : (out << "Rect (empty)");
536}
537
538} // namespace Geom
539
540#endif // LIB2GEOM_SEEN_GENERIC_RECT_H
541
542/*
543 Local Variables:
544 mode:c++
545 c-file-style:"stroustrup"
546 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
547 indent-tabs-mode:nil
548 fill-column:99
549 End:
550*/
551// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Adaptor that creates 2D functions from 1D ones.
Definition d2.h:55
A range of numbers which is never empty.
A range of numbers that can be empty.
Axis-aligned generic rectangle that can be empty.
GenericOptRect< C > & operator|=(OptCRect const &b)
Union with b.
static OptCRect from_range(InputIterator start, InputIterator end)
Create a rectangle from a range of points.
void unionWith(OptCRect const &b)
Enlarge the rectangle to contain the argument.
GenericOptRect(GenericRect< C > const &a)
GenericOptRect(OptCInterval const &x_int, OptCInterval const &y_int)
Creates an empty OptRect when one of the argument intervals is empty.
bool contains(CRect const &r) const
Check whether the rectangle includes all points in the given rectangle.
GenericOptRect(C x0, C y0, C x1, C y1)
bool intersects(OptCRect const &r) const
Check whether the rectangles have any common points.
typename CoordTraits< C >::OptIntervalType OptCInterval
typename CoordTraits< C >::PointType CPoint
bool contains(OptCRect const &r) const
Check whether the rectangle includes all points in the given rectangle.
GenericOptRect()=default
OptCRect regularized() const
Returns an empty optional (testing false) if the rectangle has zero area.
typename CoordTraits< C >::OptRectType OptCRect
bool operator==(OptCRect const &other) const
Test for equality.
GenericOptRect(CPoint const &a, CPoint const &b)
bool contains(CPoint const &p) const
Check whether the given point is within the rectangle.
C area() const
Compute the rectangle's area.
GenericOptRect< C > & operator&=(OptCRect const &b)
Intersect with b.
void unionWith(CRect const &b)
Enlarge the rectangle to contain the argument.
CInterval & D1Reference
bool empty() const
Check for emptiness.
CInterval const & D1ConstReference
std::optional< CRect > Base
void intersectWith(OptCRect const &b)
Leave only the area overlapping with the argument.
typename CoordTraits< C >::RectType CRect
GenericOptRect< C > & operator&=(CRect const &b)
Intersect with b.
bool hasZeroArea() const
Check whether the rectangle has zero area.
bool intersects(CRect const &r) const
Check whether the rectangles have any common points.
bool operator==(CRect const &other) const
typename CoordTraits< C >::IntervalType CInterval
void expandTo(CPoint const &p)
Create or enlarge the rectangle to contain the given point.
void intersectWith(CRect const &b)
Leave only the area overlapping with the argument.
Axis aligned, non-empty, generic rectangle.
static CRect from_xywh(C x, C y, C w, C h)
Create rectangle from origin and dimensions.
C distanceSq(CPoint const &p) const
Get rectangle's distance SQUARED away from the given point.
C right() const
Return rightmost coordinate of the rectangle (+X is to the right).
GenericRect()=default
Create a rectangle that contains only the point at (0, 0).
typename CoordTraits< C >::RectType CRect
CPoint clamp(CPoint const &p) const
Clamp point to the rectangle.
C area() const
Compute the rectangle's area.
void setMin(CPoint const &p)
Set the upper left point of the rectangle.
bool contains(GenericRect< C > const &r) const
Check whether the rectangle includes all points in the given rectangle.
GenericRect< C > & operator|=(OptCRect const &o)
bool intersects(GenericRect< C > const &r) const
Check whether the rectangles have any common points.
GenericRect(C x0, C y0, C x1, C y1)
Create rectangle from coordinates of two points.
CInterval f[2]
static CRect from_range(InputIterator start, InputIterator end)
Create a rectangle from a range of points.
bool contains(OptCRect const &r) const
Check whether the rectangle includes all points in the given rectangle.
void unionWith(OptCRect const &b)
Enlarge the rectangle to contain the argument.
void setLeft(C val)
Set the minimum X coordinate of the rectangle.
CInterval & D1Reference
bool contains(CPoint const &p) const
Check whether the given point is within the rectangle.
C top() const
Return top coordinate of the rectangle (+Y is downwards).
static CRect from_xywh(CPoint const &xy, CPoint const &wh)
Create rectangle from origin and dimensions.
Coord aspectRatio() const
Get the ratio of width to height of the rectangle.
CInterval const & D1ConstReference
void shrinkBy(C amount)
Shrink the rectangle in both directions by the specified amount.
bool intersects(OptCRect const &r) const
Check whether the rectangles have any common points.
void setTop(C val)
Set the minimum Y coordinate of the rectangle.
void setMax(CPoint const &p)
Set the lower right point of the rectangle.
CPoint nearestEdgePoint(CPoint const &p) const
Get the nearest point on the edge of the rectangle.
void setRight(C val)
Set the maximum X coordinate of the rectangle.
CPoint midpoint() const
Get the point in the geometric center of the rectangle.
void setBottom(C val)
Set the maximum Y coordinate of the rectangle.
void expandBy(C amount)
Expand the rectangle in both directions by the specified amount.
C left() const
Return leftmost coordinate of the rectangle (+X is to the right).
typename CoordTraits< C >::IntervalType CInterval
GenericRect< C > & operator|=(CRect const &o)
Union two rectangles.
static CRect infinite()
Create infinite rectangle.
CInterval const & operator[](Dim2 d) const
void expandTo(CPoint const &p)
Enlarge the rectangle to contain the given point.
GenericRect(CInterval const &a, CInterval const &b)
Create a rectangle from X and Y intervals.
C height() const
Get the vertical extent of the rectangle.
C minExtent() const
Get the smaller extent (width or height) of the rectangle.
GenericRect< C > & operator+=(CPoint const &p)
Offset the rectangle by a vector.
void unionWith(CRect const &b)
Enlarge the rectangle to contain the argument.
C width() const
Get the horizontal extent of the rectangle.
void expandBy(C x, C y)
Expand the rectangle in both directions.
void expandBy(CPoint const &p)
Expand the rectangle by the coordinates of the given point.
CPoint min() const
Get the corner of the rectangle with smallest coordinate values.
C bottom() const
Return bottom coordinate of the rectangle (+Y is downwards).
typename CoordTraits< C >::OptRectType OptCRect
CInterval const & operator[](unsigned i) const
C maxExtent() const
Get the larger extent (width or height) of the rectangle.
CPoint dimensions() const
Get rectangle's width and height as a point.
CInterval & operator[](unsigned i)
GenericRect(CPoint const &a, CPoint const &b)
Create a rectangle from two points.
typename CoordTraits< C >::PointType CPoint
CPoint corner(unsigned i) const
Return the n-th corner of the rectangle.
GenericRect< C > & operator-=(CPoint const &p)
Offset the rectangle by the negation of a vector.
static CRect from_array(CPoint const *c, unsigned n)
Create a rectangle from a C-style array of points it should contain.
CPoint max() const
Get the corner of the rectangle with largest coordinate values.
bool operator==(CRect const &o) const
Test for equality of rectangles.
void shrinkBy(C x, C y)
Shrink the rectangle in both directions by possibly different amounts.
CInterval & operator[](Dim2 d)
bool hasZeroArea() const
Check whether the rectangle has zero area.
const double w
Definition conic-4.cpp:19
Integral and real coordinate types and some basic utilities.
Css & result
double c[8][4]
Dim2
2D axis enumeration (X or Y).
Definition coord.h:48
double Coord
Floating point type used to store coordinates.
Definition coord.h:76
@ Y
Definition coord.h:48
@ X
Definition coord.h:48
Geom::Point start
Geom::Point end
Various utility functions.
Definition affine.h:22
std::ostream & operator<<(std::ostream &os, const Bezier &b)
Definition bezier.h:372
MultiDegree< n > max(MultiDegree< n > const &p, MultiDegree< n > const &q)
Returns the maximal degree appearing in the two arguments for each variables.
Definition sbasisN.h:158
bool contains(Path const &p, Point const &i, bool evenodd=true)
@ intersects
Definition geom.cpp:16
Piecewise< SBasis > min(SBasis const &f, SBasis const &g)
Return the more negative of the two functions pointwise.
Traits class used with coordinate types.
Definition coord.h:105
double height
double width