Non-Euclidean geometry #
Resulta que no todo vive en un mundo plano bidimensional y, por lo tanto, no todo está sujeto a las leyes de la geometría euclidiana plana. Por ejemplo: tú, yo y toda la humanidad vivimos en la superficie de la Tierra, y la Tierra no es plana. Es, de hecho, un objeto aproximadamente esférico. Lo que significa que las reglas de la geometría plana no rigen nuestras vidas.
Un globo desinflado es un objeto plano y, por lo tanto, vive dentro del ámbito de la geometría euclidiana. En este mundo, los triángulos bien dibujados tienen 180 grados. Pero tan pronto como inflas el globo, su superficie deja de ser plana, se vuelve esférica y eso lo lleva al ámbito de lo que se conoce como geometría no euclidiana.
El término no euclidiana suena muy elegante, pero en realidad solo significa cualquier tipo de geometría que no sea euclidiana, es decir, que no existe en un mundo plano. Una geometría no euclidiana es un replanteamiento y una redescripción de las propiedades de cosas como puntos, líneas y otras formas en un mundo no plano. La geometría esférica, que es una especie de geometría plana deformada sobre la superficie de una esfera, es un ejemplo de geometría no euclidiana.
non_euclidean.js
let easycam;
let edge = 80;
let fox;
let foxTex;
let train;
let trainTex;
let texShader;
function preload() {
// no varyings need to be emitted from the vertex shader
texShader = readShader('/VisualComputing2022_2/sketches/Taller3/NEG/non_euclidean.frag',
{ varyings: Tree.NONE });
fox = loadModel('/VisualComputing2022_2/sketches/Taller3/NEG/fox.obj', true);
train = loadModel('/VisualComputing2022_2/sketches/Taller3/NEG/train.obj', true);
dragon = loadModel('/VisualComputing2022_2/sketches/Taller3/NEG/dragon.obj', true);
apple = loadModel('/VisualComputing2022_2/sketches/Taller3/NEG/apple.obj', true);
skull = loadModel('/VisualComputing2022_2/sketches/Taller3/NEG/skull.obj', true);
tie = loadModel('/VisualComputing2022_2/sketches/Taller3/NEG/tie.obj', true);
}
function setup() {
createCanvas(1000, 1000, WEBGL);
// no need to normalize the texture
// textureMode(NORMAL);
shader(texShader);
// resolution will be used to sample the offscreen textures
emitResolution(texShader);
easycam = createEasyCam();
foxTex = createGraphics(width, height, WEBGL);
trainTex = createGraphics(width, height, WEBGL);
dragonTex = createGraphics(width, height, WEBGL);
appleTex = createGraphics(width, height, WEBGL);
skullTex = createGraphics(width, height, WEBGL);
tieTex = createGraphics(width, height, WEBGL);
}
function draw() {
// 1. compute current main canvas camera params
let position = treeLocation();
let center = p5.Vector.add(position, treeDisplacement());
let up = treeDisplacement(Tree.j);
// in case the current camera projection params are needed check:
// https://github.com/VisualComputing/p5.treegl#frustum-queries
// 2. offscreen rendering
// train graphics
trainTex.background(200);
trainTex.reset();
trainTex.camera(position.x, position.y, position.z,
center.x, center.y, center.z,
up.x, up.y, up.z);
trainTex.push();
trainTex.noStroke();
trainTex.fill('white');
// most models use positive y-coordinates
trainTex.scale(1, -1);
trainTex.scale(0.8);// only train
trainTex.model(train);
trainTex.pop();
// fox graphics
foxTex.background(200);
foxTex.reset();
foxTex.camera(position.x, position.y, position.z,
center.x, center.y, center.z,
up.x, up.y, up.z);
foxTex.push();
foxTex.noStroke();
foxTex.fill('orange');
foxTex.scale(1, -1);
foxTex.model(fox);
foxTex.pop();
dragonTex.background(200);
dragonTex.reset();
dragonTex.camera(position.x, position.y, position.z,
center.x, center.y, center.z,
up.x, up.y, up.z);
dragonTex.push();
dragonTex.noStroke();
dragonTex.fill('black');
dragonTex.scale(1, -1);
dragonTex.scale(0.8);// only dragon
dragonTex.model(dragon);
dragonTex.pop();
appleTex.background(200);
appleTex.reset();
appleTex.camera(position.x, position.y, position.z,
center.x, center.y, center.z,
up.x, up.y, up.z);
appleTex.push();
appleTex.noStroke();
appleTex.fill('red');
appleTex.scale(1, -1);
appleTex.scale(0.8);// only apple
appleTex.model(apple);
appleTex.pop();
skullTex.background(200);
skullTex.reset();
skullTex.camera(position.x, position.y, position.z,
center.x, center.y, center.z,
up.x, up.y, up.z);
skullTex.push();
skullTex.noStroke();
skullTex.fill('yellow');
skullTex.scale(1, -1);
skullTex.scale(0.8);// only skull
skullTex.model(skull);
skullTex.pop();
tieTex.background(200);
tieTex.reset();
tieTex.camera(position.x, position.y, position.z,
center.x, center.y, center.z,
up.x, up.y, up.z);
tieTex.push();
tieTex.noStroke();
tieTex.fill('green');
tieTex.scale(1, -1);
tieTex.scale(0.8);// only tie
tieTex.model(tie);
tieTex.pop();
// 3. main canvas
background(0);
push();
// front (+z)
stroke('blue');
strokeWeight(5);
texShader.setUniform('texture', trainTex);
beginShape();
vertex(-edge, -edge, +edge);
vertex(+edge, -edge, +edge);
vertex(+edge, +edge, +edge);
vertex(-edge, +edge, +edge);
endShape(CLOSE);
// right (+x)
texShader.setUniform('texture', foxTex);
beginShape();
vertex(+edge, -edge, +edge);
vertex(+edge, -edge, -edge);
vertex(+edge, +edge, -edge);
vertex(+edge, +edge, +edge);
endShape(CLOSE);
// back (-z)
texShader.setUniform('texture', dragonTex);
beginShape();
vertex(+edge, +edge, -edge);
vertex(-edge, +edge, -edge);
vertex(-edge, -edge, -edge);
vertex(+edge, -edge, -edge);
endShape(CLOSE);
// left (-x)
texShader.setUniform('texture', appleTex);
beginShape();
vertex(-edge, +edge, -edge);
vertex(-edge, +edge, +edge);
vertex(-edge, -edge, +edge);
vertex(-edge, -edge, -edge);
endShape(CLOSE);
// up (+y)
texShader.setUniform('texture', skullTex);
beginShape();
vertex(+edge, +edge, +edge);
vertex(+edge, +edge, -edge);
vertex(-edge, +edge, -edge);
vertex(-edge, +edge, +edge);
endShape(CLOSE);
// down (-y)
texShader.setUniform('texture', tieTex);
beginShape();
vertex(-edge, -edge, -edge);
vertex(-edge, -edge, +edge);
vertex(+edge, -edge, +edge);
vertex(+edge, -edge, -edge);
endShape(CLOSE);
pop();
}
non_euclidean.frag
precision mediump float;
// uniforms are defined and sent by the sketch
uniform sampler2D texture;
// see emitResolution: https://github.com/VisualComputing/p5.treegl#macros
uniform vec2 u_resolution;
void main() {
vec2 st = gl_FragCoord.xy / u_resolution;
gl_FragColor = texture2D(texture, vec2(st.s, 1.0 - st.t));
}