我实际上正在用 c 语言制作光线追踪器。我需要根据生命值找到圆锥体的法线。我的函数原型如下:
t_vec_3 cone_normal(t_point hitpoint, t_cone cone);
锥体结构包含这些信息:
struct s_cone
{
t_point coordinate;
t_vec_3 vector;
double diameter;
double height;
t_color color;
t_material material;
};
我尝试了几种解决方案,但在所有情况下,它们仅在圆锥向量等于 (0, 1, 0) 时才有效。
我的函数目前看起来像这样,但只有在圆锥体是直的情况下才有效。
t_vec_3 cone_normal(t_point hitpoint, t_cone cone)
{
t_vec_3 tmp;
t_vec_3 result;
tmp = set_vec(hitpoint.x - cone.coordinate.x, 0, hitpoint.z - cone.coordinate.z);
calculate_norm(&tmp);
tmp.x/= tmp.norme;
tmp.z/= tmp.norme;
normalize_vec(&tmp);
result = set_vec(tmp.x * cone.height / (cone.diameter / 2), \
(cone.diameter / 2) / cone.height, tmp.z * cone.height / (cone.diameter / 2));
normalize_vec(&result);
return (result);
}
编辑:
我忘记指定calculate_norm和normalize_vec代码。
double calculate_norm(t_vec_3 *vec)
{
double norm;
norm = sqrt(pow(vec->x, 2) + pow(vec->y, 2) + pow(vec->z, 2));
vec->norme = norm;
return (norm);
}
void normalize_vec(t_vec_3 *vec)
{
double norm;
norm = calculate_norm(vec);
vec->x = vec->x / norm;
vec->y = vec->y / norm;
vec->z = vec->z / norm;
}
您知道圆锥体高度和圆锥体直径,因此您知道顶点处的角度(从侧面到轴)。
tan(apexangle) = cone.diameter / (2*cone.height)
一旦获得分别指向击中点的轴方向和沿轴方向的单位向量 ihat 和 jhat,则单位法线 nhat 必须为
nhat = ihat * cos(apexangle) + jhat * sin(apexangle)
您只需除以 cos 即可完成一次三角计算
nhat * sec(apexangle) = ihat + jhat * (cone.diameter / (2*cone.height))
jhat 只是你的归一化的 cone.vector (我假设),而 ihat 是归一化的
hitpoint - (hitpoint.jhat)jhat.