* @param l2         line which is considered to be an edge
     * @param nEnvSource refractive index of source environment
     * @param nEnvDest   refractive index of destination environment
     * @return refracted line
     * @throws IllegalArgumentException when total internal incidence occures.
     */
    public static Line getRefractedLine(Line l1, Line l2, double nEnvSource, double nEnvDest) throws IllegalArgumentException {
        logger.debug("Calculatin refracted line for entry:" + l1.toString() + " " + l2.toString() + " sourceEnv:" + nEnvSource + " destEnv:" + nEnvDest);

        double incidenceAngle = calculateIncidenceAngle(l1, l2);

        logger.debug("Calculated incidence angle:" + incidenceAngle);
        if (Math.abs(incidenceAngle) < 0.01) {
            return l1;
        }

        double refrationAngle = calculateRefractionAngle(incidenceAngle, nEnvSource, nEnvDest);

        if (refrationAngle == Double.NaN || Double.isNaN(refrationAngle)) {
            logger.error("Expcetion damn...");
            throw new IllegalArgumentException("Total internal incidence occured!");
        }

        logger.debug("Calculated refraction angle:" + refrationAngle);
        Point refractionPoint = calculateIntersectingPoint(l1, l2);
        logger.debug("Calculated intersection point:" + refractionPoint.toString());

        if (l1.getB() != 0) {
            l1.scaleFactors(-1.0 / l1.getB());
        }

        double gamma = Math.atan(l1.getA());

        double sigma = gamma - (incidenceAngle - refrationAngle);

        logger.debug("Angles: alfa=" + incidenceAngle + ", beta=" + refrationAngle + ", gamma=" + gamma + ", sigma=" + sigma);
        double a = Math.tan(sigma);
        double b = -1.0;
        double c = -a * refractionPoint.getX() - b * refractionPoint.getY();
        logger.debug("a=" + a + ", b=" + b + ", c=" + c);
        return new Line(a, b, c);
    }