Compare commits

...

4 Commits

Author SHA1 Message Date
Sebastián Santisi 80c716ec52 Google Analytics 2 years ago
Sebastián Santisi 2fcb682f26 Random solutions to 10-queens problem 2 years ago
Sebastián Santisi 933a8adb2b Copyright mark 2 years ago
Sebastián Santisi eb37810b4b Saco el reseteo de las posiciones al agregar generadores 2 years ago

@ -2,6 +2,15 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/strict.dtd">
<html xmlns="http://www.w3.org/TR/xhtml1/strict" >
<head>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-FHK9N3Z2N1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-FHK9N3Z2N1');
</script>
<title>Simulador de Aerogeneradores y Parques Eólicos (SAPE), CSC-CONICET</title>
<script type="importmap">
{

@ -22,10 +22,9 @@ class WindSimulation {
constructor(width, height, mills) {
this.width = width;
this.height = height;
this.mills = mills;
this.wms = [];
this.init_windmills();
this.init_windmills(mills);
this.wm = null;
this.simulation = null;
@ -63,19 +62,16 @@ class WindSimulation {
scene.add(this.flag);
}
init_windmills() {
init_windmills(mills) {
if(!WindMill.isReady()) {
setTimeout(() => { this.init_windmills() }, 100);
setTimeout(() => { this.init_windmills(mills) }, 100);
return;
}
for(var i = 0; i < this.mills; i++) {
var wm = new WindMill();
wm.position.set(4 + 0.5, i + 5 - Math.ceil(this.mills / 2) + 0.5, 0);
wm.rotation.z = this.targetRotation;
scene.add(wm);
this.wms.push(wm);
}
this.wm = this.wms[0];
for(var i = 0; i < mills; i++)
this.addWindMill();
this.wm = null;
}
move(pos, ended=false, count=2) {
@ -180,7 +176,7 @@ class WindSimulation {
this.simulation = null;
this.simulationPots = null;
this.simulationPot = null;
for(var i = 0; i < this.mills; i++)
for(var i = 0; i < this.wms.length; i++)
this.wms[i].lowPower(false);
document.getElementById("follower").style.display = "none";
document.getElementById("results").style.display = "none";
@ -202,28 +198,35 @@ class WindSimulation {
this.targetRotation = rotations[dir];
}
addWindMill() {
if(this.mills >= 10) return;
this.mills++;
this.reset();
positionValid(pos) {
for(let i = 0; i < this.wms.length; i++)
if(pos.clone().sub(this.wms[i].position).length() < 1)
return false;
return true;
}
removeWindMill() {
if(this.mills <= 1) return;
this.mills--;
this.reset();
addWindMill() {
if(this.wms.length >= 10) return;
for(let x = 0; x < 5; x++)
for(let y = 0; y < 10; y++) {
var pos = new THREE.Vector3(4.5 + Math.ceil(x / 2) * (x % 2 ? 1 : -1), 4.5 + Math.ceil(y / 2) * (y % 2 ? 1 : -1), 0);
if(this.positionValid(pos)) {
var wm = new WindMill();
wm.position.set(pos.x, pos.y, 0);
wm.rotation.z = this.targetRotation;
scene.add(wm);
this.wms.push(wm);
return;
}
}
}
reset() {
for(var i = 0; i < this.wms.length; i++)
scene.remove(this.wms[i]);
this.wms = [];
this.rotation = this.targetRotation;
removeWindMill() {
if(this.wms.length <= 1) return;
this.init_windmills();
if(this.wms[this.wms.length - 1] == this.wm) this.wm = null;
scene.remove(this.wms.pop());
}
simulate() {
@ -310,15 +313,15 @@ class WindSimulation {
var results = document.getElementById("results")
var innerHTML = '<h3>Resultados de la simulación</h3>' + (pasa ?
'<p style="max-width: 16em">🥳🥳🥳 ¡Tu simulación <b>está bien</b>! ¿Probaste otros vientos? Si sí agregá más aerogeneradores.</p>' :
'<p style="max-width: 16em">⚠️⚠️⚠️ ¡Tu simulación <b>no</b> funciona! Probá otras configuraciones.</p>') + '<table>';
'<p style="max-width: 16em">' + PARTY + PARTY + PARTY + ' ¡Tu simulación <b>está bien</b> con este viento! Clickeá "¡validar!" para evaluar en los demás.</p>' :
'<p style="max-width: 16em">' + EXCLAMATION + EXCLAMATION + EXCLAMATION + ' ¡Tu simulación <b>no</b> funciona! Probá otras configuraciones.</p>') + '<table>';
for(let i = 0; i < pot.length; i++) {
var perc = Math.round(pot[i] / 14.95 * 100);
innerHTML += '<tr><td><b>Nº' + (i + 1) + ':</b></td><td>' + Math.round(pot[i] * 100) / 100 + ' GWh</td><td>' + this.divPercentBar(perc, 50) + ' ' + perc + '% ' + (perc < 50 ? '⚠️' : '') + '</td></tr>'
innerHTML += '<tr><td><b>Nº' + (i + 1) + ':</b></td><td>' + Math.round(pot[i] * 100) / 100 + ' GWh</td><td>' + this.divPercentBar(perc, 50) + ' ' + perc + '% ' + (perc < 50 ? EXCLAMATION : '') + '</td></tr>'
}
var perc = Math.round(sum / 14.95 / pot.length * 100);
innerHTML += '<tr class="last"><td>TOTAL:</td><td>' + Math.round(sum * 100) / 100 + ' GWh</td><td>' + this.divPercentBar(perc, 80) + ' ' + perc + '% ' + (perc < 80 ? '⚠️' : '') + '</td></tr></table>';
innerHTML += '<tr class="last"><td>TOTAL:</td><td>' + Math.round(sum * 100) / 100 + ' GWh</td><td>' + this.divPercentBar(perc, 80) + ' ' + perc + '% ' + (perc < 80 ? EXCLAMATION : '') + '</td></tr></table>';
results.innerHTML = innerHTML;
results.style.display = "block";
@ -395,16 +398,6 @@ window.light = light;
//scene.add( helper);
//window.helper = helper;
window.windmill = WindMill;
window.ws = ws;
window.screen = screen;
window.scene = scene;

@ -1,3 +1,5 @@
/* Copyright (C) 2024 Sebastián Santisi <ssantisi@fi.uba.ar>, CSC-CONICET */
// Unused module, wind cone.
var geometry = new THREE.CylinderGeometry(0.09, 0.03, 0.5, 10, 5, true);
geometry = geometry.toNonIndexed();
var colors = new three.BufferAttribute(new Float32Array(geometry.attributes.position.array.length), 3);

@ -0,0 +1,97 @@
<script>
// Based on: https://stackoverflow.com/questions/75486408/n-queens-problem-using-backtracking-in-javascript
function nQueen(boolArrBoard,row){
if(row === boolArrBoard.length){
display(boolArrBoard)
return 1 //count*
}
let count = 0
//placing the queen and checking every row and column*
for(let col_ = 0; col_ < boolArrBoard.length; col_++){
let col = indexes[col_];
//place the queen if it is safe *
if(isSafe(boolArrBoard,row,col)){
boolArrBoard[row][col] = true
count += nQueen(boolArrBoard,row+1)
if(count) return 1;
boolArrBoard[row][col] = false
}
}
return count
}
function isSafe(boolArrBoard,row,col){
//vertical*
for(let i = 0; i < row; i++){
if(boolArrBoard[i][col]){
return false
}
}
//left diagonal*
let maxLeft = Math.min(row,col)
for(let i = 1; i <= maxLeft; i++){
if(boolArrBoard[row - i][col - i]){
return false
}
}
//right diagonal*
let maxRight = Math.min(row, boolArrBoard.length - col - 1)
for(let i = 1; i <= maxRight; i++){
if(boolArrBoard[row - i][col + i]){
return false
}
}
return true
}
function display(boolArrBoard){
let div = document.getElementById("solution");
div.innerHTML = "";
for( let row in boolArrBoard){
for(let column in boolArrBoard[row]){
if(boolArrBoard[row][column]){
div.append('O ')
}
else{
div.append('+ ')
}
}
div.append('\n')
}
}
function shuffle(array) {
let currentIndex = array.length;
// While there remain elements to shuffle...
while (currentIndex != 0) {
// Pick a remaining element...
let randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
}
var indexes;
function generate() {
let n = 10
let boolArrBoard = Array.from({length: n}, () => {
return new Array(n).fill(false)
})
indexes = Array(n).fill().map((x,i)=>i)
shuffle(indexes);
nQueen(boolArrBoard,0)
}
</script>
<pre id="solution"></pre>
<button onclick="generate()">¡Generar!</button>
<script>
generate();
</script>

@ -36,7 +36,7 @@ h3, h4 {
z-index: 1000;
max-width: 70vw;
max-height: 70vh;
overflow-x: hidden;
overflow-x: auto;
overflow-y: auto;
width: auto;
border: solid #fff .5vh;

Loading…
Cancel
Save