Le Glitch
Un glitch désigne une défaillance technique ou électronique temporaire
Log in to post a comment.
// --- Paramètres des Lignes ---
const nb_lignes = 150; // min=50, max=300, step=1 (Nombre de lignes)
const desordre = 1.5; // min=0, max=5, step=0.1 (Variation d'espacement)
// --- Paramètres de l'illusion (Décalage du Masque) ---
const decalage_x = -7; // min=-40, max=40, step=1
const decalage_y = 7; // min=-40, max=40, step=1
// --- Forme 1 (Principale) ---
const forme1 = 0; // min=0, max=1, step=1 (0 = Rectangle, 1 = Cercle)
const taille_x1 = 45; // min=5, max=90, step=1
const taille_y1 = 45; // min=5, max=90, step=1
const rotation1 = 45; // min=0, max=360, step=1
// --- Forme 2 (Optionnelle, permet de faire un trou dans la Forme 1) ---
const active2 = 0; // min=0, max=1, step=1 (0 = Désactivé, 1 = Activé)
const forme2 = 1; // min=0, max=1, step=1 (0 = Rectangle, 1 = Cercle)
const taille_x2 = 20; // min=5, max=90, step=1
const taille_y2 = 20; // min=5, max=90, step=1
const rotation2 = 0; // min=0, max=360, step=1
const offset_x2 = 0; // min=-50, max=50, step=1
const offset_y2 = 0; // min=-50, max=50, step=1
Canvas.setpenopacity(1);
const turtle = new Turtle();
// Génération des lignes de base avec leur espacement chaotique figé
function pseudoRandom(seed) {
return Math.abs(Math.sin(seed * 12.9898 + 78.233) * 43758.5453) % 1;
}
const lignes = [];
const espacement_moyen = 190 / nb_lignes;
for (let i = 0; i < nb_lignes; i++) {
let y_base = -95 + (i * espacement_moyen);
let y_final = y_base + (pseudoRandom(i) * desordre * espacement_moyen);
lignes.push(y_final);
}
// Mathématiques de rotation pour aligner les lignes avec la forme 1
const rad1 = rotation1 * Math.PI / 180;
const cos1 = Math.cos(rad1);
const sin1 = Math.sin(rad1);
function testShape(x, y, f_type, tx, ty, rot, ox, oy) {
let dx = x - ox;
let dy = y - oy;
const rad = -rot * Math.PI / 180;
const nx = dx * Math.cos(rad) - dy * Math.sin(rad);
const ny = dx * Math.sin(rad) + dy * Math.cos(rad);
if (f_type === 0) {
return Math.abs(nx) <= tx && Math.abs(ny) <= ty; // Rectangle
} else {
return (nx * nx) / (tx * tx) + (ny * ny) / (ty * ty) <= 1; // Ellipse
}
}
function isInsideBaseMask(x, y) {
let in1 = testShape(x, y, forme1, taille_x1, taille_y1, rotation1, 0, 0);
if (active2 === 1) {
let in2 = testShape(x, y, forme2, taille_x2, taille_y2, rotation2, offset_x2, offset_y2);
return in1 !== in2; // XOR : Exclut la forme 2 de la forme 1
}
return in1;
}
function isInsideShiftedMask(x, y) {
return isInsideBaseMask(x - decalage_x, y - decalage_y);
}
// Le test pour la Phase 2 : On simule l'espace local pour y chercher les limites du masque
function phase2MaskLocal(x_local, y_local) {
let wx = x_local * cos1 - y_local * sin1 + decalage_x;
let wy = x_local * sin1 + y_local * cos1 + decalage_y;
return isInsideShiftedMask(wx, wy);
}
function findBoundary(x1, x2, y, maskFunc) {
let left = x1;
let right = x2;
let state = maskFunc(left, y);
for (let i = 0; i < 12; i++) {
let mid = (left + right) / 2;
if (maskFunc(mid, y) === state) left = mid;
else right = mid;
}
return (left + right) / 2;
}
function getSegments(y, maskFunc, wantInside, minX, maxX) {
let crossings = [minX];
let wasInside = maskFunc(minX, y);
for (let x = minX + 1; x <= maxX; x += 1) {
let inside = maskFunc(x, y);
if (inside !== wasInside) {
crossings.push(findBoundary(x - 1, x, y, maskFunc));
wasInside = inside;
}
}
crossings.push(maxX);
let segments = [];
for (let i = 0; i < crossings.length - 1; i++) {
let mid = (crossings[i] + crossings[i+1]) / 2;
if (maskFunc(mid, y) === wantInside) {
segments.push([crossings[i], crossings[i+1]]);
}
}
return segments;
}
let index = 0;
let phase = 0;
function walk(i) {
// --- PHASE 1 : Fond horizontal, contourne le masque ---
if (phase === 0) {
if (index >= lignes.length) {
phase = 1;
index = 0;
return true;
}
let y = lignes[index];
let segments = getSegments(y, isInsideBaseMask, false, -105, 105);
for (let seg of segments) {
turtle.jump(seg[0], y);
turtle.goto(seg[1], y);
}
index++;
return true;
}
// --- PHASE 2 : Lignes internes pivotées avec la forme ---
else if (phase === 1) {
if (index >= lignes.length) {
return false;
}
let y_local = lignes[index];
// On cherche les limites dans l'espace "non pivoté" de la forme
let segments = getSegments(y_local, phase2MaskLocal, true, -150, 150);
for (let seg of segments) {
// On applique la matrice de rotation pour tracer de vraies lignes inclinées
let wx1 = seg[0] * cos1 - y_local * sin1 + decalage_x;
let wy1 = seg[0] * sin1 + y_local * cos1 + decalage_y;
let wx2 = seg[1] * cos1 - y_local * sin1 + decalage_x;
let wy2 = seg[1] * sin1 + y_local * cos1 + decalage_y;
turtle.jump(wx1, wy1);
turtle.goto(wx2, wy2);
}
index++;
return true;
}
}