Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
33 changes: 33 additions & 0 deletions src/main/java/com/thealgorithms/physics/SnellLaw.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
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);
}
}
41 changes: 41 additions & 0 deletions src/test/java/com/thealgorithms/physics/SnellLawTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.thealgorithms.physics;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

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() {
double n1 = 1.5;
double n2 = 1.0;
double theta1 = Math.toRadians(60); // large 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));
}
}