You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言光线追踪器中任意方向圆锥体法向量求解问题

任意方向圆锥体的法向量求解方法

几何原理梳理

圆锥的法向量需要结合其径向方向和轴线方向计算:

  • 设圆锥顶点为P0(即cone.coordinate),轴线方向向量为dir(需归一化),高度为h,底面半径r = diameter/2,半角正切值tanθ = r/h。
  • 对于命中点P,先计算顶点到命中点的向量V = P - P0。
  • 将V分解为平行于轴线的分量V_parallel和垂直于轴线的分量V_perpendicular。
  • 法向量由径向单位向量(垂直于轴线的方向)和轴线方向向量按比例组合后归一化得到。

完整实现代码

t_vec_3    cone_normal(t_point hitpoint, t_cone cone)
{
    t_vec_3    V;
    t_vec_3    cone_dir;
    double     h;
    double     r;
    double     tan_theta;
    double     h_proj;
    t_vec_3    V_perp;
    t_vec_3    radial_dir;
    t_vec_3    normal;

    // 初始化核心参数
    h = cone.height;
    r = cone.diameter / 2.0;
    tan_theta = r / h;

    // 确保圆锥方向向量为单位向量
    cone_dir = cone.vector;
    normalize_vec(&cone_dir);

    // 计算顶点到命中点的向量V
    V = set_vec(
        hitpoint.x - cone.coordinate.x,
        hitpoint.y - cone.coordinate.y,
        hitpoint.z - cone.coordinate.z
    );

    // 计算V在圆锥轴线上的投影长度
    h_proj = dot_product(V, cone_dir);

    // 计算V垂直于轴线的分量
    V_perp.x = V.x - h_proj * cone_dir.x;
    V_perp.y = V.y - h_proj * cone_dir.y;
    V_perp.z = V.z - h_proj * cone_dir.z;

    // 处理命中点在轴线上的特殊情况(理论上极少出现)
    if (V_perp.x == 0 && V_perp.y == 0 && V_perp.z == 0)
        return cone_dir;

    // 归一化垂直分量得到径向单位向量
    normalize_vec(&V_perp);
    radial_dir = V_perp;

    // 组合径向与轴线向量得到法向量
    normal.x = radial_dir.x / tan_theta - cone_dir.x * tan_theta;
    normal.y = radial_dir.y / tan_theta - cone_dir.y * tan_theta;
    normal.z = radial_dir.z / tan_theta - cone_dir.z * tan_theta;

    // 归一化最终法向量
    normalize_vec(&normal);

    return normal;
}

依赖补充

需要实现点积函数用于向量投影计算:

double dot_product(t_vec_3 a, t_vec_3 b)
{
    return a.x * b.x + a.y * b.y + a.z * b.z;
}

内容的提问来源于stack exchange,提问作者coromo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:58:24