Public
Edited
Jan 5, 2024
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function draw_board() {
const [area, svg] = make_svg();
draw_horizontal_lines(svg);
draw_vertical_lines(svg);
return area.node();
}
Insert cell
function draw_board_transformed() {
const [area, svg] = make_svg();
draw_horizontal_lines_transformed(svg);
draw_vertical_lines_transformed(svg);
let margin = 50;
let height = HEIGHT - 2*margin;
let width = WIDTH - 2*margin;
// Draw on a larger canvas and crop to only show the middle - this way
// we don't have to deal with edge (literally!) cases.
svg.attr('viewBox', `${margin} ${margin} ${width} ${height}`);
return area.node();
}
Insert cell
function draw_horizontal_lines(svg) {
for (let y = -MAX_Y; y < MAX_Y; y+= 10) {
draw_line(svg, -MAX_X, y, MAX_X, y, 'red');
}
}
Insert cell
function draw_vertical_lines(svg) {
for (let x = -MAX_X; x < MAX_X; x+=10) {
draw_line(svg, x, -MAX_Y, x, MAX_Y, 'blue');
}
}
Insert cell
function get_level_curve_coord() {
let vs = [];
for (let v = 0; v < MAX_Y; v += 7) {
vs.push(Math.sqrt(v));
}
vs += [0.4, 0.5];
return reflect_array(vs);
}
Insert cell
function draw_horizontal_lines_transformed(svg) {

// generate level curves so that y at x = xmax is uniformily spaced
let x2 = MAX_X;
let ys = [];
for (let y2 = 0; y2 < 10 * MAX_Y; y2 += 10) {
let y = Math.sqrt((-x2 + Math.sqrt(x2**2 + y2**2))/2);
ys.push(y);
}
ys = reflect_array(ys);

let sqrt_maxx = Math.sqrt(MAX_X);
let stepx = sqrt_maxx / MAX_X;
let xs = [];
for (let x = 0; x < sqrt_maxx; x += stepx) {
xs.push(x*x);
}
for (let y of ys) {
let prev = null;
for (let x of xs) {
let [x2, y2] = f(x, y);
if (!is_inside(x2, y2)) {
break;
}
if (prev) {
draw_line(svg, prev[0], prev[1], x2, y2, 'red');
}
prev = [x2, y2];
}
}
}
Insert cell
function draw_vertical_lines_transformed(svg) {

// generate level curves so that y at x = -xmax is uniformily spaced
let x2 = -MAX_X;
let xs = [];
for (let y2 = 0; y2 < 10 * MAX_Y; y2 += 10) {
let y = Math.sqrt((-x2 + Math.sqrt(x2**2 + y2**2))/2);
let x = y2 / (2*y);
xs.push(x);
}
xs = reflect_array(xs);

// for each level curve.
let sqrt_maxy = Math.sqrt(MAX_Y);
let stepy = sqrt_maxy / MAX_Y;
let ys = [];
for (let y = 0; y < sqrt_maxy; y += stepy) {
ys.push(y*y);
}
for (let x of xs) {
let prev = null;
for (let y of ys) {
let [x2, y2] = f(x, y);
if (!is_inside(x2, y2)) {
break;
}
if (prev) {
draw_line(svg, prev[0], prev[1], x2, y2, 'blue');
}
prev = [x2, y2];
}
}
}
Insert cell
// z^2
function f(x, y) {
let x2 = x*x - y*y;
let y2 = 2*x*y;
return [x2, y2];
}
Insert cell
WIDTH = 500
Insert cell
MAX_X = 100
Insert cell
HEIGHT = 500
Insert cell
MAX_Y = 100
Insert cell
function make_svg() {
const area = d3.create('div');
const header = area.append('div');
const svg = area.append('svg')
.attr('width', WIDTH)
.attr('height', HEIGHT);
return [area, svg];
}
Insert cell
function draw_pixel(svg, x_, y_, color) {
let x = (x_ / (2*MAX_X) + 0.5 ) * WIDTH;
let y = (y_ / (2*MAX_Y) + 0.5 ) * HEIGHT;
svg.append("rect")
.attr("x", x)
.attr("y", y)
.attr("width", 1)
.attr("height", 1)
.attr("fill", color);
}
Insert cell
function draw_line(svg, x1_, y1_, x2_, y2_, color) {
let [x1, y1] = normalize_pt(x1_, y1_);
let [x2, y2] = normalize_pt(x2_, y2_);
svg.append("line")
.attr("x1", x1)
.attr("x2", x2)
.attr("y1", y1)
.attr("y2", y2)
.attr("stroke-width", 1)
.attr("stroke", color);
}
Insert cell
function normalize_pt(x_, y_) {
let x = (x_ / (2*MAX_X) + 0.5 ) * WIDTH;
let y = (y_ / (2*MAX_Y) + 0.5 ) * HEIGHT;
return [x, y];
}

Insert cell
function reflect_array(xs) {
let xs2 = [];
for (let x of xs) {
xs2.push(-x);
}
for (let x of xs) {
xs2.push(x);
}
return xs2;
}
Insert cell
function is_inside(x, y) {
return is_x_inside(x) && is_y_inside(y);
}
Insert cell
function is_x_inside(x) {
return x >= -MAX_X && x <= MAX_X;
}
Insert cell
function is_y_inside(y) {
return y >= -MAX_Y && y <= MAX_Y;
}
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