Published
Edited
Oct 30, 2020
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
getPoint = (i, dist, center) => {
// // все делятся на:
// - обработанные (в выходном массиве)
// - стек (на грани, остортированы по длине)
// - соседние
let data = []
let stack = [{x:0, y:0, dist:0}]
if (half) stack[0].x = -donutRadius-1
let N = i + 1
// debugger
while(data.length<N && stack.length>0) {
// 1. выбираем первую точку А из стека
let current = stack.shift()
// console.log('cur',current)
// 2. выбираем всех его соседей и встраиваем в стек
let neighbours = getNeighbours(current)
// TODO избегаем повторов (выгорает трава). Например, расстояние не должно быть меньше текущей точки.
// console.log('neigh',neighbours)
neighbours = neighbours.filter(n => {
let match = false
data.forEach(d=>{
if(d.x==n.x&&d.y==n.y) {
match = true
}
})
stack.forEach(d=>{
if(d.x==n.x&&d.y==n.y) {
match = true
}
})
return !match
})
neighbours.forEach(n => {
pushNeighbour(stack, n)
})
// TODO ещё надо дистанс хранить в стеке
// console.log('stack_sort',stack)
// 3. добавляем А в массив
data.push(current)
// 4. Если длина
}
let lastPoint = data.pop()
lastPoint.x += lastPoint.y/2
lastPoint.y *= Math.sqrt(3)/2
lastPoint.x *= dist
lastPoint.y *= dist
lastPoint.x += center.x
lastPoint.y += center.y


return  lastPoint
}
Insert cell
pushNeighbour = (stack, n) => {
n.dist = distance(n)
let i = 0
for(; i < stack.length; i++){
if(n.dist<stack[i].dist) {
stack.splice(i, 0, n)
break
}
}
// if n.dist is the biggest, add it to the end
if(i==stack.length)
stack.push(n)
}
Insert cell
Insert cell
Insert cell
// sortStack = (stack) => {
// stack = stack.map(p => {
// return {x:p.x, y:p.y, dist:distance(p)}
// })
// return stack.sort((a,b)=>{
// return distance(a)-distance(b)
// })
// }
Insert cell
distance = (point) => {
let x = point.x, y = point.y
let distance
x+=y/2
y*=Math.sqrt(3)/2
// distance = (x*x+y*y)+Math.atan2(point.x,point.y)*.001
distance = sdHexagon({x:x, y:y})+Math.atan2(point.x,point.y)*.001
if(half){
// distance -= donutRadius**2
distance -= donutRadius
distance = Math.abs(distance)
if (y > .5) distance = Infinity
}
return distance
}
Insert cell
function *generator() {
let numbers = [1,2,3,4,5];
numbers.map(n => yield (n + 1));
}
Insert cell
sdHexagon = (point) => {
let x = point.x
let y = point.y
let r = 0 // radius
let k = {x:-0.866025404, y:0.5, z:0.577350269}
x = Math.abs(x)
y = Math.abs(y)
let dot = 2 * Math.min(k.x * x + k.y * y, 0)
x -= dot*k.x
y -= dot*k.y
let clampX = x
clampX < -k.z*r ? -k.z*r : clampX
clampX > k.z*r ? k.z*r : clampX
x -= clampX
y -= r
return Math.sqrt(x*x+y*y)*Math.sign(y)
}
// float sdHexagon( in vec2 p, in float r )
// {
// const vec3 k = vec3(-0.866025404,0.5,0.577350269);
// p = abs(p);
// p -= 2.0*min(dot(k.xy,p),0.0)*k.xy;
// p -= vec2(clamp(p.x, -k.z*r, k.z*r), r);
// return length(p)*sign(p.y);
// }
Insert cell
Insert cell
import {checkbox, slider} from "@jashkenas/inputs"
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
d3 = require('d3@5')
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