Skip to content

Commit 316def4

Browse files
authored
Add Snell's Law refraction algorithm (#7150)
* Add Snell's Law implementation for refraction angle * Add tests for Snell's Law calculations * Update documentation with reference link to Snell's Law Added a reference link to Snell's Law in the documentation. * Prevent instantiation of SnellLaw class Make SnellLaw class non-instantiable by adding a private constructor. * Rename SnellsLawTest to SnellLawTest * Refactor SnellLawTest for clarity and accuracy * Rename SnellsLaw.java to SnellLaw.java * Refactor SnellLawTest with additional assertions * Refactor SnellLaw class constructor and error handling Refactor SnellLaw constructor and error message formatting. * Fix missing newline at end of SnellLawTest.java Ensure that the SnellLawTest class has a newline at the end of the file. * Simplify assertions in SnellLawTest * Simplify exception throwing for total internal reflection
1 parent 246162e commit 316def4

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.thealgorithms.physics;
2+
3+
/**
4+
* Calculates refraction angle using Snell's Law:
5+
* n1 * sin(theta1) = n2 * sin(theta2)
6+
* @see <a href="https://en.wikipedia.org/wiki/Snell%27s_law">Snell's Law</a>
7+
*/
8+
public final class SnellLaw {
9+
10+
private SnellLaw() {
11+
throw new AssertionError("No instances.");
12+
}
13+
14+
/**
15+
* Computes the refracted angle (theta2) in radians.
16+
*
17+
* @param n1 index of refraction of medium 1
18+
* @param n2 index of refraction of medium 2
19+
* @param theta1 incident angle in radians
20+
* @return refracted angle (theta2) in radians
21+
* @throws IllegalArgumentException if total internal reflection occurs
22+
*/
23+
public static double refractedAngle(double n1, double n2, double theta1) {
24+
double ratio = n1 / n2;
25+
double sinTheta2 = ratio * Math.sin(theta1);
26+
27+
if (Math.abs(sinTheta2) > 1.0) {
28+
throw new IllegalArgumentException("Total internal reflection: no refraction possible.");
29+
}
30+
31+
return Math.asin(sinTheta2);
32+
}
33+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.thealgorithms.physics;
2+
3+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
import static org.junit.jupiter.api.Assertions.assertThrows;
6+
7+
import org.junit.jupiter.api.Test;
8+
9+
public class SnellLawTest {
10+
11+
@Test
12+
public void testRefractedAngle() {
13+
double n1 = 1.0; // air
14+
double n2 = 1.5; // glass
15+
double theta1 = Math.toRadians(30);
16+
17+
double theta2 = SnellLaw.refractedAngle(n1, n2, theta1);
18+
19+
double expected = Math.asin(n1 / n2 * Math.sin(theta1));
20+
21+
assertEquals(expected, theta2, 1e-12);
22+
}
23+
24+
@Test
25+
public void testTotalInternalReflection() {
26+
double n1 = 1.5;
27+
double n2 = 1.0;
28+
double theta1 = Math.toRadians(60); // large angle
29+
30+
assertThrows(IllegalArgumentException.class, () -> SnellLaw.refractedAngle(n1, n2, theta1));
31+
}
32+
33+
@Test
34+
public void testNoTotalInternalReflectionAtLowAngles() {
35+
double n1 = 1.5;
36+
double n2 = 1.0;
37+
double theta1 = Math.toRadians(10);
38+
39+
assertDoesNotThrow(() -> SnellLaw.refractedAngle(n1, n2, theta1));
40+
}
41+
}

0 commit comments

Comments
 (0)