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 | } |