pcb 4.1.1
An interactive printed circuit board layout editor.
|
00001 00039 #ifndef PCB_BOX_H 00040 #define PCB_BOX_H 00041 00042 #include <assert.h> 00043 #include "global.h" 00044 00045 #include "misc.h" 00046 00047 typedef enum 00048 { NORTH = 0, EAST = 1, SOUTH = 2, WEST = 3, NE = 4, SE = 5, SW = 6, NW = 00049 7, ALL = 8 } direction_t; 00050 00056 #define ROTATEBOX_CW(box) { Coord t;\ 00057 t = (box).X1; (box).X1 = -(box).Y2; (box).Y2 = (box).X2;\ 00058 (box).X2 = -(box).Y1; (box).Y1 = t;\ 00059 } 00060 #define ROTATEBOX_TO_NORTH(box, dir) do { Coord t;\ 00061 switch(dir) {\ 00062 case EAST: \ 00063 t = (box).X1; (box).X1 = (box).Y1; (box).Y1 = -(box).X2;\ 00064 (box).X2 = (box).Y2; (box).Y2 = -t; break;\ 00065 case SOUTH: \ 00066 t = (box).X1; (box).X1 = -(box).X2; (box).X2 = -t;\ 00067 t = (box).Y1; (box).Y1 = -(box).Y2; (box).Y2 = -t; break;\ 00068 case WEST: \ 00069 t = (box).X1; (box).X1 = -(box).Y2; (box).Y2 = (box).X2;\ 00070 (box).X2 = -(box).Y1; (box).Y1 = t; break;\ 00071 case NORTH: break;\ 00072 default: assert(0);\ 00073 }\ 00074 } while (0) 00075 #define ROTATEBOX_FROM_NORTH(box, dir) do { Coord t;\ 00076 switch(dir) {\ 00077 case WEST: \ 00078 t = (box).X1; (box).X1 = (box).Y1; (box).Y1 = -(box).X2;\ 00079 (box).X2 = (box).Y2; (box).Y2 = -t; break;\ 00080 case SOUTH: \ 00081 t = (box).X1; (box).X1 = -(box).X2; (box).X2 = -t;\ 00082 t = (box).Y1; (box).Y1 = -(box).Y2; (box).Y2 = -t; break;\ 00083 case EAST: \ 00084 t = (box).X1; (box).X1 = -(box).Y2; (box).Y2 = (box).X2;\ 00085 (box).X2 = -(box).Y1; (box).Y1 = t; break;\ 00086 case NORTH: break;\ 00087 default: assert(0);\ 00088 }\ 00089 } while (0) 00090 00091 /* to avoid overflow, we calculate centers this way */ 00092 #define CENTER_X(b) ((b).X1 + ((b).X2 - (b).X1)/2) 00093 #define CENTER_Y(b) ((b).Y1 + ((b).Y2 - (b).Y1)/2) 00094 /* some useful box utilities. */ 00095 00096 typedef struct cheap_point 00097 { 00098 Coord X, Y; 00099 } CheapPointType; 00100 00101 00102 /* note that boxes are closed on top and left and open on bottom and right. */ 00103 /* this means that top-left corner is in box, *but bottom-right corner is 00104 * not*. */ 00105 static inline bool 00106 point_in_box (const BoxType * box, Coord X, Coord Y) 00107 { 00108 return (X >= box->X1) && (Y >= box->Y1) && (X < box->X2) && (Y < box->Y2); 00109 } 00110 00111 static inline bool 00112 point_in_closed_box (const BoxType * box, Coord X, Coord Y) 00113 { 00114 return (X >= box->X1) && (Y >= box->Y1) && (X <= box->X2) && (Y <= box->Y2); 00115 } 00116 00117 static inline bool 00118 box_is_good (const BoxType * b) 00119 { 00120 return (b->X1 < b->X2) && (b->Y1 < b->Y2); 00121 } 00122 00123 static inline bool 00124 box_intersect (const BoxType * a, const BoxType * b) 00125 { 00126 return 00127 (a->X1 < b->X2) && (b->X1 < a->X2) && (a->Y1 < b->Y2) && (b->Y1 < a->Y2); 00128 } 00129 00130 static inline CheapPointType 00131 closest_point_in_box (const CheapPointType * from, const BoxType * box) 00132 { 00133 CheapPointType r; 00134 assert (box->X1 < box->X2 && box->Y1 < box->Y2); 00135 r.X = 00136 (from->X < box->X1) ? box->X1 : (from->X > 00137 box->X2 - 1) ? box->X2 - 1 : from->X; 00138 r.Y = 00139 (from->Y < box->Y1) ? box->Y1 : (from->Y > 00140 box->Y2 - 1) ? box->Y2 - 1 : from->Y; 00141 assert (point_in_box (box, r.X, r.Y)); 00142 return r; 00143 } 00144 00145 static inline bool 00146 box_in_box (const BoxType * outer, const BoxType * inner) 00147 { 00148 return 00149 (outer->X1 <= inner->X1) && (inner->X2 <= outer->X2) && 00150 (outer->Y1 <= inner->Y1) && (inner->Y2 <= outer->Y2); 00151 } 00152 00153 static inline BoxType 00154 clip_box (const BoxType * box, const BoxType * clipbox) 00155 { 00156 BoxType r; 00157 assert (box_intersect (box, clipbox)); 00158 r.X1 = MAX (box->X1, clipbox->X1); 00159 r.X2 = MIN (box->X2, clipbox->X2); 00160 r.Y1 = MAX (box->Y1, clipbox->Y1); 00161 r.Y2 = MIN (box->Y2, clipbox->Y2); 00162 assert (box_in_box (clipbox, &r)); 00163 return r; 00164 } 00165 00166 static inline BoxType 00167 shrink_box (const BoxType * box, Coord amount) 00168 { 00169 BoxType r = *box; 00170 r.X1 += amount; 00171 r.Y1 += amount; 00172 r.X2 -= amount; 00173 r.Y2 -= amount; 00174 return r; 00175 } 00176 00177 static inline BoxType 00178 bloat_box (const BoxType * box, Coord amount) 00179 { 00180 return shrink_box (box, -amount); 00181 } 00182 00187 static inline BoxType 00188 box_center (const BoxType * box) 00189 { 00190 BoxType r; 00191 r.X1 = box->X1 + (box->X2 - box->X1)/2; 00192 r.X2 = r.X1 + 1; 00193 r.Y1 = box->Y1 + (box->Y2 - box->Y1)/2; 00194 r.Y2 = r.Y1 + 1; 00195 return r; 00196 } 00197 00202 static inline BoxType 00203 box_corner (const BoxType * box) 00204 { 00205 BoxType r; 00206 r.X1 = box->X1; 00207 r.X2 = r.X1 + 1; 00208 r.Y1 = box->Y1; 00209 r.Y2 = r.Y1 + 1; 00210 return r; 00211 } 00212 00216 static inline BoxType 00217 point_box (Coord X, Coord Y) 00218 { 00219 BoxType r; 00220 r.X1 = X; 00221 r.X2 = X + 1; 00222 r.Y1 = Y; 00223 r.Y2 = Y + 1; 00224 return r; 00225 } 00226 00230 static inline void 00231 close_box (BoxType * r) 00232 { 00233 r->X2++; 00234 r->Y2++; 00235 } 00236 00245 static inline double 00246 dist2_to_box (const CheapPointType * p, const BoxType * b) 00247 { 00248 CheapPointType r = closest_point_in_box (p, b); 00249 return Distance (r.X, r.Y, p->X, p->Y); 00250 } 00251 00252 #endif /* __BOX_H_INCLUDED__ */