Subversion Repositories DIN Is Noise

Rev

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