Reputation: 399
I have realized a javascript program, which can draw an arbitrary triangle, and calculate the angles and sides length.
Here is a program, which I try to realize: https://www.mathsisfun.com/proof180deg.html
Sadly I can't draw the arc's in angles of triangle!
Maybe by means of the HTML canvas arc() Method will be realized. E.g. like:
ctx.arc(x, y, 50, start , end);
The x-y position is known. I'm looking for "start" and "end" of angles.
Thanks in advance.
Upvotes: 2
Views: 794
Reputation: 54128
You can use Math.atan2 to get the direction of a line.
for example
// line from x1,y1 to x2,y2
var nx1 = x2 - x1;
var ny1 = y2 - y1;
var angle = Math.atan2(ny1,nx1);
So the you get the angle of the two lines from a corner. The angles are in the range -Math.PI to Math.PI so you need to move the first angle ahead of the second if it is lower or it will take the long way around.
There is also the problem of the triangle orientation, it can be clockwise or anticlockwise. If the wrong way the angles will be on the outside. You can use the cross product of the two lines to find the directio. If the wrong way then just swap the two angles.
Use the mouse to move one of the points.
const ctx = canvas.getContext("2d");
// 2 lines start at x1,y1, then join at x2,y2, and then out to x3,y3
function drawLinesAndAngle(x1,y1,x2,y2,x3,y3){
// get vectors from x2,y2 to the other points
var nx1 = x1 - x2;
var ny1 = y1 - y2;
var nx2 = x3 - x2;
var ny2 = y3 - y2;
var lineAngle1 = Math.atan2(ny1,nx1);
var lineAngle2 = Math.atan2(ny2,nx2);
// use cross product to find correct direction.
if(nx1 * ny2 - ny1 * nx2 < 0){ // wrong way around swap direction
const t = lineAngle2;
lineAngle2 = lineAngle1;
lineAngle1 = t;
}
// if angle 1 is behind then move ahead
if(lineAngle1 < lineAngle2){
lineAngle1 += Math.PI * 2;
}
// render the arc
ctx.fillStyle = "red";
ctx.beginPath();
ctx.moveTo(x2,y2);
ctx.arc(x2,y2,35,lineAngle1, lineAngle2);
ctx.fill();
// render outside arc
ctx.fillStyle = "blue";
ctx.beginPath();
ctx.moveTo(x2,y2);
ctx.arc(x2,y2,7,lineAngle2, lineAngle1);
ctx.fill();
// get the mid point
const mx = -Math.cos((lineAngle1 + lineAngle2) / 2) * 50 + x2;
const my = -Math.sin((lineAngle1 + lineAngle2) / 2) * 50 + y2;
// render the angle
ctx.fillStyle = "black";
ctx.font = "16px arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(
(360-(lineAngle1 - lineAngle2) * (180 /Math.PI)).toFixed(0), // convert to deg
mx,
my,
)
}
// short cut vars
var w = canvas.width;
var h = canvas.height;
var cw = w / 2; // center
var ch = h / 2;
// main update function
function update(timer){
ctx.setTransform(1,0,0,1,0,0); // reset transform
ctx.globalAlpha = 1; // reset alpha
if(w !== innerWidth || h !== innerHeight){
cw = (w = canvas.width = innerWidth) / 2;
ch = (h = canvas.height = innerHeight) / 2;
}else{
ctx.clearRect(0,0,w,h);
}
// start line
const x = Math.cos(timer / 5000) * Math.min(cw,ch) * 0.95 + cw;
const y = Math.sin(timer / 5000) * Math.min(cw,ch) * 0.95 + ch;
// fill triangle
ctx.fillStyle = "#FD8";
ctx.beginPath();
ctx.lineTo(x,y);
ctx.lineTo(cw,ch);
ctx.lineTo(mouse.x,mouse.y);
ctx.closePath();
ctx.fill();
drawLinesAndAngle(x,y,cw,ch,mouse.x,mouse.y);
drawLinesAndAngle(cw,ch,mouse.x,mouse.y,x,y);
drawLinesAndAngle(mouse.x,mouse.y,x,y,cw,ch);
// render the lines
ctx.strokeStyle = "black";
ctx.lineWidth = 3;
ctx.lineJoin = "round";
ctx.beginPath();
ctx.lineTo(x,y);
ctx.lineTo(cw,ch);
ctx.lineTo(mouse.x,mouse.y);
ctx.closePath();
ctx.stroke();
requestAnimationFrame(update);
}
requestAnimationFrame(update);
const mouse = {x : 0, y : 0, button : false, drag : false, dragStart : false, dragEnd : false, dragStartX : 0, dragStartY : 0}
function mouseEvents(e){
mouse.x = e.pageX;
mouse.y = e.pageY;
mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
}
["down","up","move"].forEach(name => document.addEventListener("mouse"+name,mouseEvents));
canvas { position : absolute; top : 0px; left : 0px; }
<canvas id="canvas"></canvas>
Upvotes: 5