Skip to content

Commit 7faaffb

Browse files
committed
Semi-transparent faces on tesseract: 24 quads with depth-sorted alpha
1 parent 4104ae3 commit 7faaffb

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

docs/assets/js/tesseract.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,30 @@
399399
if (diff === 1) E.push([i, j])
400400
}
401401

402+
// 24 square faces: fix 2 axes, vary the other 2
403+
var Faces = []
404+
for (var a1 = 0; a1 < 4; a1++)
405+
for (var a2 = a1 + 1; a2 < 4; a2++) {
406+
var fixed = []
407+
for (var k = 0; k < 4; k++)
408+
if (k !== a1 && k !== a2) fixed.push(k)
409+
for (var f0 = 0; f0 < 2; f0++)
410+
for (var f1 = 0; f1 < 2; f1++) {
411+
var fv0 = f0 ? 1 : -1, fv1 = f1 ? 1 : -1
412+
var quad = []
413+
for (var vi = 0; vi < 16; vi++)
414+
if (V[vi][fixed[0]] === fv0 && V[vi][fixed[1]] === fv1)
415+
quad.push(vi)
416+
// Sort by angle in (a1,a2) plane for proper winding
417+
;(function (ax1, ax2) {
418+
quad.sort(function (a, b) {
419+
return Math.atan2(V[a][ax2], V[a][ax1]) - Math.atan2(V[b][ax2], V[b][ax1])
420+
})
421+
})(a1, a2)
422+
Faces.push(quad)
423+
}
424+
}
425+
402426
// 4D rotation in a plane
403427
function rot4(v, p, q, a) {
404428
var co = Math.cos(a), si = Math.sin(a)
@@ -453,6 +477,30 @@
453477
return { x: cx + x3 * sc * s, y: cy + y3 * sc * s + floatY, z: z3 }
454478
})
455479

480+
// Faces sorted back to front, semi-transparent
481+
Faces.slice().sort(function (a, b) {
482+
var az = 0, bz = 0
483+
for (var i = 0; i < 4; i++) { az += pts[a[i]].z; bz += pts[b[i]].z }
484+
return az - bz
485+
}).forEach(function (f) {
486+
var avgZ = (pts[f[0]].z + pts[f[1]].z + pts[f[2]].z + pts[f[3]].z) / 4
487+
var alpha = 0.04 + (avgZ + 1) * 0.04
488+
alpha = Math.max(0.03, Math.min(0.14, alpha))
489+
var hue = ((avgZ + 1) * 0.2 + t * 0.02) % 1
490+
var r = Math.round(110 + hue * 80)
491+
var g = Math.round(60 + (1 - hue) * 50)
492+
var b = Math.round(200 + hue * 55)
493+
494+
ctx.beginPath()
495+
ctx.moveTo(pts[f[0]].x, pts[f[0]].y)
496+
ctx.lineTo(pts[f[1]].x, pts[f[1]].y)
497+
ctx.lineTo(pts[f[2]].x, pts[f[2]].y)
498+
ctx.lineTo(pts[f[3]].x, pts[f[3]].y)
499+
ctx.closePath()
500+
ctx.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + alpha + ')'
501+
ctx.fill()
502+
})
503+
456504
// Edges sorted back to front, smooth rounded caps, no vertex dots
457505
ctx.lineCap = 'round'
458506
ctx.lineJoin = 'round'

0 commit comments

Comments
 (0)