Skip to content

Instantly share code, notes, and snippets.

@reuk
Created September 22, 2013 17:52
Show Gist options
  • Save reuk/6662224 to your computer and use it in GitHub Desktop.
Save reuk/6662224 to your computer and use it in GitHub Desktop.
hypercube, implementation inspired by http://steve.hollasch.net/thesis/chapter4.html
class Vec4 {
float x, y, z, w;
Vec4(float a, float b, float c, float d) {
x = a;
y = b;
z = c;
w = d;
}
void mul(float a) {
x *= a;
y *= a;
z *= a;
w *= a;
}
void div(float a) {
x /= a;
y /= a;
z /= a;
w /= a;
}
float lengthSquared() {
return x * x + y * y + z * z + w * w;
}
float length() {
return sqrt(lengthSquared());
}
void normalize() {
div(length());
}
}
class Matrix4 {
Vec4 a, b, c, d;
Matrix4(Vec4 wa, Vec4 wb, Vec4 wc, Vec4 wd) {
a = wa;
b = wb;
c = wc;
d = wd;
}
}
float dot(Vec4 a, Vec4 b) {
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
}
Vec4 cross(Vec4 a, Vec4 b, Vec4 c) {
return new Vec4(
a.y * (b.z * c.w - c.z * b.w) - a.z * (b.y * c.w - c.y * b.w) + a.w * (b.y * c.z - c.y * b.z),
-a.x * (b.z * c.w - c.z * b.w) + a.z * (b.x * c.w - c.x * b.w) - a.w * (b.x * c.z - c.x * b.z),
a.x * (b.y * c.w - c.y * b.w) - a.y * (b.x * c.w - c.x * b.w) + a.w * (b.x * c.y - c.x * b.y),
-a.x * (b.y * c.z - c.y * b.z) + a.y * (b.x * c.z - c.x * b.z) - a.z * (b.x * c.y - c.x * b.y)
);
}
Vec4 sub(Vec4 a, Vec4 b) {
return new Vec4(
a.x - b.x,
a.y - b.y,
a.z - b.z,
a.w - b.w
);
}
PVector fourToThree(Vec4 pt, Vec4 from, float vAngle, Matrix4 mat) {
final float T = 1 / tan(vAngle / 2);
final Vec4 V = sub(pt, from);
final float S = T / dot(V, mat.d);
return new PVector(
S * dot(V, mat.a),
S * dot(V, mat.b),
S * dot(V, mat.c)
);
}
Matrix4 calcMatrix4(Vec4 from, Vec4 to, Vec4 up, Vec4 over) {
Vec4 wd = sub(to, from);
wd.normalize();
Vec4 wa = cross(up, over, wd);
wa.normalize();
Vec4 wb = cross(over, wd, wa);
wb.normalize();
final Vec4 WC = cross(wd, wa, wb);
return new Matrix4(wa, wb, WC, wd);
}
Vec4 FROM4 = new Vec4(4, 0, 0, 0);
Vec4 TO4 = new Vec4(0, 0, 0, 0);
Vec4 UP4 = new Vec4(0, 1, 0, 0);
Vec4 OVER4 = new Vec4(0, 0, 1, 0);
float THETA4 = PI / 4;
final PVector TO3 = new PVector(0, 0, 0);
final PVector UP3 = new PVector(0, 1, 0);
final float THETA3 = PI / 4;
Matrix4 MAT;
void vertex(PVector a) {vertex(a.x, a.y, a.z);}
void vertex(Vec4 a) {vertex(fourToThree(a, FROM4, THETA4, MAT));}
void setup() {
size(500, 500, P3D);
frameRate(25);
}
void draw() {
translate(width / 2, height / 2);
background(255);
noFill();
stroke(0);
strokeWeight(3);
noSmooth();
final int LOOPLENGTH = 40;
final float RATIO = ((frameCount % LOOPLENGTH) + 1) / float(LOOPLENGTH);
FROM4 = new Vec4(4 * sin(RATIO * PI / 2), 0, 4 * cos(RATIO * PI / 2), 0);
MAT = calcMatrix4(FROM4, TO4, UP4, OVER4);
rotateY(-RATIO * PI / 2);
rotateX(RATIO * PI / 2);
scale(150);
final float RADIUS = 1;
for (int j = 0; j != 4; ++j) {
final float C = ((j % 4) / 2) == 1 ? RADIUS : -RADIUS;
final float D = (((j + 1) % 4) / 2) == 1 ? RADIUS : -RADIUS;
beginShape();
for (int i = 0; i != 4; ++i) {
final float A = ((i % 4) / 2) == 1 ? RADIUS : -RADIUS;
final float B = (((i + 1) % 4) / 2) == 1 ? RADIUS : -RADIUS;
vertex(new Vec4(A, B, C, D));
}
endShape(CLOSE);
beginShape();
for (int i = 0; i != 4; ++i) {
final float A = ((i % 4) / 2) == 1 ? RADIUS : -RADIUS;
final float B = (((i + 1) % 4) / 2) == 1 ? RADIUS : -RADIUS;
vertex(new Vec4(A, C, B, D));
}
endShape(CLOSE);
beginShape();
for (int i = 0; i != 4; ++i) {
final float A = ((i % 4) / 2) == 1 ? RADIUS : -RADIUS;
final float B = (((i + 1) % 4) / 2) == 1 ? RADIUS : -RADIUS;
vertex(new Vec4(A, C, D, B));
}
endShape(CLOSE);
}
// saveFrame("###-hyper.png");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment