apologies for the delay - breakfast!
couldn't get your example working due to lack of libraries. rattled up a shorter one, hope it's clear.
that PVector class is a bit of a mess, or the documentation for it is. it always ends up looking like functional programming! it's not obvious what gets created, what gets modified etc.
Code:
// acd 20091222
// for Cedric
PVector[] p = new PVector[8]; // cube
PVector[] pi = new PVector[4]; // inner square
PVector[] n = new PVector[4]; // normals
float xangle, yangle, zangle;
float xdelta, ydelta, zdelta;
void setup() {
size(640, 640, P3D);
println("Setup");
// big cube
p[0] = new PVector(1, 1, 1);
p[1] = new PVector(1, 1, -1);
p[2] = new PVector(1, -1, -1);
p[3] = new PVector(1, -1, 1);
p[4] = new PVector(-1, 1, 1);
p[5] = new PVector(-1, 1, -1);
p[6] = new PVector(-1, -1, -1);
p[7] = new PVector(-1, -1, 1);
// inner square
pi[0] = new PVector(1, .5, .5);
pi[1] = new PVector(1, .5, -.5);
pi[2] = new PVector(1, -.5, -.5);
pi[3] = new PVector(1, -.5, .5);
xangle = random(TWO_PI);
xdelta = random(-.02, .02);
yangle = random(TWO_PI);
ydelta = random(-.02, .02);
zangle = random(TWO_PI);
zdelta = random(-.02, .02);
println("Setup Done");
}
void draw() {
background(0);
camera(500, 500, 500, 0, 0, 0, 0, 1, 0);
rotateX(xangle);
xangle += xdelta;
rotateY(yangle);
yangle += ydelta;
rotateZ(zangle);
zangle += zdelta;
scale(100);
// big cube (white)
stroke(255);
line(p[0], p[1]);
line(p[1], p[2]);
line(p[2], p[3]);
line(p[3], p[0]);
line(p[4], p[5]);
line(p[5], p[6]);
line(p[6], p[7]);
line(p[7], p[4]);
line(p[0], p[4]);
line(p[1], p[5]);
line(p[2], p[6]);
line(p[3], p[7]);
// join outer to inner (blue)
stroke(0, 0, 255);
line(p[0], pi[0]);
line(p[1], pi[1]);
line(p[2], pi[2]);
line(p[3], pi[3]);
// inner square (green)
stroke(0, 255, 0);
line(pi[0], pi[1]);
line(pi[1], pi[2]);
line(pi[2], pi[3]);
line(pi[3], pi[0]);
// normals off inner square (red)
stroke(255, 0, 0);
// vectors joining adjacent points
PVector pi01 = PVector.sub(pi[1], pi[0]);
PVector pi12 = PVector.sub(pi[2], pi[1]);
PVector pi23 = PVector.sub(pi[3], pi[2]);
PVector pi30 = PVector.sub(pi[0], pi[3]);
// find normals and add to points
n[0] = PVector.add(pi01.cross(pi30), pi[0]);
n[1] = PVector.add(pi12.cross(pi01), pi[1]);
n[2] = PVector.add(pi23.cross(pi12), pi[2]);
n[3] = PVector.add(pi30.cross(pi23), pi[3]);
// draw them
line(pi[0], n[0]);
line(pi[1], n[1]);
line(pi[2], n[2]);
line(pi[3], n[3]);
}
// line routine which takes vectors (to save typing)
void line(PVector a, PVector b) {
line(a.x, a.y, a.z, b.x, b.y, b.z);
}
NB those red lines are calculated using ONLY the green lines, that's all you need.