TheAlgorithms/Java · warning · IllegalArgumentException

Total internal reflection: no refraction possible.

Error message

Total internal reflection: no refraction possible.

What it means

Thrown by SnellLaw.refractedAngle when the computed sin(theta2) has absolute value greater than 1.0. By Snell's law n1*sin(theta1) = n2*sin(theta2); when light travels from a denser to a rarer medium (n1 > n2) beyond the critical angle, sin(theta2) exceeds 1 and no refraction is possible — the light undergoes total internal reflection. Math.asin would otherwise return NaN for such input.

Source

Thrown at src/main/java/com/thealgorithms/physics/SnellLaw.java:28

    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);
    }
}

View on GitHub (pinned to fdfb9a395b)

Solutions

  1. Handle total internal reflection as a legitimate physical outcome: catch the exception and reflect the ray instead of refracting it.
  2. Check (n1/n2)*Math.abs(Math.sin(theta1)) <= 1.0 before calling, and branch to a reflection path if it exceeds 1.
  3. Verify n1 and n2 are in the correct order — n1 is the medium the ray is leaving, n2 the medium it is entering.
  4. Confirm theta1 is in radians (convert with Math.toRadians if your input is in degrees).

Example fix

// before
double theta2 = SnellLaw.refractedAngle(1.5, 1.0, Math.toRadians(50)); // TIR -> throws
// after
 double ratio = 1.5 / 1.0;
double s2 = ratio * Math.abs(Math.sin(Math.toRadians(50)));
double theta2;
if (s2 > 1.0) {
    theta2 = Math.PI / 2 - Math.toRadians(50); // reflect instead
} else {
    theta2 = SnellLaw.refractedAngle(1.5, 1.0, Math.toRadians(50));
}
Defensive patterns

Strategy: try-catch

Validate before calling

double sinTheta2 = (n1 / n2) * Math.abs(Math.sin(theta1));
double theta2;
if (sinTheta2 > 1.0) {
    // total internal reflection — reflect instead of refract
    theta2 = Math.PI / 2 - theta1;
} else {
    theta2 = SnellLaw.refractedAngle(n1, n2, theta1);
}

Try / catch

try {
    theta2 = SnellLaw.refractedAngle(n1, n2, theta1);
} catch (IllegalArgumentException e) {
    // total internal reflection: route the ray through reflection logic
    theta2 = Math.PI / 2 - theta1;
}

Prevention

When it happens

Trigger: Calling refractedAngle(n1, n2, theta1) where (n1/n2) * |sin(theta1)| > 1.0 — i.e. n1 > n2 and the incident angle exceeds the critical angle theta_c = asin(n2/n1). Example: n1=1.5 (glass), n2=1.0 (air), theta1 > ~41.8 degrees.

Common situations: Optics simulation where the incident angle crosses the critical angle, ray tracing from glass-to-air or water-to-air, or swapping n1 and n2 by mistake so that the denser medium is treated as the destination.

Related errors


AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13). Data as JSON: /api/errors/187743cb1b1ace4c. Report an issue: GitHub.