# 2. 详论

## 2.1. 解析几何算法

$(y-y2)/(y1-y2) = (x-x2)/(x1-x2)$

//判断两线段相交
bool IsIntersect(double px1, double py1, double px2, double py2, double px3, double py3, double px4, double py4)
{
bool flag = false;
double d = (px2 - px1) * (py4 - py3) - (py2 - py1) * (px4 - px3);
if (d != 0)
{
double r = ((py1 - py3) * (px4 - px3) - (px1 - px3) * (py4 - py3)) / d;
double s = ((py1 - py3) * (px2 - px1) - (px1 - px3) * (py2 - py1)) / d;
if ((r >= 0) && (r <= 1) && (s >= 0) && (s <= 1))
{
flag = true;
}
}
return flag;
}


## 2.3. 向量方程法

### 2.3.1. 原理

$D = E - O$

$P = O + tD$

$\begin{cases} P = O_1 + t_1 D_1 \\ P = O_2 + t_2 D_2 \\ \end{cases}$

$t_1 D_1 - t_2 D_2 = O_2 - O_1 = O_{12} \tag{1}$

$\begin{bmatrix} {D_1.x}&{-D_2.x}\\ {D_1.y}&{-D_2.y}\\ \end{bmatrix} \begin{bmatrix} {t1}\\ {t2}\\ \end{bmatrix}= \begin{bmatrix} {O_{12}.x}\\ {O_{12}.y}\\ \end{bmatrix}$

### 2.3.2. 实现

//空间直线
template <class T>
class LineSegment
{
public:
Vec3<T> startPoint;
Vec3<T> endPoint;
Vec3<T> direction;

Vec3<T> min;
Vec3<T> max;

LineSegment()
{
}

LineSegment(Vec3<T> start, Vec3<T> end)
{
startPoint = start;
endPoint = end;
direction = end - start;
CalMinMax();
}

inline void Set(Vec3<T> start, Vec3<T> end)
{
startPoint = start;
endPoint = end;
direction = end - start;
CalMinMax();
}

inline void CalMinMax()
{
min.x() = std::min<T>(startPoint.x(), endPoint.x());
min.y() = std::min<T>(startPoint.y(), endPoint.y());
min.z() = std::min<T>(startPoint.z(), endPoint.z());

max.x() = std::max<T>(startPoint.x(), endPoint.x());
max.y() = std::max<T>(startPoint.y(), endPoint.y());
max.z() = std::max<T>(startPoint.z(), endPoint.z());
}

//两条线段相交
inline static bool Intersection2D(LineSegment & line1, LineSegment & line2, Vec3<T>& insPoint)
{
double D = -line1.direction.x() * line2.direction.y() + line1.direction.y() * line2.direction.x();
if(D == 0.0)
{
return false;
}

auto O12 = line2.startPoint - line1.startPoint;
T D1 = -O12.x() * line2.direction.y() + O12.y() * line2.direction.x();
T D2 = line1.direction.x() * O12.y() - line1.direction.y() * O12.x();

T t1 = D1 / D;
if(t1<0 || t1 > 1)
{
return false;
}

T t2 = D2 / D;
if(t2<0 || t2 > 1)
{
return false;
}

insPoint = line1.startPoint + line1.direction * t1;     //这样计算得到的Z值是不准确的

return true;
}
};


# 3. 参考

posted @ 2021-06-15 20:31  charlee44  阅读(202)  评论(0编辑  收藏  举报