'Make a triangle and label it using Canvas in Node.js

I am trying to make something that looks like this:

enter image description here

I've written this so far:

const { createCanvas } = require('canvas');
 
class Trigonometry {
    constructor({ sides, angles }) {
        this.sides = sides;
        this.angles = angles;
    }
 
    drawCanvas() {
        const { a, b, c } = this.sides;
        const [SA, SB, SC] = this.scaleNumbers(a, b, c);
        const { A: AA, B: AB, C: AC } = this.angles;
 
        const canvas = createCanvas(300, 300);
        const ctx = canvas.getContext('2d');
 
        const ax = 0, ay = 0;
        const bx = SC, by = 0;
        const cx = (SB * SA + SC * SC - SA * SA) / (2 * SC);
        const cy = Math.sqrt(SB * SA + SC + cx * cx);
 
        const ox = canvas.width / 2 - bx / 2;
        const oy = canvas.height / 2 + cy / 2;
 
        // Draw triangle
        ctx.beginPath();
        ctx.moveTo(ox + ax, oy - ay);
        ctx.lineTo(ox + bx, oy - by);
        ctx.lineTo(ox + cx, oy - cy);
        ctx.lineTo(ox + ax, oy - ay);
        ctx.lineWidth = 2; ctx.fillStyle = 'grey';
        ctx.stroke(); ctx.fill();
        ctx.closePath();
 
        // Draw angle labels
        ctx.font = 'bold 15px Arial';
        ctx.fillStyle = 'blue';
        this.drawLabel(ctx, `A=${AA}°`, ox + ax, oy - ay);
        this.drawLabel(ctx, `B=${AB}°`, ox + bx, oy - by);
        this.drawLabel(ctx, `C=${AC}°`, ox + cx, oy - cy);
 
        // Draw line labels
        ctx.fillStyle = 'green';
        this.drawLabel(ctx, `a=${a}`, bx + cx / 2, by - cy / 2);
        this.drawLabel(ctx, `b=${b}`, ox + cx / 2, oy - cy / 2);
        this.drawLabel(ctx, `c=${c}`, ox + bx / 2, oy - by / 2);
 
        return canvas.toDataURL()
    }
 
    drawLabel(ctx, txt, x, y) {
        const { width } = ctx.measureText(txt);
        ctx.fillText(txt, x - width / 2, y);
    }
 
    scaleNumbers(...numbers) {
        if (numbers.every(n => n > 200 && n < 250)) return numbers;
        if (numbers.some(n => n > 250))
            return numbers.map(n => n / (Math.max(...numbers) / 250))
        return numbers.map(n => n * (250 / Math.min(...numbers)));
    }
}
 
const trig = new Trigonometry({
    sides: { a: 800, b: 750, c: 700 },
    angles: { A: 66.868, B: 59.556, C: 53.576 },
});

const data = trig.toDataURL();

But it doesn't result in exactly what I want, the triangle is simply wrong and it breaks a lot and simply looks bad.

enter image description here

All the line lengths and angles get calculated before hand so I have access to all of those. Maybe there is another way to do this without using canvas?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source