//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;
}