Published
Edited
Oct 22, 2020
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
// const width=1587/2, height=1123/2
const width=900, height=500
const viewBoxWidth=500, viewBoxHeight=500
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr('viewBox', `${-viewBoxWidth/2} ${-viewBoxHeight/2} ${viewBoxWidth} ${viewBoxHeight}`)
.attr('style', 'background: #1E1225')
let rand = makeRandomGenerator(inputSeed);
// Every point is a trace.
let points = (new Array(lineCount)).fill(0).map(p => {
let x = (rand.random()-.5)*512
let y = (rand.random()-.5)*512
let z = (rand.random()-.5)*512
let source = new THREE.Vector3(x, y, z);
// trace of a point moving over time
let path = d3.path();
let d, norm, diff, target = source.clone();
let visible = false, visiblePrev;
for(let i = 0; i < stepsNumber; ) {
d = distance(target);
visiblePrev = visible

// we start tracing path only on the surface
if(Math.abs(d)<1e-10){
i++
// Как проверить, видна или нет.
// Идём от точки против оси z. Если прошли 1000 пикселей и ни на что не напоролись, значит видна.
let visibility = target.clone()
visibility.add(new THREE.Vector3(0,0,-9))
let visibilityD = d
for(let j = 0; j < 50; j++){
//if(visibility.z < -9999) break
visibility.add(new THREE.Vector3(0,0,-visibilityD))
visibilityD = distance(visibility)
console.log('visibility.z', visibility.z, 'visibilityD', visibilityD)
}
// Если за N реймарш-шагов мы не дошли до плоскости z = -9999 пикселей, точка не видна.
visible = visibility.z < -9999? true : false
// лайнту надо рисовать только если предыдущая точка была видна и эта тоже.
// мувту — во всех остаальных случаях.
// То есть, если хотя бы одна из точек (прошлая или текущая) не была видна
//

if(flags.includes('visibleSide')) {
console.log('step', i, ' visible ', visible, 'visiblePrev ', visiblePrev)
if(visible && visiblePrev) {
path.lineTo(target.x, target.y);
console.log('visible')
}
else {
path.moveTo(target.x, target.y);
console.log('not visible')
}
}
else {
if(path['_'].length == 0)
path.moveTo(target.x, target.y);
else
path.lineTo(target.x, target.y);
}

let slide = new THREE.Vector3(0,0,0)
slide.x = new noise('001').noise3D(target.x/noiseDetails, target.y/noiseDetails, target.z/noiseDetails)
slide.y = new noise('002').noise3D(target.x/noiseDetails, target.y/noiseDetails, target.z/noiseDetails)
slide.z = new noise('003').noise3D(target.x/noiseDetails, target.y/noiseDetails, target.z/noiseDetails)
slide.normalize().multiplyScalar(minSlide)
target.add(slide);
}

norm = normal(target).multiplyScalar(-1);
diff = norm.clone().multiplyScalar(d);
source = target.clone();
target.add(diff);
}
// the last point is to be traced yet
// path.lineTo(target.x, target.y);
console.log(path)
return path;
})
// drawing traces
if (flags.includes('l')) {
svg.selectAll('path')
.data( points )
.enter()
.append('path')
.attr('d', p => p.toString())
.attr('stroke', '#FCE000')
.attr('fill', 'none')
.attr('stroke-width', 1.4);
}

// drawing points
if (flags.includes('d')) {
svg.selectAll('circle')
.data( points )
.enter()
.append('circle')
.attr('cx', p => p['_x0'])
.attr('cy', p => p['_y0'])
.attr('r', p => 2)
.attr('fill', p => '#FCE000');
}

return svg.node()
}
Insert cell
Insert cell
distance = p => {
p = p.clone();
// rotation of the shape
p
.applyAxisAngle(new THREE.Vector3(0,1,0).normalize(), sceneRotationX)
.applyAxisAngle(new THREE.Vector3(0,0,1).normalize(), sceneRotationY)

// let distortion = new THREE.Vector3(0,0,0)
// // distortion.x = Math.sin(p.y/30)
// distortion.x = new noise('001').noise3D(p.x/200, p.y/200, p.z/200)
// distortion.y = new noise('002').noise3D(p.x/200, p.y/200, p.z/200)
// distortion.z = new noise('003').noise3D(p.x/200, p.y/200, p.z/200)
// distortion.multiplyScalar(30)
// p.add(distortion)
// torus
// let q = new THREE.Vector2(new THREE.Vector2(p.x, p.y).length()-120,p.z)
// return (q.length()-60)
// cage
p.x = Math.abs(p.x) - 120
p.y = Math.abs(p.y) - 120
p.z = Math.abs(p.z) - 120
let q = new THREE.Vector3(
Math.abs(p.x+1)-1,
Math.abs(p.y+1)-1,
Math.abs(p.z+1)-1)
let p1 = new THREE.Vector3(p.x,q.y,q.z).max(new THREE.Vector3(0,0,0)).length() +
Math.min(Math.max(p.x,q.y,q.z), 0)
let p2 = new THREE.Vector3(q.x,p.y,q.z).max(new THREE.Vector3(0,0,0)).length() +
Math.min(Math.max(q.x,p.y,q.z), 0)
let p3 = new THREE.Vector3(q.x,q.y,p.z).max(new THREE.Vector3(0,0,0)).length() +
Math.min(Math.max(q.x,q.y,p.z), 0)
return Math.min(p1,p2,p3)-40
// // sphere
// return p.length()-150

}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more