Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/main/java/com/thealgorithms/physics/SnellsLaw.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.thealgorithms.physics;

/**
* Calculates refraction angle using Snell's Law:
* n1 * sin(theta1) = n2 * sin(theta2)
* @see <a href="https://en.wikipedia.org/wiki/Snell%27s_law">Snell's Law</a>
*/
public final class SnellLaw {
private SnellLaw() {
throw new AssertionError("No instances.");
}
/**
* Computes the refracted angle (theta2) in radians.
*
* @param n1 index of refraction of medium 1
* @param n2 index of refraction of medium 2
* @param theta1 incident angle in radians
* @return refracted angle (theta2) in radians
* @throws IllegalArgumentException if total internal reflection occurs
*/
public static double refractedAngle(double n1, double n2, double theta1) {
double ratio = n1 / n2;
double sinTheta2 = ratio * Math.sin(theta1);

if (Math.abs(sinTheta2) > 1.0) {
throw new IllegalArgumentException("Total internal reflection: no refraction possible.");
}

return Math.asin(sinTheta2);
}
}
43 changes: 43 additions & 0 deletions src/test/java/com/thealgorithms/physics/SnellLawTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.thealgorithms.physics;

import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

public class SnellLawTest {

@Test
public void testRefractedAngle() {
double n1 = 1.0; // air
double n2 = 1.5; // glass
double theta1 = Math.toRadians(30);

double theta2 = SnellLaw.refractedAngle(n1, n2, theta1);

double expected = Math.asin((n1 / n2) * Math.sin(theta1));

assertEquals(expected, theta2, 1e-12);
}

@Test
public void testTotalInternalReflection() {
// total internal reflection happens when n1 > n2 AND theta1 is large
double n1 = 1.5;
double n2 = 1.0;
double theta1 = Math.toRadians(60); // large enough angle

assertThrows(IllegalArgumentException.class, () -> {
SnellLaw.refractedAngle(n1, n2, theta1);
});
}

@Test
public void testNoTotalInternalReflectionAtLowAngles() {
double n1 = 1.5;
double n2 = 1.0;
double theta1 = Math.toRadians(10);

assertDoesNotThrow(() -> {
SnellLaw.refractedAngle(n1, n2, theta1);
});
}
}
Loading