Published
Edited
Sep 22, 2018
1 star
Insert cell
Insert cell
{
const height = 800;
const context = DOM.context2d(width, height);
const scale = (Math.min(width, height) - 4) / 3;
const center = [1 / scale, -0.25];

function circle([x, y, r], o) {
const options = Object.assign(
{
color: "black",
fill: true,
dash: [0, 0]
},
o
);
context.beginPath();
context.moveTo(x + r, y);
context.arc(x, y, r, 0, 2 * Math.PI);
context.strokeStyle = options.color;
context.setLineDash(options.dash);
context.fillStyle = options.color;
options.fill ? context.fill() : context.stroke();
}

function line([x1, y1], [x2, y2], o) {
const options = Object.assign({ color: "black" }, o);
context.beginPath();
context.moveTo(x1, y1);
context.lineTo(x2, y2);
context.strokeStyle = options.color;
context.stroke();
}

function textAt([x, y], text) {
context.font = `${16 / scale}px sans-serif`;
context.fillText(text, x + 10 / scale, y + 15 / scale);
}

function triangle([x1, y1, r1], [x2, y2, r2], [x3, y3, r3]) {
line([x1, y1], [x2, y2]);
circle([x1, y1, r1]);
textAt([x1, y1], "A");
line([x2, y2], [x3, y3]);
circle([x2, y2, r2]);
textAt([x2, y2], "B");
line([x3, y3], [x1, y1]);
circle([x3, y3, r3]);
textAt([x3, y3], "C");
}

while (true) {
const t1 = toggle ? Math.sin(Date.now() / 1000) / 2 : 0;
const t2 = toggle ? Math.cos(Date.now() / 1000) / 2 : 0;
const p = [
[-280 / scale + t1, 180 / scale, 3 / scale],
[250 / scale, 150 / scale, 3 / scale],
[-200 / scale, -180 / scale + t2, 3 / scale]
];

context.clearRect(0, 0, width, height);
context.save();
context.translate(width / 2, height / 2);
context.scale(scale, scale);
context.lineWidth = 1 / scale;

triangle(...p);

const a = dist(p[1], p[2]);
const b = dist(p[0], p[2]);
const c = dist(p[0], p[1]);

const [alpha, beta, gamma] = sss(a, b, c);

const oc = orthocenter(p, alpha, beta, gamma);

const ap = altitude(a, alpha, b, beta, c, gamma, p);
ap.map((po, i) => {
circle(po, { color: "blue" });
line(po, p[i], { color: "blue" });
});
const ce = centroid(p);

// not ideal
let color = "green";
const abM = middleBetween(p[0], p[1]);
circle(abM, { color });
line(p[2], abM, { color });
const bcM = middleBetween(p[1], p[2]);
circle(bcM, { color });
line(p[0], bcM, { color });
const acM = middleBetween(p[0], p[2]);
circle(acM, { color });
line(p[1], acM, { color });

const cc = circumcircle(p);
circle(cc, { fill: false, center: true, dash: [5 / scale, 15 / scale] });

// circumcenter
circle([cc[0], cc[1], 4 / scale], { color: "red" });

// orthocenter
circle([...oc, 4 / scale], { color: "red" });

// centroid
circle([...ce, 4 / scale], { color: "red" });

// euler line
const [p1, p2] = lineThrough(oc, getAlphaBetweenPoints(oc, ce));
line(p1, p2, { color: "red" });

context.restore();
yield context.canvas;
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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