计算线段与平面的交点

计算线段与平面的交点_第1张图片


//2.在三维空间中,求一个线段与三角形的交点
struct Point{
    float x;
    float y;
    float z;
    Point(float _x, float _y, float _z) : x(_x), y(_y), z(_z){}
};
struct segment{
    Point a,b;
};
struct Triangle {
    Point a,b,c;
};

bool intersect(const segment &s, const Triangle &t, Point &out) {
    // 求平面法向量
    // 叉乘公式:c = a×b = (a.y*b.z-b.y*a.z , b.x*a.z-a.x*b.z , a.x*b.y-b.x*a.y)
    Point v1 = t.a - t.b;
    Point v2 = t.a - t.c;
    Point n = Point(v1.y*v2.z-v2.y*v1.z , v2.x*v1.z-v1.x*v2.z , v1.x*v2.y-v2.x*v1.y);
    // 计算线段点到平面距离
    Point tmp = s.a - t.a;
    float cos_theta = tmp * n / sqrt(pow(tmp.x, 2), pow(tmp.y, 2), pow(tmp.z, 2))/ sqrt(pow(n.x, 2), pow(n.y, 2), pow(n.z, 2));
    float verticle_dis = distance(s.a, t.a) * cos_theta;
    // 计算直线与平面交点
    tmp = t.b - t.a;
    cos_theta =  tmp * n / sqrt(pow(tmp.x, 2), pow(tmp.y, 2), pow(tmp.z, 2))/ sqrt(pow(n.x, 2), pow(n.y, 2), pow(n.z, 2));
    Point ans = verticle_dis / cos_theta * normal(tmp) + s.a;

    // 判断点是否在线段上
    if( s.a <= ans && ans <= s.b){ // 1.在以该线段位对应角的长方体内
        if(euql_0((ans - s.a) X (s.b - s.a))){ // 2.两个向量叉积为0,则在线段上
            out = ans;
            return true;
        }
    }
    return false;
}

 

你可能感兴趣的:(Computer,Graphics)