两条直线可能有三种关系:1.共线 2.平行(不包括共线) 3.相交。 那给定两条直线怎么判断他们的位置关系呢。还是用到向量的叉积
例题:POJ 1269
题意:这道题是给定四个点p1, p2, p3, p4,直线L1,L2分别穿过前两个和后两个点。来判断直线L1和L2的关系
这三种关系一个一个来看:
1. 共线。 如果两条直线共线的话,那么另外一条直线上的点一定在这一条直线上。所以p3在p1p2上,所以用get_direction(p1, p2, p3)来判断p3相对于p1p2的关系,同理判断p4与p1p2的关系。
2. 平行。 如果两条直线平行的话,分别找出直线L1和L2的向量,那么向量的叉积等于0。其中L1的向量是 p2-p1, L2的向量是p4-p3
3. 相交。 这种情况是最复杂的一中情况,不过有了向量这一工具也不复杂了。
假设p0(x0, y0)是两条直线的交点,那么
p0p1×p2p0=0
p0p3×p4p0=0 (p0p1表示向量p0p1)
将p0代入之后结果得到方程组
x0*(y2-y1) + y0*(x1 - x2) + x2*y1 - x1*y2 = 0
x0*(y4-y3) + y0*(x3 - x4) + x4*y3 - x3*y4 = 0
这是典型的一元二次方程组,联立可得到x和y,
对于普通的二元一次方程组
a1x + b1y + c1 = 0
a2x + b2y + c2 = 0
的解为
x = (b1*c2 - b2*c1) / (b2*a1 - b1 * a2)
y = (a1*c2 - c1*a2) / (a2*b1 - a1 * b2)
所以最后可得出x和y也就是让求的交点坐标。代码如下
/************************************************************************* > File Name: poj_1269_chaji.cpp > Author: > Mail: > Created Time: 2015年04月01日 星期三 21时44分32秒 ************************************************************************/ #include<iostream> #include <cstdio> using namespace std; struct point{ int x, y; }; point p1, p2, p3, p4; int get_direction(point a, point b, point c)//判断点与直线的关系, 也就是叉积 { point t1, t2; t1.x = c.x - a.x; t1.y = c.y - a.y; t2.x = b.x - a.x; t2.y = b.y - a.y; return (t1.x * t2.y - t1.y * t2.x); } int on_line(point a, point b)//判断是否共线 { return (a.x * b.y - a.y * b.x); } //求两直线的交点,返回x和y void get_intersection(point p1, point p2, point p3, point p4, double &x, double &y) { double a1, b1, c1, a2, b2, c2;//求交点过程 a1 = (p2.y - p1.y) * 1.0; b1 = (p1.x - p2.x) * 1.0; c1 = (p2.x * p1.y - p1.x * p2.y) * 1.0; a2 = (p4.y - p3.y) * 1.0; b2 = (p3.x - p4.x) * 1.0; c2 = (p3.y * p4.x - p4.y * p3.x) * 1.0; x = (b1 * c2 - b2 * c1) / (b2 * a1 - b1 * a2); y = (a1 * c2 - c1 * a2) / (a2 * b1 - a1 * b2); } int main() { int n; scanf("%d", &n); puts("INTERSECTING LINES OUTPUT"); while (n--) { scanf("%d %d %d %d %d %d %d %d", &p1.x, &p1.y, &p2.x, &p2.y, &p3.x, &p3.y, &p4.x, &p4.y); if (get_direction(p1, p2, p3) == 0 && get_direction(p1, p2, p4) == 0) { printf("LINE "); continue; } point v1, v2; v1.x = p2.x - p1.x; v1.y = p2.y - p1.y;//直线1的向量 v2.x = p4.x - p3.x; v2.y = p4.y - p3.y;//直线2的向量 if (on_line(v1, v2) == 0) { printf("NONE "); continue; } double x, y; get_intersection(p1, p2, p3, p4, x, y); printf("POINT %.2f %.2f ", x, y); } puts("END OF OUTPUT"); return 0; }