Intersecting Lines POJ - 1269

Intersecting Lines

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 22767 Accepted: 9502

Description

We all know that a pair of distinct points on a plane defines a line and that a pair of lines on a plane will intersect in one of three ways: 1) no intersection because they are parallel, 2) intersect in a line because they are on top of one another (i.e. they are the same line), 3) intersect in a point. In this problem you will use your algebraic knowledge to create a program that determines how and where two lines intersect.
Your program will repeatedly read in four points that define two lines in the x-y plane and determine how and where the lines intersect. All numbers required by this problem will be reasonable, say between -1000 and 1000.

Input
The first line contains an integer N between 1 and 10 describing how many pairs of lines are represented. The next N lines will each contain eight integers. These integers represent the coordinates of four points on the plane in the order x1y1x2y2x3y3x4y4. Thus each of these input lines represents two lines on the plane: the line through (x1,y1) and (x2,y2) and the line through (x3,y3) and (x4,y4). The point (x1,y1) is always distinct from (x2,y2). Likewise with (x3,y3) and (x4,y4).

Output
There should be N+2 lines of output. The first line of output should read INTERSECTING LINES OUTPUT. There will then be one line of output for each pair of planar lines represented by a line of input, describing how the lines intersect: none, line, or point. If the intersection is a point then your program should output the x and y coordinates of the point, correct to two decimal places. The final line of output should read “END OF OUTPUT”.

Sample Input

5
0 0 4 4 0 4 4 0
5 0 7 6 1 0 2 3
5 0 7 6 3 -6 4 -3
2 0 2 27 1 5 18 5
0 3 4 0 1 2 2 5

Sample Output

INTERSECTING LINES OUTPUT
POINT 2.00 2.00
NONE
LINE
POINT 2.00 5.00
POINT 1.07 2.20
END OF OUTPUT

思路:判断两直线的关系,运用叉乘判断两直线是否平行,当Cross(line_1,line_2)==0时,直线有重合和平行两种关系。
判断一下点C D是否在Line_1上。而当两直线一个交点时有如下公式直线Line_1有点(x1,y1),(x2,y2) Line_2有点(x3,y3),(x4,y4).
证明可参考此篇博客

Ac Code:

#include<iostream>
#include<string>
#include<map>
#include<algorithm>
#include<memory.h>
#include<cmath>
#include<vector>
#include<iomanip>
#define pii pair<int,int>
#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const int Max = 1e5 + 5;


#define EPS (1e-10)
#define equals(a,b) (fabs((a)-(b))< EPS )

class Point
{
   
public:
	double x, y;
	Point(double x = 0, double y = 0) :x(x), y(y) {
   }
	Point operator + (Point p) {
    return Point(x + p.x, y + p.y); }
	Point operator - (Point p) {
    return Point(x - p.x, y - p.y); }
	Point operator * (double a) {
    return Point(a * x, a * y); }
	Point operator / (double a) {
    return Point(x / a, y / a); }

	double abs() {
    return sqrt(norm()); }
	double norm() {
    return x * x + y * y; }
	bool operator < (const Point& p)const
	{
   
		return x != p.x ? x < p.x : y < p.y;
	}
	bool operator == (const Point& p)const
	{
   
		return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
	}
};

typedef Point Vector;

struct Segment
{
   
	Point p1, p2;
	Segment(Point a, Point b) :p1(a), p2(b) {
   }
};
typedef Segment Line;

class Circle
{
   
public:
	Point c;
	double r;
	Circle(Point c = Point(), double r = 0.0) :c(c), r(r) {
   }
};

typedef vector<Point> Polygon;

double dot(Vector a, Vector b)//点乘,求投影
{
   
	return a.x * b.x + a.y * b.y;
}

double cross(Vector a, Vector b)//叉乘,求面积
{
   
	return a.x * b.y - a.y * b.x;
}

bool isOrthogonal(Vector a, Vector b)//判断向量AB是否垂直
{
   
	return equals(dot(a, b), 0.0);
}

bool isOrthogonal(Point a1, Point a2, Point b1, Point b2)
{
   
	return isOrthogonal(a1 - a2, b1 - b2);
}

bool isOrthogonal(Segment s1, Segment s2)
{
   
	return equals(dot(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
}

bool isParallel(Vector a, Vector b)
{
   
	return equals(cross(a, b), 0.0);
}

Point project(Segment s, Point p)//点在线段上的投影
{
   
	Vector base = s.p2 - s.p1;
	double r = dot(p - s.p1, base) / base.norm();
	return s.p1 + base * r;
}

Point reflect(Segment s, Point p)//映像
{
   
	return p + (project(s, p) - p) * 2.0;
}

double getDistance(Point a, Point b)//两点之间的距离
{
   
	return (a - b).abs();
}

double getDistanceLP(Line l, Point p)//点到直线的距离
{
   
	return abs(cross(l.p2 - l.p1, p - l.p1) / (l.p2 - l.p1).abs());
}

double getDistanceSP(Segment s, Point p)//点到线段的距离
{
   
	if (dot(s.p2 - s.p1, p - s.p1) < 0.0)return (p - s.p1).abs();
	if (dot(s.p1 - s.p2, p - s.p2) < 0.0)return (p - s.p2).abs();
	return getDistanceLP(s, p);
}

int ccw(Point p0, Point p1, Point p2)
{
   
	Vector a = p1 - p0;
	Vector b = p2 - p0;
	if (cross(a, b) > EPS)return 1;//直线p0-p2在直线p0-p1的逆时针方向;
	if (cross(a, b) < -EPS)return -1;//直线p0-p2在直线p0-p1的顺时针方向;
	if (dot(a, b) < -EPS)return 2;//p2在p0-p1的后方
	if (a.norm() < b.norm())return -2;//p2在p0-p1的前方
	return 0;//p2在p0-p1上
}

bool intersect(Point p1, Point p2, Point p3, Point p4)//线段p1p2与线段p3p4是否相交
{
   
	return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 && ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);
}

bool intersect(Segment s1, Segment s2)//判断线段s1、s2是否相交
{
   
	return intersect(s1.p1, s1.p2, s2.p1, s2.p2);
}

double getDistance(Segment s1, Segment s2)//两线段之间的距离
{
   
	if (intersect(s1, s2))return 0.0;
	return min(min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2)),
		min(getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)));
}

Point getCrossPoint(Segment s1, Segment s2)//线段s1与线段s2的交点
{
   
	Vector base = s2.p2 - s2.p1;
	double d1 = abs(cross(base, s1.p1 - s2.p1));
	double d2 = abs(cross(base, s1.p2 - s2.p1));
	double t = d1 / (d1 + d2);
	return s1.p1 + (s1.p2 - s1.p1) * t;
}

pair<Point, Point> getCrossPoints(Circle c, Line l)//求圆与直线的交点
{
   
	Vector pr = project(l, c.c);
	Vector e = (l.p2 - l.p1) / (l.p2 - l.p1).abs();
	double base = sqrt(c.r * c.r - (pr - c.c).norm());
	return make_pair(pr + e * base, pr - e * base);
}

double arg(Vector p) {
    return atan2(p.y, p.x); }
Vector polar(double a, double r) {
    return Point(cos(r) * a, sin(r) * a); }

pair<Point, Point> getCrossPoints(Circle c1, Circle c2)//圆与圆的交点
{
   
	double d = (c1.c - c2.c).abs();
	double a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
	double t = arg(c2.c - c1.c);
	return make_pair(c1.c + polar(c1.r, t + a), c1.c + polar(c1.r, t - a));
}

int contains(Polygon g, Point p)//内包 点在多边形内返回2,多边形上返回1,多边形外返回0
{
   
	int n = g.size();
	bool x = false;
	for (int i = 0;i < n;i++)
	{
   
		Point a = g[i] - p, b = g[(i + 1) % n] - p;
		if (abs(cross(a, b)) < EPS && dot(a, b) < EPS)return 1;
		if (a.y > b.y) swap(a, b);
		if (a.y < EPS && EPS<b.y && cross(a, b)>EPS)x = !x;
	}
	return (x ? 2 : 0);
}

Polygon andrewScan(Polygon s)//凸包
{
   
	Polygon u, l;
	if (s.size() < 3)return s;
	sort(s.begin(), s.end());
	//将x值最小的2个点添加至u
	u.push_back(s[0]);
	u.push_back(s[1]);
	//将x值最大的2个点添加至u
	l.push_back(s[s.size() - 1]);
	l.push_back(s[s.size() - 2]);

	//构建凸包上部
	for (int i = 2;i < s.size();i++)
	{
   
		for (int n = u.size();n >= 2 && ccw(u[n - 2], u[n - 1], s[i]) != -1;n--)
		{
   
			u.pop_back();
		}
		u.push_back(s[i]);
	}
	//构造凸包下部
	for (int i = s.size() - 3;i >= 0;i--)
	{
   
		for (int n = l.size();n >= 2 && ccw(l[n - 2], l[n - 1], s[i]) != -1;n--)
		{
   
			l.pop_back();
		}
		l.push_back(s[i]);
	}
	//按顺时针方向生成凸包的点的序列
	reverse(l.begin(), l.end());
	for (int i = u.size() - 2;i >= 1;i--)
	{
   
		l.push_back(u[i]);
	}
	return l;
}

double xx, yy;

int getLineCross(Point a, Point b, Point c, Point d)
{
   
	if (isParallel(a - b, c - d))
	{
   
		if (ccw(a, b, c) != 1 && ccw(a, b, c) != -1 && ccw(a, b, d) != 1 && ccw(a, b, d) != -1) return 1;//两直线重叠
		else return 2; //两直线平行
	}
	xx = ((c.x - d.x) * (b.x * a.y - a.x * b.y) - (a.x - b.x) * (d.x * c.y - c.x * d.y)) / ((c.x - d.x) * (a.y - b.y) - (a.x - b.x) * (c.y - d.y));
	yy = ((c.y - d.y) * (b.y * a.x - a.y * b.x) - (a.y - b.y) * (d.y * c.x - c.y * d.x)) / ((c.y - d.y) * (a.x - b.x) - (a.y - b.y) * (c.x - d.x));
	return 3;//两直线相交
}
//y0 = ((y3-y4) * (y2*x1 - y1*x2) - (y1-y2) * (y4*x3 - y3*x4)) / ((y3-y4) * (x1-x2) - (y1-y2) * (x3-x4));
int main()
{
   
	FAST;
	int t;cin >> t;
	cout << "INTERSECTING LINES OUTPUT" << endl;
	while (t--)
	{
   
		Point a, b, c, d;
		cin >> a.x >> a.y >> b.x >> b.y >> c.x >> c.y >> d.x >> d.y;
		int sec = getLineCross(a, b, c, d);
		if (sec == 1)cout << "LINE" << endl;
		if (sec == 2)cout << "NONE" <<endl;
		if (sec == 3)cout <<"POINT "<< fixed << setprecision(2) << xx << " " << yy << endl;
	}
	cout << "END OF OUTPUT" << endl;
}
全部评论

相关推荐

感觉他们一点都不了解现在这个社会就业有多难,已经在牛客刷到好多篇&nbsp;延毕的帖子了,延毕就会导致已经找好的工作就没了,还得重新再找,学校和老师们是怎么想的呢????看到学生丢失工作会开心吗&nbsp;就业数据都在造假,真实的就业困难不去解决&nbsp;一个个真是好样的
从今天开始狠狠卷JV...:学生看到的是导师不放实习导致offer黄了。 导师看到的是招进来的学生吃自己补助和自己的招生名额,却没给自己升迁带来任何帮助,还要跑路。 根本利益的不一致,最主要留校的导师大概率是职场上招聘失败的,被迫留校的,什么牛鬼蛇神都会有
点赞 评论 收藏
分享
05-13 02:01
已编辑
惠州学院 前端工程师
安静的少年在求佛:建议把公司名字写到标题。以后有人想搜就能直接搜到
点赞 评论 收藏
分享
05-23 19:02
吉林大学 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务