1 #pragma once
2 #include <stdint.h>
3 #include <vector>
4 #include <algorithm>
5 #include <type_traits>
6 #include <math.h>
7 #include <array>
8 #include "lut.hpp"
9
10 namespace horizon {
11 enum class Orientation { LEFT, RIGHT, UP, DOWN };
12 /**
13 * Used in conjunction with a UUID/UUIDPath to identify an object.
14 */
15 enum class ObjectType {
16 INVALID,
17 JUNCTION,
18 LINE,
19 SYMBOL_PIN,
20 ARC,
21 SCHEMATIC_SYMBOL,
22 TEXT,
23 LINE_NET,
24 COMPONENT,
25 NET,
26 NET_LABEL,
27 POWER_SYMBOL,
28 BUS,
29 BUS_LABEL,
30 BUS_RIPPER,
31 POLYGON,
32 POLYGON_VERTEX,
33 POLYGON_EDGE,
34 POLYGON_ARC_CENTER,
35 HOLE,
36 PAD,
37 BOARD_PACKAGE,
38 TRACK,
39 VIA,
40 SHAPE,
41 BOARD,
42 SCHEMATIC,
43 UNIT,
44 ENTITY,
45 SYMBOL,
46 PACKAGE,
47 PADSTACK,
48 PART,
49 PLANE,
50 DIMENSION,
51 NET_CLASS,
52 BOARD_HOLE,
53 MODEL_3D,
54 FRAME,
55 KEEPOUT,
56 CONNECTION_LINE,
57 AIRWIRE,
58 BOARD_PANEL,
59 PICTURE,
60 DECAL,
61 BOARD_DECAL,
62 PROJECT,
63 };
64 enum class PatchType { OTHER, TRACK, PAD, PAD_TH, VIA, PLANE, HOLE_PTH, HOLE_NPTH, BOARD_EDGE, TEXT, N_TYPES };
65
66 extern const LutEnumStr<PatchType> patch_type_lut;
67 extern const LutEnumStr<ObjectType> object_type_lut;
68 extern const LutEnumStr<Orientation> orientation_lut;
69
70 /**
71 * Your typical coordinate class.
72 * Supports some mathematical operators as required.
73 * Unless otherwise noted, 1 equals 1 nm (that is nanometer, not nautical mile)
74 * Instead of instantiating the template on your own, you want to use Coordf
75 * (float) for calculations
76 * that will end up only on screen and Coordi (int64_t) for everything else.
77 */
78 template <typename T> class Coord {
79 public:
80 T x;
81 T y;
82
83 using type = T;
84
85 // WTF, but works
86 // template<typename U = T>
87 // Coord(double ix, double iy, typename std::enable_if<std::is_same<U,
88 // float>::value>::type* = 0) : x((float)ix), y((float)iy) { }
89
90
Coord(T ix,T iy)91 Coord(T ix, T iy) : x(ix), y(iy)
92 {
93 }
Coord()94 Coord() : x(0), y(0)
95 {
96 }
Coord(std::vector<T> v)97 Coord(std::vector<T> v) : x(v.at(0)), y(v.at(1))
98 {
99 }
operator Coord<float>() const100 operator Coord<float>() const
101 {
102 return Coord<float>(x, y);
103 }
operator Coord<double>() const104 operator Coord<double>() const
105 {
106 return Coord<double>(x, y);
107 }
operator +(const Coord<T> & a) const108 Coord<T> operator+(const Coord<T> &a) const
109 {
110 return Coord<T>(x + a.x, y + a.y);
111 }
operator -(const Coord<T> & a) const112 Coord<T> operator-(const Coord<T> &a) const
113 {
114 return Coord<T>(x - a.x, y - a.y);
115 }
operator *(const Coord<T> & a) const116 Coord<T> operator*(const Coord<T> &a) const
117 {
118 return Coord<T>(x * a.x, y * a.y);
119 }
operator *(T r) const120 Coord<T> operator*(T r) const
121 {
122 return Coord<T>(x * r, y * r);
123 }
operator /(T r) const124 Coord<T> operator/(T r) const
125 {
126 return Coord<T>(x / r, y / r);
127 }
operator ==(const Coord<T> & a) const128 bool operator==(const Coord<T> &a) const
129 {
130 return a.x == x && a.y == y;
131 }
operator !=(const Coord<T> & a) const132 bool operator!=(const Coord<T> &a) const
133 {
134 return !(a == *this);
135 }
operator <(const Coord<T> & a) const136 bool operator<(const Coord<T> &a) const
137 {
138 if (x < a.x)
139 return true;
140 if (x > a.x)
141 return false;
142 return y < a.y;
143 }
144
145 /**
146 * @returns element-wise minimum of \p a and \p b
147 */
min(const Coord<T> & a,const Coord<T> & b)148 static Coord<T> min(const Coord<T> &a, const Coord<T> &b)
149 {
150 return Coord<T>(std::min(a.x, b.x), std::min(a.y, b.y));
151 }
152
153 /**
154 * @returns element-wise maximum of \p a and \p b
155 */
max(const Coord<T> & a,const Coord<T> & b)156 static Coord<T> max(const Coord<T> &a, const Coord<T> &b)
157 {
158 return Coord<T>(std::max(a.x, b.x), std::max(a.y, b.y));
159 }
160
161 /**
162 * @param r magnitude
163 * @param phi angle in radians
164 * @returns coordinate specified by \p r and \p phi
165 */
euler(T r,T phi)166 static Coord<T> euler(T r, T phi)
167 {
168 static_assert(std::is_floating_point_v<T>);
169 return {r * cos(phi), r * sin(phi)};
170 }
171
rotate(T a) const172 Coord<T> rotate(T a) const
173 {
174 static_assert(std::is_floating_point_v<T>);
175 const T x2 = x * cos(a) - y * sin(a);
176 const T y2 = x * sin(a) + y * cos(a);
177 return {x2, y2};
178 }
179
to_coordi() const180 Coord<int64_t> to_coordi() const
181 {
182 static_assert(std::is_floating_point_v<T>);
183 return Coord<int64_t>(x, y);
184 }
185
186 /**
187 * @param a other coordinate
188 * @returns dot product of \p a and this
189 */
dot(const Coord<T> & a) const190 T dot(const Coord<T> &a) const
191 {
192 return x * a.x + y * a.y;
193 }
194
cross(const Coord<T> & other) const195 T cross(const Coord<T> &other) const
196 {
197 return (x * other.y) - (y * other.x);
198 }
199
200 /**
201 * @returns squared magnitude of this
202 */
mag_sq() const203 T mag_sq() const
204 {
205 return x * x + y * y;
206 }
207
mag() const208 T mag() const
209 {
210 static_assert(std::is_floating_point_v<T>);
211 return sqrt(mag_sq());
212 }
213
normalize() const214 Coord<T> normalize() const
215 {
216 static_assert(std::is_floating_point_v<T>);
217 return *this / mag();
218 }
219
magd() const220 double magd() const
221 {
222 static_assert(std::is_integral_v<T>);
223 return sqrt(mag_sq());
224 }
225
in_range(const Coord<T> & a,const Coord<T> & b) const226 bool in_range(const Coord<T> &a, const Coord<T> &b) const
227 {
228 return x > a.x && y > a.y && x < b.x && y < b.y;
229 }
230
operator +=(const Coord<T> a)231 void operator+=(const Coord<T> a)
232 {
233 x += a.x;
234 y += a.y;
235 }
operator -=(const Coord<T> a)236 void operator-=(const Coord<T> a)
237 {
238 x -= a.x;
239 y -= a.y;
240 }
operator *=(T a)241 void operator*=(T a)
242 {
243 x *= a;
244 y *= a;
245 }
246 /*json serialize() {
247 return {x,y};
248 }*/
as_array() const249 std::array<T, 2> as_array() const
250 {
251 return {x, y};
252 }
253 };
254
255
256 typedef Coord<float> Coordf;
257 typedef Coord<int64_t> Coordi;
258 typedef Coord<double> Coordd;
259
260 class Color {
261 public:
262 float r;
263 float g;
264 float b;
Color(double ir,double ig,double ib)265 Color(double ir, double ig, double ib) : r(ir), g(ig), b(ib)
266 {
267 }
268 // Color(unsigned int ir, unsigned ig, unsigned ib): r(ir/255.), g(ig/255.),
269 // b(ib/255.) {}
new_from_int(unsigned int ir,unsigned ig,unsigned ib)270 static Color new_from_int(unsigned int ir, unsigned ig, unsigned ib)
271 {
272 return Color(ir / 255.0, ig / 255.0, ib / 255.0);
273 }
Color()274 Color() : r(0), g(0), b(0)
275 {
276 }
277 };
278
279 struct ColorI {
280 uint8_t r;
281 uint8_t g;
282 uint8_t b;
283
operator <horizon::ColorI284 bool operator<(const ColorI &other) const
285 {
286 return hashify() < other.hashify();
287 }
288
to_colorhorizon::ColorI289 Color to_color() const
290 {
291 return Color::new_from_int(r, g, b);
292 }
293
294 private:
hashifyhorizon::ColorI295 uint32_t hashify() const
296 {
297 return r | (g << 8) | (b << 16);
298 }
299 };
300
operator ""_mm(long double i)301 constexpr int64_t operator"" _mm(long double i)
302 {
303 return i * 1e6;
304 }
operator ""_mm(unsigned long long int i)305 constexpr int64_t operator"" _mm(unsigned long long int i)
306 {
307 return i * 1000000;
308 }
309
310 struct shallow_copy_t {
311 explicit shallow_copy_t() = default;
312 };
313
314 constexpr shallow_copy_t shallow_copy = shallow_copy_t();
315
316 enum class CopyMode { DEEP, SHALLOW };
317
318 } // namespace horizon
319