4 * \brief Random box-related utilities.
6 * \author This file, box.h, was written and is
7 * Copyright (c) 2001 C. Scott Ananian.
11 * <h1><b>Copyright.</b></h1>\n
13 * PCB, interactive printed circuit board design
15 * Copyright (C) 1994,1995,1996 Thomas Nau
17 * Copyright (C) 1998,1999,2000,2001 harry eaton
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 * Contact addresses for paper mail and Email:
34 * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA
35 * haceaton@aplcomm.jhuapl.edu
48 { NORTH
= 0, EAST
= 1, SOUTH
= 2, WEST
= 3, NE
= 4, SE
= 5, SW
= 6, NW
=
49 7, ALL
= 8 } direction_t
;
52 * \brief Rotates box 90-degrees cw.
54 * That's a strange rotation!
56 #define ROTATEBOX_CW(box) { Coord t;\
57 t = (box).X1; (box).X1 = -(box).Y2; (box).Y2 = (box).X2;\
58 (box).X2 = -(box).Y1; (box).Y1 = t;\
60 #define ROTATEBOX_TO_NORTH(box, dir) do { Coord t;\
63 t = (box).X1; (box).X1 = (box).Y1; (box).Y1 = -(box).X2;\
64 (box).X2 = (box).Y2; (box).Y2 = -t; break;\
66 t = (box).X1; (box).X1 = -(box).X2; (box).X2 = -t;\
67 t = (box).Y1; (box).Y1 = -(box).Y2; (box).Y2 = -t; break;\
69 t = (box).X1; (box).X1 = -(box).Y2; (box).Y2 = (box).X2;\
70 (box).X2 = -(box).Y1; (box).Y1 = t; break;\
75 #define ROTATEBOX_FROM_NORTH(box, dir) do { Coord t;\
78 t = (box).X1; (box).X1 = (box).Y1; (box).Y1 = -(box).X2;\
79 (box).X2 = (box).Y2; (box).Y2 = -t; break;\
81 t = (box).X1; (box).X1 = -(box).X2; (box).X2 = -t;\
82 t = (box).Y1; (box).Y1 = -(box).Y2; (box).Y2 = -t; break;\
84 t = (box).X1; (box).X1 = -(box).Y2; (box).Y2 = (box).X2;\
85 (box).X2 = -(box).Y1; (box).Y1 = t; break;\
91 /* to avoid overflow, we calculate centers this way */
92 #define CENTER_X(b) ((b).X1 + ((b).X2 - (b).X1)/2)
93 #define CENTER_Y(b) ((b).Y1 + ((b).Y2 - (b).Y1)/2)
94 /* some useful box utilities. */
96 typedef struct cheap_point
102 /* note that boxes are closed on top and left and open on bottom and right. */
103 /* this means that top-left corner is in box, *but bottom-right corner is
106 point_in_box (const BoxType
* box
, Coord X
, Coord Y
)
108 return (X
>= box
->X1
) && (Y
>= box
->Y1
) && (X
< box
->X2
) && (Y
< box
->Y2
);
112 point_in_closed_box (const BoxType
* box
, Coord X
, Coord Y
)
114 return (X
>= box
->X1
) && (Y
>= box
->Y1
) && (X
<= box
->X2
) && (Y
<= box
->Y2
);
118 box_is_good (const BoxType
* b
)
120 return (b
->X1
< b
->X2
) && (b
->Y1
< b
->Y2
);
124 box_intersect (const BoxType
* a
, const BoxType
* b
)
127 (a
->X1
< b
->X2
) && (b
->X1
< a
->X2
) && (a
->Y1
< b
->Y2
) && (b
->Y1
< a
->Y2
);
130 static inline CheapPointType
131 closest_point_in_box (const CheapPointType
* from
, const BoxType
* box
)
134 assert (box
->X1
< box
->X2
&& box
->Y1
< box
->Y2
);
136 (from
->X
< box
->X1
) ? box
->X1
: (from
->X
>
137 box
->X2
- 1) ? box
->X2
- 1 : from
->X
;
139 (from
->Y
< box
->Y1
) ? box
->Y1
: (from
->Y
>
140 box
->Y2
- 1) ? box
->Y2
- 1 : from
->Y
;
141 assert (point_in_box (box
, r
.X
, r
.Y
));
146 box_in_box (const BoxType
* outer
, const BoxType
* inner
)
149 (outer
->X1
<= inner
->X1
) && (inner
->X2
<= outer
->X2
) &&
150 (outer
->Y1
<= inner
->Y1
) && (inner
->Y2
<= outer
->Y2
);
153 static inline BoxType
154 clip_box (const BoxType
* box
, const BoxType
* clipbox
)
157 assert (box_intersect (box
, clipbox
));
158 r
.X1
= MAX (box
->X1
, clipbox
->X1
);
159 r
.X2
= MIN (box
->X2
, clipbox
->X2
);
160 r
.Y1
= MAX (box
->Y1
, clipbox
->Y1
);
161 r
.Y2
= MIN (box
->Y2
, clipbox
->Y2
);
162 assert (box_in_box (clipbox
, &r
));
166 static inline BoxType
167 shrink_box (const BoxType
* box
, Coord amount
)
177 static inline BoxType
178 bloat_box (const BoxType
* box
, Coord amount
)
180 return shrink_box (box
, -amount
);
184 * \brief Construct a minimum box that touches the input box at the
187 static inline BoxType
188 box_center (const BoxType
* box
)
191 r
.X1
= box
->X1
+ (box
->X2
- box
->X1
)/2;
193 r
.Y1
= box
->Y1
+ (box
->Y2
- box
->Y1
)/2;
199 * \brief Construct a minimum box that touches the input box at the
202 static inline BoxType
203 box_corner (const BoxType
* box
)
214 * \brief Construct a box that holds a single point.
216 static inline BoxType
217 point_box (Coord X
, Coord Y
)
228 * \brief Close a bounding box by pushing its upper right corner.
231 close_box (BoxType
* r
)
238 * \brief Return the square of the minimum distance from a point to some
239 * point inside a box.
241 * The box is half-closed!\n
242 * That is, the top-left corner is considered in the box, but the
243 * bottom-right corner is not.
246 dist2_to_box (const CheapPointType
* p
, const BoxType
* b
)
248 CheapPointType r
= closest_point_in_box (p
, b
);
249 return Distance (r
.X
, r
.Y
, p
->X
, p
->Y
);
252 #endif /* __BOX_H_INCLUDED__ */