/* ======================================================================== The 2022 /r/place Atlas An Atlas of Reddit's 2022 /r/place, with information to each artwork of the canvas provided by the community. Copyright (c) 2017 Roland Rytz Copyright (c) 2022 r/placeAtlas2 contributors Licensed under the GNU Affero General Public License Version 3 https://place-atlas.stefanocoding.me/license.txt ======================================================================== */ let areasSum = 0; const areas = []; for (let q = 0; q < atlas.length; q++) { const path = atlas[q].path; let area = 0, i, j, point1, point2; for (i = 0, j = path.length - 1; i < path.length; j = i, i++) { point1 = path[i]; point2 = path[j]; area += point1[0] * point2[1]; area -= point1[1] * point2[0]; } area = Math.abs(area / 2); areasSum += area; areas.push(area); atlas[q].area = area; } areas.sort(function (a, b) { if (a < b) { return -1; } if (a > b) { return 1; } // a must be equal to b return 0; }); atlas.sort(function (a, b) { if (a.area < b.area) { return -1; } if (a.area > b.area) { return 1; } // a must be equal to b return 0; }); const el = document.createElement("canvas"); el.style.position = "absolute"; el.style.top = "0px"; el.style.zIndex = "10000"; const ctx = el.getContext("2d"); el.width = 1600; el.height = 500; const steps = 150; const max = 1500; let largerThanMax = 0; for (const i in areas) { if (areas[i] > max) { largerThanMax++; } } console.log("There are " + largerThanMax + " entries larger than " + max + ", accounting for " + (largerThanMax / areas.length * 100) + "% of all entries."); console.log("The largest entry has an area of " + areas[areas.length - 1] + " pixels."); const counts = [0]; const brackets = [max / steps]; let bracket = 0; let mostCounts = 0; for (const i in areas) { if (areas[i] > (bracket + 1) * (max / steps)) { mostCounts = Math.max(mostCounts, counts[bracket]); bracket++; if (bracket >= steps) { break; } counts[bracket] = 0; brackets[bracket] = (bracket + 1) * (max / steps); } counts[bracket]++; } //console.log(counts); //console.log(brackets); //console.log(mostCounts); ctx.fillStyle = "#FFFFFF"; ctx.fillRect(0, 0, el.width, el.height); ctx.strokeStyle = "#F5F5F5"; ctx.fillStyle = "#333333"; ctx.font = "15px sans"; ctx.textAlign = "right"; ctx.textBaseline = "middle"; let linesDistance = 1; for (let i = 0; i <= Math.ceil((mostCounts / linesDistance) / 5) * 5; i++) { ctx.beginPath(); ctx.moveTo( 50 , ~~(el.height - 50 - i * (linesDistance / mostCounts) * (el.height - 100)) + 0.5 ); ctx.lineTo( el.width - 25 , ~~(el.height - 50 - i * (linesDistance / mostCounts) * (el.height - 100)) + 0.5 ); ctx.stroke(); } ctx.strokeStyle = "#333333"; linesDistance = 5; for (let i = 0; i <= Math.ceil(mostCounts / linesDistance); i++) { ctx.beginPath(); ctx.moveTo( 50 , ~~(el.height - 50 - i * (linesDistance / mostCounts) * (el.height - 100)) + 0.5 ); ctx.lineTo( el.width - 25 , ~~(el.height - 50 - i * (linesDistance / mostCounts) * (el.height - 100)) + 0.5 ); ctx.stroke(); ctx.fillText( i * linesDistance , 40 , ~~(el.height - 50 - i * (linesDistance / mostCounts) * (el.height - 100)) + 0.5 ); } const skip = 2; ctx.textAlign = "center"; ctx.textBaseline = "hanging"; ctx.font = "10px sans"; let a = 0; for (let i = 0; i <= counts.length; i++) { if (i % skip == 0) { let y = 0; if (a % 2 == 0) { y = ~~(el.height - 30) + 0.5; } else { y = ~~(el.height - 45) + 0.5; } a++; ctx.beginPath(); ctx.moveTo( ~~(((i) / steps) * (el.width - 125) + 75) + 0.5 , ~~(el.height - 50) + 0.5 ); ctx.lineTo( ~~(((i) / steps) * (el.width - 125) + 75) + 0.5 , y ); ctx.stroke(); ctx.fillText( (i) * (max / steps) , ~~(((i) / steps) * (el.width - 125) + 75) - 0.5 , y + 5 ); } } ctx.fillStyle = "#FF0000"; ctx.strokeStyle = "#CC0000"; for (let i = 0; i < counts.length; i++) { if (i % 2 == 0) { ctx.fillStyle = "#FF0000"; } else { ctx.fillStyle = "#DD0000"; } ctx.fillRect( ~~((i / steps) * (el.width - 125) + 75) , el.height - 50 , Math.ceil(1 / steps * (el.width - 125)) , ~~(-(counts[i] / mostCounts) * (el.height - 100)) ); /*ctx.beginPath(); ctx.moveTo( ~~((i/steps)*(el.width-125)+75)+0.5 ,~~(el.height - 50) ); ctx.lineTo( ~~((i/steps)*(el.width-125)+75)+0.5 ,~~(el.height-(counts[i]/mostCounts)*(el.height-100))-50+0.5 ); ctx.lineTo( ~~(((i+1)/steps)*(el.width-125)+75)+0.5 ,~~(el.height-(counts[i]/mostCounts)*(el.height-100))-50+0.5 ); ctx.lineTo( ~~(((i+1)/steps)*(el.width-125)+75)+0.5 ,~~(el.height - 50) ); ctx.stroke();*/ } document.getElementById("wrapper").appendChild(el); //console.log(areas); console.log("Median area: " + areas[~~(areas.length / 2)]); console.log("Average area: " + (areasSum / atlas.length)); const topCount = 50; console.log("The " + topCount + " largest entries:"); let outstring = ""; for (let i = 0; i < topCount; i++) { outstring += ((i + 1) + "|[" + atlas[atlas.length - i - 1].name + "](http://place-atlas.stefanocoding.me/?id=" + atlas[atlas.length - i - 1].id + ")|" + ~~atlas[atlas.length - i - 1].area + "|" + Math.round(atlas[atlas.length - i - 1].area / 100) / 100 + "%\n"); } console.log(outstring); atlas.sort(function (a, b) { if (a.center[0] < b.center[0]) { return -1; } if (a.center[0] > b.center[0]) { return 1; } // a must be equal to b return 0; }); console.log("Median x: " + atlas[~~(atlas.length / 2)].center[0]); atlas.sort(function (a, b) { if (a.center[1] < b.center[1]) { return -1; } if (a.center[1] > b.center[1]) { return 1; } // a must be equal to b return 0; }); console.log("Median y: " + atlas[~~(atlas.length / 2)].center[1]);