Subversion Repositories DIN Is Noise

Rev

Rev 2009 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1370 jag 1
/*
2
* rect.cc
2097 jag 3
* DIN Is Noise is copyright (c) 2006-2024 Jagannathan Sampath
1713 jag 4
* DIN Is Noise is released under GNU Public License 2.0
1479 jag 5
* For more information, please visit https://dinisnoise.org/
1370 jag 6
*/
82 - 7
#include "mondrian.h"
84 - 8
#include "container.h"
9
#include "console.h"
10
#include "utils.h"
11
#include <utility>
12
using namespace std;
82 - 13
 
14
rect::rect () {
15
  parent = child1 = child2 = 0;
16
  total_slits = 0;
17
  for (int i = 0; i < 4; ++i) nslits[i] = 0;
18
  split = split::NONE;
19
  make_random_color ();
20
  ++ref;
21
}
22
 
23
void rect::erase (ball* b) {::erase (balls, b);}
24
 
452 jag 25
void rect::calc_intervals () {
82 - 26
  hint.first = extents.bottom;
27
  hint.second = extents.top;
28
  vint.first = extents.left;
29
  vint.second = extents.right;
30
}
31
 
32
void rect::get_vertical_interval (pair<float, float>& invl, rect* _root) {
33
  invl.first = 1.0f + (vint.first - _root->extents.left) * _root->extents.width_1;
34
  invl.second = 1.0f + (vint.second - _root->extents.left) * _root->extents.width_1;
35
}
36
 
37
void rect::get_horizontal_interval (pair<float, float>& invl, rect* _root) {
38
  invl.first = 1.0f + (hint.first - _root->extents.bottom) * _root->extents.height_1;
39
  invl.second = 1.0f + (hint.second - _root->extents.bottom) * _root->extents.height_1;
40
}
41
 
42
int rect::add_slit (slit* s, int e) {
43
  int result = 1;
44
  int& nse = nslits [e]; // number of slits on this edge
45
  // for all edges
46
  float lows [rect::nedges] = {extents.left, extents.bottom, extents.left, extents.bottom};
47
  float highs [rect::nedges] = {extents.right, extents.top, extents.right, extents.top};
48
  float low = lows[e];
49
  if (nse) { // slits already on this edge
50
    list<slit*>& ls = slits [e]; // slits of this edge
51
    for (slit_iterator i = ls.begin (), j = ls.end (); i != j; ++i) {
52
      slit* si = *i;
53
      if (s->mid < si->start) {
54
        s->start = max (s->start, low);
55
        s->end = min (s->end, si->start);
56
        i = ls.insert (i, s); // inserts sorted
127 jag 57
 
58
        slit_iterator ip (i); --ip; // slit b4 inserted slit
59
        slit_iterator in (i); ++in; // slit after inserted slit
60
 
61
        // handle animation of previous and next slits
62
        slit *ips = *ip, *ins = *in;
63
        if (ip != j && ips->fdr) ips->anim_end = min (ips->anim_end, s->start);
64
        if (in != j && ins->fdr) ins->anim_start = max (ins->anim_start, s->end);
65
 
66
        // handle edited slit 
82 - 67
        if (mondrian0.editing_slit) {
127 jag 68
          int hl = 0;
82 - 69
          slit* eds = mondrian0.slit_lip.slitt; // the edited slit
70
          if ((ip != j) && (*ip == eds)) { // edited slit is b4 inserted slit
71
            // slits editable high is inserted slits low
72
            mondrian0.slit_lip.set_high (s->start);
73
            hl = 1;
127 jag 74
          } else if ((in != j) && (*in == eds)) { // slit after inserted slit is edited slit
75
            // slit's editable low is inserted slits high
76
            mondrian0.slit_lip.set_low (s->end);
77
            hl = 1;
82 - 78
          }
79
          if (hl && mondrian0.slit_lip.slitt->is_too_small()) mondrian0.remove_slit (mondrian0.slit_lip.slitt);
80
        }
81
        goto adder;
82
      }
83
      low = si->end;
84
    }
85
 
86
    // append slit
87
    // if last slit is currently edited slit, adjusts its high
88
    //
89
    slit* sl = ls.back ();
90
    if (sl == mondrian0.slit_lip.slitt) mondrian0.slit_lip.set_high (s->start);
91
 
91 - 92
  } /*else cons << console::cyan << "No slits on edge, adding first slit" << eol;*/
82 - 93
 
94
  // append slit
95
  s->start = max (s->start, low);
96
  s->end = min (s->end, highs[e]);
97
  slits[e].push_back (s);
98
  adder:
127 jag 99
    s->anim_start = s->start;
100
    s->anim_end = s->end;
82 - 101
    ++nse;
102
    ++total_slits;
91 - 103
    /*cons << console::yellow << "Slit size = " << (s->end - s->start) << eol;
104
    cons << console::yellow << "Slits on edge = " << nse << eol;*/
82 - 105
    if (s->is_too_small()) result = 0; else s->calc_mid ();
106
  return result;
107
}
108
 
109
void rect::update_slits (int e, float minn, float maxx) {
110
  list<slit*>& ls = slits [e];
111
  for (slit_iterator i = ls.begin (), j = ls.end (); i != j;) {
112
    slit* si = *i;
113
    clamp (minn, si->start, maxx);
114
    clamp (minn, si->end, maxx);
115
    if (si->is_too_small()) {
116
      mondrian0.remove_slit (si);
117
      i = ls.begin ();
118
      j = ls.end ();
119
    } else {
120
      ++i;
121
      si->calc_mid ();
122
    }
123
  }
124
}