1 /*
2 * rect.h
3 * box in Mondrian
4 * DIN Is Noise is copyright (c) 2006-2021 Jagannathan Sampath
5 * For more information, please visit https://dinisnoise.org/
6 */
7 
8 #ifndef __rect__
9 #define __rect__
10 
11 #include "box.h"
12 #include "random.h"
13 #include <list>
14 #include <string>
15 
16 struct slit;
17 struct rect;
18 struct ball;
19 
20 // for rect splits
21 //
22 struct split {
23 
24   // orientation of split
25 	enum {NONE, HORIZONTAL, VERTICAL, BOTH}; // BOTH used by auto splitter
26 
27   // where to split rect
28   enum {NOTES, ANYWHERE};
29 
30 
31 };
32 
33 struct split_data;
34 struct split_listener {
35 	virtual void split_over (split_data& sd) = 0;
36 };
37 
38 struct split_data {
39 
40   rect* R;
41   std::list<rect*>* lr;
42 
43   int split_at;
44 
45 	int split_type;
46   split_listener* lis;
47 
48   int start, end;
49   int nsplits;
50 
51   // for NxN
52   float sz;
53   int n;
54 
55 	split_data (int s, int e, int sa, int st, rect* r, std::list<rect*>* l = 0, split_listener* ls = 0,
56                         float zs = 0, int _n = 0) {
57     split_at = sa;
58 		start = s;
59 		end = e;
60 		split_type = st;
61 		R = r;
62 		lr = l;
63 		lis = ls;
64     sz = zs;
65     n = _n;
66     nsplits = 0;
67 
68 	}
69 
70 };
71 typedef std::list<split_data>::iterator split_iterator;
72 
73 struct rect { // box in which balls bounce
74 
75   static int ref; // to log if we deleted all rects on exit
76 	std::string id; // used when saving
77 
78   rect* parent; // box in which this box is found
79 
80 	// each box can have two children
81 	// no child means its a leaf
82 	//
83   rect* child1; // child 1 of this box
84   rect* child2; // child 2 of this box
is_leafrect85 	inline int is_leaf () {return child1 == 0 && child2 == 0;}
86 
87   int split; // ? type is HORIZONTAL or VERTICAL
88 
89 	// slits occur on edges of the leaves
90 	static const int nedges = 4;
91 	int total_slits;
92 	std::list<slit*> slits [nedges]; // all slits of this box
93 	int nslits [nedges]; // slits per edge
94 	int add_slit (slit* s, int e); // add slit to edge
95 	void update_slits (int e, float minn, float maxx); // on edge edit
96 
97   // visual
98   box<float> extents;
99   float r, g, b; // color
set_colorrect100   void set_color (float _r, float _g, float _b) { r = _r; g = _g; b = _b;}
101 
102   static rnd<float> rd; // to make random box color
make_random_colorrect103   inline void make_random_color () {r = rd (); g = rd (); b = rd ();}
104 
105   std::list<ball*> balls; // balls bouncing in this box
106   void erase (ball* b); // erase ball found in this box
107 
108 	// pitch intervals spanned by this box
109   std::pair<float, float> hint; // along horizontal
110   std::pair<float, float> vint; // along vertical
111   void calc_intervals ();
112 	void get_horizontal_interval (std::pair<float, float>& invl, rect* _root);
113 	void get_vertical_interval (std::pair<float, float>& invl, rect* _root);
114 
get_arearect115   float get_area () {return extents.width * extents.height;}
116 
117 	rect ();
~rectrect118   ~rect () {--ref;}
119 
120   enum {EARLIEST, RANDOM, BIGGEST, LATEST, BALLED}; // see mondrian::pick_leaf ()
121 
122 
123 };
124 
125 struct box_from_disk_t { // for loading boxes from disk
126 	rect* R;
127 	std::string parent;
128 	std::string child1, child2;
box_from_disk_tbox_from_disk_t129 	box_from_disk_t () { R = 0; }
130 };
131 
132 struct finding { // used by mondrian::find
133   rect* found; // found box
134   rect* sibling; // its sibling
clearfinding135 	void clear () {found = sibling = 0;}
findingfinding136   finding () {clear ();}
137 };
138 
139 
140 typedef std::list<box_from_disk_t>::iterator box_from_disk_iterator;
141 typedef std::list<rect*>::iterator box_iterator;
142 
143 #endif
144