Files
havox/tutorials/summed_area/script.js
2026-03-16 18:03:17 +00:00

278 lines
6.6 KiB
JavaScript

let myWidth = 800, myHeight = 800, offset = 5;
let r, n = 10;
let t = [];
let tl = null
let br = null;
let showCount = false;
let drawRectMode = 0;
let sOutput, wOutput, tlOutput, tOutput, lOutput;
function setup()
{
createCanvas(myWidth + 2*offset, myHeight + 2*offset);
r = myWidth / n;
for (y = 0; y < n; y ++)
{
for (x = 0; x < n; x ++)
{
t.push(new cTile(x*r + offset, y*r + offset, r));
}
}
sOutput = document.getElementById('subsetOutput');
wOutput = document.getElementById('wholeOutput');
tlOutput = document.getElementById('tlOutput');
tOutput = document.getElementById('tOutput');
lOutput = document.getElementById('lOutput');
}
function draw()
{
background(46, 52, 64);
t.forEach(e => e.show());
stroke(156,212,228);
noFill();
strokeWeight(5);
if (tl)
{
if (!br)
{
rect(tl.x, tl.y, tl.w);
} else {
rect(tl.x, tl.y, br.x - tl.x + r, br.y - tl.y + r);
drawRect(drawRectMode);
}
}
}
function defineCount(br)
{
let cols = Math.floor(br.x/ r) + 1;
let rows = Math.floor(br.y/ r) + 1;
let c = 0;
// let index = cols + n * rows;
for (y = 0; y < rows; y++) {
for (x = 0; x < cols; x++){
var i = x + n * y;
if (t[i].s){
c++;
}
}
}
return c;
}
function countSquares(tl, br)
{
let topLeft, left, top, whole;
let tlx, tly, brx, bry;
tlx = Math.floor(tl.x / r);
tly = Math.floor(tl.y / r);
brx = Math.floor(br.x / r);
bry = Math.floor(br.y / r);
topLeft = t[(tlx-1) + n * (tly-1)].count;
left = t[(tlx-1) + n * bry ].count;
top = t[brx + n * (tly-1)].count;
whole = t[brx + n * bry ].count;
var s = whole + topLeft - top - left;
if (s < 0)
s = 0;
return s;
}
function drawRect(n)
{
strokeWeight(5);
noFill();
switch(n)
{
case 1:
//whole
stroke(180,142,173);
fill('rgba(180, 142, 173, 0.05)');
rect(offset, offset, br.x - offset + br.w, br.y - offset + br.w);
break;
case 2:
//topleft
stroke(208,135,112);
fill('rgba(208,135,112, 0.05)');
rect(offset, offset, tl.x - offset, tl.y - offset);
break;
case 3:
//left
stroke(163,190,140);
fill('rgba(163,190,140, 0.05)');
rect(offset, offset, tl.x - offset, br.y - offset + br.w);
break;
case 4:
//top
stroke(235,203,139);
fill('rgba(235,203,139, 0.05)');
rect(offset, offset, br.x - offset + br.w, tl.y - offset);
break;
default:
break;
}
strokeWeight(1);
}
function showCountToggle(){
showCount = !showCount;
}
function toggleRectMode(){
if (tl && br)
{
var tlx = Math.floor(tl.x / r);
var tly = Math.floor(tl.y / r);
var brx = Math.floor(br.x / r);
var bry = Math.floor(br.y / r);
var topLeft = t[(tlx-1) + n * (tly-1)].count;
var left = t[(tlx-1) + n * bry ].count;
var top = t[brx + n * (tly-1)].count;
var whole = t[brx + n * bry ].count;
if (drawRectMode == 0){
wOutput.innerHTML = whole.toString(10);
wOutput.style.fontWeight = "bold";
drawRectMode ++;
} else if (drawRectMode == 1){
tlOutput.innerHTML = topLeft.toString(10);
tlOutput.style.fontWeight = "bold";
wOutput.style.fontWeight = "normal";
drawRectMode ++;
} else if (drawRectMode == 2){
lOutput.innerHTML = left.toString(10);
lOutput.style.fontWeight = "bold";
tlOutput.style.fontWeight = "normal";
drawRectMode ++;
} else if (drawRectMode == 3) {
tOutput.innerHTML = top.toString(10);
tOutput.style.fontWeight = "bold";
lOutput.style.fontWeight = "normal";
drawRectMode ++;
} else if (drawRectMode == 4) {
tOutput.style.fontWeight = "normal";
drawRectMode = 0;
}
}
}
function updateSum()
{
var tlx = Math.floor(tl.x / r);
var tly = Math.floor(tl.y / r);
var brx = Math.floor(br.x / r);
var bry = Math.floor(br.y / r);
var topLeft = t[(tlx-1) + n * (tly-1)].count;
var left = t[(tlx-1) + n * bry ].count;
var top = t[brx + n * (tly-1)].count;
var whole = t[brx + n * bry ].count;
wOutput.innerHTML = whole.toString(10);
tlOutput.innerHTML = topLeft.toString(10);
lOutput.innerHTML = left.toString(10);
tOutput.innerHTML = top.toString(10);
sOutput.innerHTML = countSquares(tl,br).toString(10);
}
function mouseClicked(event)
{
if (event.shiftKey)
{
if (mouseX > offset && mouseX < myWidth && mouseY > offset && mouseY < myHeight)
{
let col = Math.floor(mouseX / r);
let row = Math.floor(mouseY / r);
if (tl != null && br != null)
{
tl = null;
br = null;
}
if (!tl)
{
tl = t[col + n * row];
} else {
br = t[col + n * row];
}
if (tl != null && br != null)
{
updateSum();
}
}
} else {
if (mouseX > 0 && mouseX < myWidth && mouseY > 0 && mouseY < myHeight)
{
let col = Math.floor(mouseX / r);
let row = Math.floor(mouseY / r);
t[col + n * row].setState();
t.forEach(tile => tile.setCount(defineCount(tile)));
if (tl != null && br != null)
{
updateSum();
}
}
}
}
class cTile
{
constructor(_x, _y, _w)
{
this.x = _x;
this.y = _y;
this.s = false;
this.w = _w;
this.count = 0;
}
show()
{
if (this.s)
{
fill(191,97,106);
} else {
noFill();
}
stroke(236,239,244);
strokeWeight(1);
rect(this.x, this.y, this.w, this.w);
if (showCount)
{
textSize(18);
stroke(255);
fill(255);
text(this.count.toString(10), this.x + this.w/2 - 3, this.y + this.w/2 + 5);
}
}
setState()
{
this.s = !this.s;
}
setCount(c)
{
this.count = c;
}
};