Rev 2097 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* rect.h
* box in Mondrian
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
* For more information, please visit https://dinisnoise.org/
*/
#ifndef __rect__
#define __rect__
#include "box.h"
#include "random.h"
#include <list>
#include <string>
struct slit;
struct rect;
struct ball;
// for rect splits
//
struct split {
// orientation of split
enum {NONE, HORIZONTAL, VERTICAL, BOTH}; // BOTH used by auto splitter
// where to split rect
enum {NOTES, ANYWHERE};
};
struct split_data;
struct split_listener {
virtual void split_over (split_data& sd) = 0;
};
struct split_data {
rect* R;
std::list<rect*>* lr;
int split_at;
int split_type;
split_listener* lis;
int start, end;
int nsplits;
// for NxN
float sz;
int n;
split_data (int s, int e, int sa, int st, rect* r, std::list<rect*>* l = 0, split_listener* ls = 0,
float zs = 0, int _n = 0) {
split_at = sa;
start = s;
end = e;
split_type = st;
R = r;
lr = l;
lis = ls;
sz = zs;
n = _n;
nsplits = 0;
}
};
typedef std::list<split_data>::iterator split_iterator;
struct rect { // box in which balls bounce
static int ref; // to log if we deleted all rects on exit
std::string id; // used when saving
rect* parent; // box in which this box is found
// each box can have two children
// no child means its a leaf
//
rect* child1; // child 1 of this box
rect* child2; // child 2 of this box
inline int is_leaf () {return child1 == 0 && child2 == 0;}
int split; // ? type is HORIZONTAL or VERTICAL
// slits occur on edges of the leaves
static const int nedges = 4;
int total_slits;
std::list<slit*> slits [nedges]; // all slits of this box
int nslits [nedges]; // slits per edge
int add_slit (slit* s, int e); // add slit to edge
void update_slits (int e, float minn, float maxx); // on edge edit
// visual
box<float> extents;
float r, g, b; // color
void set_color (float _r, float _g, float _b) { r = _r; g = _g; b = _b;}
static rnd<float> rd; // to make random box color
inline void make_random_color () {r = rd (); g = rd (); b = rd ();}
std::list<ball*> balls; // balls bouncing in this box
void erase (ball* b); // erase ball found in this box
// pitch intervals spanned by this box
std::pair<float, float> hint; // along horizontal
std::pair<float, float> vint; // along vertical
void calc_intervals ();
void get_horizontal_interval (std::pair<float, float>& invl, rect* _root);
void get_vertical_interval (std::pair<float, float>& invl, rect* _root);
float get_area () {return extents.width * extents.height;}
rect ();
~rect () {--ref;}
enum {EARLIEST, RANDOM, BIGGEST, LATEST, BALLED}; // see mondrian::pick_leaf ()
};
struct box_from_disk_t { // for loading boxes from disk
rect* R;
std::string parent;
std::string child1, child2;
box_from_disk_t () { R = 0; }
};
struct finding { // used by mondrian::find
rect* found; // found box
rect* sibling; // its sibling
void clear () {found = sibling = 0;}
finding () {clear ();}
};
typedef std::list<box_from_disk_t>::iterator box_from_disk_iterator;
typedef std::list<rect*>::iterator box_iterator;
#endif