2015-04-20 4 views
0

Я пишу трассировщик лучей в java, и я пытаюсь реализовать преломление, но меня смущает информация, которую я нахожу на эту тему. Если у меня есть 3D-вектор для входящего луча света, нормальная поверхность, заданная как 3D-вектор, и показатели преломления двух сред, какие операции мне нужно применить, чтобы получить вектор проходящего луча?Как найти преломляющий вектор от входящего вектора и поверхности нормальный

+0

http://en.wikipedia.org/wiki/Snell%27s_law#Vector_form –

ответ

1

V_incedence быть нормализованным входящим вектором. Пусть n1 и n2 являются показателями преломления двух поверхностей. Вы хотите рассчитать V_refraction. Пусть n - нормализованный нормальный вектор.

V_refraction = r*V_incedence + (rc - sqrt(1-r^2(1-c^2)))n 
where r = n1/n2 and c = -n dot V_incedence. 
+0

Спасибо за ответ. В первой строке это означает добавление вектора V_incedence.multiply (r) с вектором n.multiply (rc - sqrt (1-r^2 (1-c^2)))? – user2320239

+0

Да, точно. –

0

Я реализовал это в моем луче Java трассера гляньте https://github.com/bradforj287/brads-java-raytracer

private static double clamp(final double val, final double min, final double max) { 
    return Math.max(min, Math.min(max, val)); 
} 

private Vector3d getRefractionVector(final Vector3d I, final Vector3d N, final double ior) { 
    double cosi = clamp(-1, 1, I.dot(N)); 
    double etai = 1, etat = ior; 
    Vector3d n = N; 
    if (cosi < 0) { 
     cosi = -cosi; 
    } else { 
     double temp = etai; 
     etai = etat; 
     etat = temp; 
     n = N.multiply(-1); 
    } 
    double eta = etai/etat; 
    double k = 1 - (eta * eta) * (1 - (cosi * cosi)); 
    if (k <= 0) { 
     return Vector3d.ZERO; 
    } else { 
     return I.multiply(eta).add(n.multiply(((eta * cosi) - Math.sqrt(k)))); 
    } 
} 
Смежные вопросы