Skip to content

Instantly share code, notes, and snippets.

@HarryStevens
Last active March 8, 2024 08:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HarryStevens/b03d6496bdaf2a21cc4b1a4c854b5cfe to your computer and use it in GitHub Desktop.
Save HarryStevens/b03d6496bdaf2a21cc4b1a4c854b5cfe to your computer and use it in GitHub Desktop.
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