function* setup() {
let this_width = 0.8 * width;
let height = 0.7 * d3.min([this_width, window.screen.height]);
let container = d3
.create('div')
.style('width', this_width.toString() + 'px')
.style('height', height.toString() + 'px');
let scene = container
.append('x3d')
.attr('width', this_width.toString() + 'px')
.attr('height', height.toString() + 'px')
.append('scene');
scene
.append('viewpoint')
.attr('position', '11.08014 -3.40616 4.08709')
.attr('orientation', '0.61973 0.43866 0.65078 1.70872');
let coneTransform = scene
.append('transform')
.attr('rotation', `1 0 0 ${Math.PI / 2}`);
let transform1 = coneTransform
.append('transform')
.attr('translation', '0 -1.5 0');
let shape = transform1.append('shape');
shape
.append('appearance')
.append('material')
.attr('diffuseColor', `0.2 0.2 0.8`)
.attr('specularColor', '0.2 0.2 0.2');
shape
.append('cone')
.attr('subdivision', '128')
.attr('height', 3)
.attr('bottomRadius', 3)
.attr('bottom', 'false')
.attr('solid', 'false');
let transform2 = coneTransform
.append('transform')
.attr('translation', '0 1.5 0')
.attr('rotation', `0 0 1 ${Math.PI}`);
shape = transform2.append('shape');
shape
.append('appearance')
.append('material')
.attr('diffuseColor', `0.2 0.2 0.8`)
.attr('specularColor', '0.2 0.2 0.2');
shape
.append('cone')
.attr('subdivision', '128')
.attr('height', 3)
.attr('bottomRadius', 3)
.attr('bottom', 'false')
.attr('solid', 'false');
// Add the plane
let translation = scene
.append('transform')
.attr('id', 'plane_translation')
.attr('translation', '0 0 -1');
let plane_rotation = translation
.append('transform')
.attr('id', 'plane_rotation')
.attr('rotation', `1 0 0 ${Math.PI / 6}`);
let planeShape = plane_rotation.append('shape').attr('id', 'plane');
planeShape
.append('appearance')
.append('material')
.attr('transparency', '0.25')
.attr('diffuseColor', `0.8 0.8 0.2`)
.attr('specularColor', '0.2 0.2 0.2');
planeShape
.append('plane')
.attr('solid', 'false')
.attr('size', '8 8');
// Add all the sections as curves on the cone.
// Initial transparency will be set to 1; curve
// will only be shown once selected.
let sections = scene.append('group').attr('id', 'sections');
// Add the point
let point = sections.append('group').attr('id', 'point');
shape = point.append('shape');
shape
.append('appearance')
.append('material')
.attr('transparency', 1)
.attr('diffuseColor', '0 0 0');
shape.append('sphere').attr('radius', '0.05');
// Add the circle
let circle_points = d3.range(-1, 102).map(function(t) {
return [
2 * Math.cos((2 * Math.PI * t) / 100),
2 * Math.sin((2 * Math.PI * t) / 100),
-2
];
});
sections.append(() =>
create_tube(circle_points, 0.02, {
cross_vector: [0, 0, 1],
m: 6,
diffuseColor: '0 0 0',
transparency: '1',
id: 'circle'
})
);
// Add the ellipse
let ellipse_points = d3.range(-1, 102).map(function(t) {
let tt = (2 * Math.PI * t) / 100;
let sqrt3 = Math.sqrt(3);
let cost = Math.cos(tt);
return [
Math.sqrt(1.5) * Math.sin(tt),
-(sqrt3 + 3 * cost) / 2,
-(3 + sqrt3 * cost) / 2
];
});
sections.append(() =>
create_tube(ellipse_points, 0.02, {
cross_vector: [0, -Math.sqrt(3) / 2, 1 / 2],
m: 12,
diffuseColor: '0 0 0',
transparency: '1',
id: 'ellipse'
})
);
// Add the parabola
let parabola_points = d3.range(-21, 22).map(function(x) {
let xx = (Math.sqrt(5) * x) / 20;
return [xx, (1 - xx ** 2) / 2, (-1 - xx ** 2) / 2];
});
sections.append(() =>
create_tube(parabola_points, 0.02, {
cross_vector: [0, -1, 1],
m: 12,
diffuseColor: '0 0 0',
transparency: '1',
id: 'parabola'
})
);
// Add the hyperbola in two parts
let hyperbola = sections.append('group').attr('id', 'hyperbola');
let xwidth = 20 * Math.acosh(3);
let dx = xwidth / 40;
let hyperbola_points1 = d3
.range(-xwidth - dx, xwidth + 2 * dx, dx)
.map(function(t) {
let tt = t / 20;
return [-Math.sinh(tt), 1, Math.cosh(tt)];
});
hyperbola.append(() =>
create_tube(hyperbola_points1, 0.02, {
cross_vector: [0, 1, 0],
m: 12,
diffuseColor: '0 0 0',
transparency: '1',
id: 'hyperbola_points1'
})
);
let hyperbola_points2 = hyperbola_points1.map(([x, y, z]) => [x, y, -z]);
hyperbola.append(() =>
create_tube(hyperbola_points2, 0.02, {
cross_vector: [0, 1, 0],
m: 12,
diffuseColor: '0 0 0',
transparency: '1',
id: 'hyperbola_points2'
})
);
// Add the single line
let single_line_transform = sections
.append('transform')
.attr('id', 'line')
.attr('rotation', `1 0 0 ${Math.PI / 4}`);
shape = single_line_transform.append('shape');
shape
.append('appearance')
.append('material')
.attr('transparency', 1)
.attr('diffuseColor', '0 0 0');
shape
.append('cylinder')
.attr('height', `${Math.sqrt(2) * 6}`)
.attr('radius', '0.02');
// Add the intersecting lines in two parts
let lines = sections.append('group').attr('id', 'lines');
let line1_transform = lines
.append('transform')
.attr(
'rotation',
`0 ${-Math.sqrt(3) / 2} 0.5 ${Math.acos(Math.sqrt(2 / 3))}`
)
.append('transform')
.attr('rotation', `1 0 0 ${Math.PI / 3}`);
shape = line1_transform.append('shape');
shape
.append('appearance')
.append('material')
.attr('transparency', 1)
.attr('diffuseColor', '0 0 0');
shape
.append('cylinder')
.attr('height', `${Math.sqrt(2) * 6}`)
.attr('radius', '0.02');
let line2_transform = lines
.append('transform')
.attr(
'rotation',
`0 ${-Math.sqrt(3) / 2} 0.5 ${-Math.acos(Math.sqrt(2 / 3))}`
)
.append('transform')
.attr('rotation', `1 0 0 ${Math.PI / 3}`);
shape = line2_transform.append('shape');
shape
.append('appearance')
.append('material')
.attr('transparency', 1)
.attr('diffuseColor', '0 0 0');
shape
.append('cylinder')
.attr('height', `${Math.sqrt(2) * 6}`)
.attr('radius', '0.02');
// Yield and reload
yield container.node();
x3dom.reload();
}