Skip to content

Instantly share code, notes, and snippets.

@HarryStevens
Last active Jan 30, 2019
Embed
What would you like to do?
Angle of Reflection
license: gpl-3.0

Use angleReflect() from Geometric.js to calculate the angle of reflection given an angle of incidence and a surface angle.

The blue line represents the angle of incidence, the purple line the angle of reflection, and the black line the surface. You can change the angle of incidence by draggin the blue circle, and the angle of the surface by dragging the black circle.

<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
}
line {
stroke-width: 2px;
pointer-events: none;
}
.surface-line {
stroke: black;
}
.start-angle {
stroke: steelblue;
}
.reflect-angle {
stroke: purple;
}
circle {
stroke: #fff;
cursor: pointer;
}
.start-handle {
fill: steelblue;
}
</style>
</head>
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://unpkg.com/geometric@1.0.6/build/geometric.js"></script>
<script>
var width = window.innerWidth, height = window.innerHeight;
var center = [width / 2, height / 2];
var svg = d3.select("body").append("svg").attr("width", width).attr("height", height);
var surfaceAnglePrev = 0,
surfaceAngle = 0,
surfaceAngleChange = 0,
surfaceStartPoint,
surfaceEndPoint,
startAngle = 235,
reflectedAngle,
distance = 200,
startPoint,
reflectedPoint;
var surfaceDragGenerator = d3.drag()
.on("drag", d => {
surfaceAnglePrev = surfaceAngle;
surfaceAngle = geometric.lineAngle([[event.pageX, event.pageY], center]);
surfaceAngleChange = surfaceAngle - surfaceAnglePrev;
update();
});
var surfaceLine = svg.append("line")
.attr("class", "surface-line");
var surfaceHandle = svg.append("circle")
.attr("class", "surface-handle")
.attr("r", 10)
.call(surfaceDragGenerator);
var startDragGenerator = d3.drag()
.on("drag", d => {
startPoint = [event.pageX, event.pageY];
distance = geometric.lineLength([center, startPoint]);
startAngle = geometric.lineAngle([center, startPoint]);
update();
});
var startLine = svg.append("line")
.attr("class", "start-angle")
.attr("x2", center[0])
.attr("y2", center[1]);
var startHandle = svg.append("circle")
.attr("class", "start-handle")
.attr("r", 10)
.call(startDragGenerator)
var reflectedLine = svg.append("line")
.attr("class", "reflect-angle")
.attr("x2", center[0])
.attr("y2", center[1]);
update();
function update(){
surfaceStartPoint = geometric.pointTranslate(center, surfaceAngle, -120);
surfaceEndPoint = geometric.pointTranslate(center, surfaceAngle, 120);
startAngle += surfaceAngleChange;
reflectedAngle = geometric.angleReflect(startAngle - 180, surfaceAngle); // subtract 180 from start angle so that it begins at start point
startPoint = geometric.pointTranslate(center, startAngle, distance);
reflectedPoint = geometric.pointTranslate(center, reflectedAngle, distance);
surfaceLine
.attr("x1", surfaceStartPoint[0])
.attr("y1", surfaceStartPoint[1])
.attr("x2", surfaceEndPoint[0])
.attr("y2", surfaceEndPoint[1]);
surfaceHandle
.attr("transform", "translate(" + surfaceStartPoint + ")");
startLine
.attr("x1", startPoint[0])
.attr("y1", startPoint[1]);
startHandle
.attr("transform", "translate(" + startPoint + ")");
reflectedLine
.attr("x1", reflectedPoint[0])
.attr("y1", reflectedPoint[1]);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment