angle = {
console.log('');
console.log('eval angle');
const height = 400;
const canvas = d3.select(DOM.svg(width, height));
canvas.style('border', '1px solid rgba(0,0,0,0.05)')
.style('font-family', 'monospace')
const origin = {x: width/2, y: height/2}
const rayLength = width > height / 3 ? height / 3 : width / 3;
const staticRayEndCoord = [origin.x + rayLength, origin.y]
const scaleX = d3.scaleLinear()
.domain([-1, 1])
.range([origin.x - rayLength, origin.x + rayLength]);
const scaleY = d3.scaleLinear()
.domain([1, -1])
.range([origin.y + rayLength, origin.y -rayLength]);
const thetaStartAngle = pi / 2;
const thetaEndAngle = pi/4;
const vis = canvas.append('g')
.attr('class', 'visualization');
const labelArcGen = d3.arc()
.outerRadius(60)
.innerRadius(60)
.startAngle(thetaStartAngle)
.endAngle(thetaEndAngle);
const arcGen = d3.arc()
.outerRadius(39)
.innerRadius(40)
.startAngle(thetaStartAngle)
.endAngle(thetaEndAngle);
const thetaArc = vis.append('path')
.attr('class', 'arc arc-theta')
.attr('fill', 'transparent')
.attr('stroke', colors.thetaArc)
.attr('transform', `translate(${origin.x}, ${origin.y})`)
.attr('d', arcGen);
let betaArc;
if (showBeta) {
betaArc = vis.append('path')
.attr('class', 'arc arc-beta')
.attr('fill', 'transparent')
.attr('stroke', colors.betaArc)
.attr('transform', `translate(${origin.x}, ${origin.y})`)
.attr('d', arcGen.startAngle(thetaEndAngle).endAngle(-3/2 * pi));
}
const lineGenerator = d3.line();
const side = vis.append('path')
.attr('class', 'ray ray--static')
.attr('stroke', 'black')
.attr('marker-end', (d) => "url(#arrow)")
.attr('d', lineGenerator([[origin.x, origin.y], staticRayEndCoord]));
const line = vis.append('path')
.attr('class', 'ray ray--dynamic')
.attr("stroke", "black")
.attr('d', lineGenerator([[origin.x, origin.y], [Math.cos(thetaEndAngle) * rayLength + origin.x , origin.y - Math.sin(thetaEndAngle) * rayLength]]))
.attr('marker-end', (d) => "url(#arrow)");
vis.append('circle')
.style("fill", 'black')
.attr("cx", origin.x)
.attr("cy", origin.y)
.attr("r", 2);
function updatePositions(x,y){
const a = Math.atan2( y - origin.y, x - origin.x);
const rayX = scaleX(Math.cos(a));
const rayY = scaleY(Math.sin(a));
const thetaAngle = a < 0 ? a + pi/2 : (- 2* pi + a) + pi / 2 ;
const lineData = lineGenerator([[origin.x, origin.y], [rayX, rayY]]);
const thetaArcArcData = arcGen.endAngle(thetaAngle);
thetaArc.attr('d', thetaArcArcData);
labelArcGen.endAngle(thetaAngle);
const thetaLabelCentroid = labelArcGen.centroid();
thetaLabel.attr('transform', `translate(${thetaLabelCentroid[0] + origin.x}, ${thetaLabelCentroid[1] + origin.y})`);
if (betaArc) {
const endAngle = thetaAngle + 2 * pi
const betaArcData = arcGen.endAngle(endAngle).startAngle(thetaStartAngle);
betaArc.attr('d', betaArcData);
const labelArcData = labelArcGen.endAngle(endAngle).startAngle(thetaStartAngle);
const betaLabelCentroid = labelArcData.centroid();
betaLabel.attr('transform', `translate(${betaLabelCentroid[0] + origin.x}, ${betaLabelCentroid[1] + origin.y})`);
}
line.attr('d', lineData);
}
canvas.on("mousemove", function() {
const mouse = d3.mouse(this);
updatePositions(mouse[0], mouse[1]);
});
const annotations = canvas.append('g')
.attr('class', 'annotations')
annotations.append('text')
.attr('class', 'annotation annotation-point')
.attr('transform', `translate(${origin.x - 5}, ${origin.y + 20})`)
.text('O')
.attr('fill','black')
const thetaLabel = annotations.append("text")
.attr('class', 'annotation annotation-theta')
.attr('fill', colors.thetaArc)
.attr('dx','-4')
.attr('dy','4')
.attr('transform', `translate(${labelArcGen.centroid()[0] + origin.x}, ${labelArcGen.centroid()[1] + origin.y})`)
.text('θ');
let betaLabel;
if (showBeta) {
betaLabel = annotations.append("text")
.attr('class', 'annotation annotation-theta')
.attr('fill', colors.betaArc)
.attr('dx','-4')
.attr('dy','4')
.attr('transform', `translate(${labelArcGen.startAngle(thetaEndAngle).endAngle(-3/2 * pi).centroid()[0] + origin.x}, ${labelArcGen.startAngle(thetaEndAngle).endAngle(-3/2 * pi).centroid()[1] + origin.y})`)
.text('β');
}
const description = showBeta ? "Angles θ and β with vertex at point O": 'An angle θ with vertex at point O'
annotations.append('text')
.attr('font-size', '14')
.attr('class', 'annotation annotation-description')
.attr('transform', `translate(${20}, ${20})`)
.text(`Fig 2: ${description}`)
.attr('fill','black')
canvas.append("svg:defs").append("svg:marker")
.attr("id", "arrow")
.attr("viewBox", "0 -5 10 10")
.attr("markerWidth", 5)
.attr("markerHeight", 5)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
return canvas.node();
}