Как нарисовать Додекаэдр d3.js?
Вот в чем вопрос. Здесь информация о построении. https://studbooks.net/2304995/matematika_himiya_fizika/postroenie_dodekaedra http://www.scienceu.com/geometry/facts/solids/coords/dodeca.html А как это сделать в d3.js?
Даны координаты:
OFF
20 12 0
0.469 0.469 0.469
0.290 0.000 0.759
-0.759 -0.290 0.000
0.759 0.290 0.000
-0.469 0.469 -0.469
0.000 -0.759 -0.290
-0.759 0.290 0.000
0.469 -0.469 0.469
-0.469 0.469 0.469
-0.469 -0.469 0.469
0.469 -0.469 -0.469
0.290 0.000 -0.759
-0.469 -0.469 -0.469
0.000 -0.759 0.290
0.000 0.759 -0.290
-0.290 0.000 0.759
0.759 -0.290 0.000
-0.290 0.000 -0.759
0.469 0.469 -0.469
0.000 0.759 0.290
5 9 13 7 1 15 153 51 204
5 6 4 14 19 8 153 51 204
5 12 5 13 9 2 153 51 204
5 6 2 12 17 4 153 51 204
5 16 10 11 18 3 153 51 204
5 19 8 15 1 0 153 51 204
5 16 7 1 0 3 153 51 204
5 5 12 17 11 10 153 51 204
5 18 14 4 17 11 153 51 204
5 16 10 5 13 7 153 51 204
5 2 6 8 15 9 153 51 204
5 19 0 3 18 14 153 51 204
Ответы (2 шт):
Автор решения: Stranger in the Q
→ Ссылка
обошлось без d3.js:
let k = 500, a1 = 0, a2 = 0, far = 300, p,
w = 500, h = 500, s = 80, lines = [];
for (var i = 0; i < 5; i++) {
part(i, -s, 0);
part(i, s, Math.PI);
}
function part(i, y, da) {
let a = Math.PI*2/5;
let A1 = da+i*a;
let A2 = da+a*(i+1);
let A3 = a/2+A1;
let r1 = s*0.9;
let r2 = s*1.4;
let y1 = y*1.1;
let y2 = y/4;
let cosA1 = Math.cos(A1);
let sinA1 = Math.sin(A1);
let p0 = {
x: cosA1*r1,
y: y1,
z: sinA1*r1
};
let p1 = {
x: cosA1*r2,
y: y2,
z: sinA1*r2
};
lines.push([p0, p1]);
lines.push([p1, {
x: Math.cos(A3)*r2,
y: -y2,
z: Math.sin(A3)*r2,
}]);
lines.push([p0, {
x: Math.cos(A2)*r1,
y: y1,
z: Math.sin(A2)*r1
}]);
}
svg.innerHTML = lines.map(d => `<path stroke="white"></path>`).join('');
let paths = svg.querySelectorAll('path');
render();
function project(p) {
let cosa1 = Math.cos(a1);
let sina1 = Math.sin(a1);
let cosa2 = Math.cos(a2);
let sina2 = Math.sin(a2);
let x = p.x*cosa1 + p.z*sina1;
let z = p.z*cosa1 - p.x*sina1;
let y = p.y*cosa2 + z*sina2;
let d = z*cosa2 - p.y*sina2 + far;
p.cx = (k/d)*x + w/2;
p.cy = (k/d)*y + h/2;
//p.d = far/d;
}
function render() {
lines.forEach((line, index) => {
line.forEach(project);
paths[index].setAttribute('d',
`M${line[0].cx} ${line[0].cy} L${line[1].cx} ${line[1].cy}`)
});
}
let evt = (t, f) => addEventListener(t, e => render(f(e)));
evt('wheel', e => k *= 1 - Math.sign(e.deltaY)*0.1);
evt('mouseup', e => p = null);
evt('mousedown', e => p = {x:e.x, y:e.y, a1, a2});
evt('mousemove', e => p && (a1=p.a1-(e.x-p.x)/100) + (a2=p.a2-(e.y-p.y)/100));
body {
background: black
}
<svg id="svg" stroke-width="2" width=500 height=500></svg>