2 // structs.cpp: Useful structs to describe objects
4 // Part of the Architektonas Project
5 // (C) 2022 Underground Software
6 // See the README and GPLv3 files for licensing and warranty information
8 // JLH = James Hammons <jlhamm@acm.org>
11 // --- ---------- ------------------------------------------------------------
12 // JLH 01/13/2022 Created this file
16 #include "mathconstants.h"
18 const char objName[OTCount][16] = {
19 "None", "Line", "Circle", "Ellipse", "Arc", "Dimension",
20 "Spline", "Text", "Container"
22 const char dimName[DTCount][32] = {
23 "Linear", "Vertical", "Horizontal", "Radial", "Diametric",
24 "Circumferential", "Angular", "Leader"
27 const char buShortName[BUCount][8] = {
28 "in", "ft", "yd", "mi", "mm", "cm", "m", "km"
31 const double buInInches[BUCount] = { 1.0, 12.0, 36.0, 1.0/25.4, 1.0/2.54, 1.0/0.0254, 1.0/0.0000254 };
36 Line::Line(): type(OTLine), id(Global::objectID++), selected(false), hovered(false), hitObject(false)
38 hitPoint[0] = hitPoint[1] = false;
41 Line::Line(Vector pt1, Vector pt2, float th/*= 1.0*/, uint32_t c/* = 0*/, int l/*= LSSolid*/): type(OTLine), id(Global::objectID++), layer(0), color(c), thickness(th), style(l), selected(false), hovered(false), hitObject(false)
45 hitPoint[0] = hitPoint[1] = false;
48 Vector Line::Vect(void)
50 return Vector(p[0], p[1]);
53 Vector Line::Unit(void)
55 return Vector(p[0], p[1]).Unit();
58 double Line::Length(void)
60 return Vector(p[0], p[1]).Magnitude();
66 Circle::Circle(): type(OTCircle), id(Global::objectID++)
70 Circle::Circle(Vector pt1, double r, float th/*= 1.0*/, uint32_t c/*= 0*/, int l/*= LSSolid*/): type(OTCircle), id(Global::objectID++), layer(0), color(c), thickness(th), style(l), selected(false), hovered(false), hitObject(false)
74 hitPoint[0] = hitPoint[1] = false;
80 Ellipse::Ellipse(): type(OTEllipse), id(Global::objectID++)
84 Ellipse::Ellipse(Vector pt1, Vector pt2, double r1, double r2, float th/*= 1.0*/, uint32_t c/*= 0*/, int l/*= LSSolid*/): type(OTEllipse), id(Global::objectID++), layer(0), color(c), thickness(th), style(l), selected(false), hovered(false), hitObject(false)
90 hitPoint[0] = hitPoint[1] = false;
96 Arc::Arc(): type(OTArc), id(Global::objectID++)
100 Arc::Arc(Vector ctr, double r, double a1, double a2, float th/*= 1.0*/, uint32_t c/*= 0*/, int l/*= LSSolid*/): type(OTArc), id(Global::objectID++), layer(0), color(c), thickness(th), style(l), selected(false), hovered(false), hitObject(false)
106 hitPoint[0] = hitPoint[1] = hitPoint[2] = false;
109 Arc::Arc(Vector ctr, double r, Point p1, Point p2, float th/*= 1.0*/, uint32_t c/*= 0*/, int l/*= LSSolid*/): type(OTArc), id(Global::objectID++), layer(0), color(c), thickness(th), style(l), selected(false), hovered(false), hitObject(false)
113 angle[0] = Vector::Angle(ctr, p1);
115 s = 10, e = 20, span = 10 (why not -350?)
116 s = 20, e = 10, span = -10 (why not 350?)
117 s = 10, e = 350, span = 340 (why not -20?)
118 s = 350, e = 10, span = -340 (why not 20?)
120 below is still not right, we need one more point to disambiguate this...
122 angle[1] = Vector::Angle(ctr, p2) - angle[0];
123 hitPoint[0] = hitPoint[1] = hitPoint[2] = false;
126 Rect Arc::Bounds(void)
128 // Swap start & end angles if the span is negative...
129 double start = (angle[1] > 0 ? angle[0] : angle[0] + angle[1]);
130 double end = (angle[1] > 0 ? angle[0] + angle[1] : angle[0]);
132 // If the end of the arc is before the beginning, add 360 degrees
137 // Find which quadrant the start angle is in (consider the beginning of
138 // the 90° angle to be in the quadrant, the end to be in the next
139 // quadrant). Then, divide the span into 90° segments. The integer
140 // portion is the definite axis crossings; the remainder needs more
141 // scrutiny. There will be an additional axis crossing if the the sum of
142 // the start angle and the remainder is > 90°.
143 int quadStart = (int)(start / QTR_TAU);
144 double qsRemain = start - ((double)quadStart * QTR_TAU);
145 int numAxes = (int)((fabs(angle[1]) + qsRemain) / QTR_TAU);
147 Rect bounds(sin(start), cos(start), sin(end), cos(end));
148 const double box[4] = { 1.0, -1.0, -1.0, 1.0 };
150 for(int i=0; i<numAxes; i++)
151 bounds[(quadStart + i) % 4] = box[(quadStart + i) % 4];
154 bounds.Translate(p[0]);
162 Dimension::Dimension(): type(OTDimension), id(Global::objectID++), selected(false), hovered(false), hitObject(false)
164 hitPoint[0] = hitPoint[1] = hitPoint[2] = hitPoint[3] = hitPoint[4] = false;
167 Dimension::Dimension(Vector pt1, Vector pt2, DimensionType dt/*= DTLinear*/, double offs/*= 0*/, float th/*= 1.0*/, uint32_t c/*= 0x0000FF*/, int l/*= LSSolid*/): type(OTDimension), id(Global::objectID++), layer(0), color(c), thickness(th), style(l), selected(false), hovered(false), hitObject(false), subtype(dt), offset(offs)
171 hitPoint[0] = hitPoint[1] = hitPoint[2] = hitPoint[3] = hitPoint[4] = false;
177 Text::Text(): type(OTText), id(Global::objectID++)
181 Text::Text(Vector pt1, const char * str, float th/*= 10.0*/, uint32_t c/*= 0*/): type(OTText), id(Global::objectID++), layer(0), color(c), thickness(th), style(LSSolid), selected(false), hovered(false), hitObject(false), measured(false), s(str)
187 //prolly don't need this, as this just a special case of a polyline...
190 Polygon(): type(OTPolygon), id(Global::objectID++) {}
196 Polyline::Polyline(float th/*= 1.0*/, uint32_t c/*= 0*/, int l/*= LSSolid*/): type(OTPolyline), id(Global::objectID++), layer(0), color(c), thickness(th), style(l), selected(false), hovered(false), hitObject(false)
200 Polyline::Polyline(std::vector<Point> pts, float th/*= 1.0*/, uint32_t c/*= 0*/, int l/*= LSSolid*/): type(OTPolyline), id(Global::objectID++), layer(0), color(c), thickness(th), style(l), selected(false), hovered(false), hitObject(false)
205 void Polyline::Add(Point p)
210 void Polyline::Add(std::vector<Point> pts)
212 points.insert(points.end(), pts.begin(), pts.end());
215 Rect Polyline::Bounds(void)
217 Rect bounds(points[0]);
219 for(long unsigned int i=0; i<(points.size()-1); i++)
222 Need to check for arc bounds as well here...
224 // bounds += points[i];
225 bounds += points[i + 1];
231 void Polyline::Translate(Point delta)
233 for(long unsigned int i=0; i<points.size(); i++)
240 Spline::Spline(): type(OTSpline), id(Global::objectID++)
247 Container::Container(bool tl/*= false*/): type(OTContainer), id(Global::objectID++), selected(false), hovered(false), hitObject(false), topLevel(tl), clicked(NULL), baseUnit(0), unitStyle(0), decimalPrecision(3), fractionalPrecision(4)
251 void Container::Add(void * obj)
253 objects.push_back(obj);
256 void Container::Add(VPVector objs)
258 objects.insert(objects.end(), objs.begin(), objs.end());
261 // void DeleteContents(void) {}
262 /* void DeleteContents(Container * c)
264 std::vector<void *>::iterator i;
266 for(i=c->objects.begin(); i!=c->objects.end(); i++)
268 Object * obj = (Object *)(*i);
270 if (obj->type == OTContainer)
271 DeleteContainer((Container *)obj);