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