Algorithm Design——求两条线段的交点
2013-12-01 11:09
309 查看
/** 给出线段AB以及线段CD,只要判断A、B两点在直线CD的两端,并且C、D两点在直线AB的两端即可。 用叉乘进行判断。 问题描述 下面给出的是一个判断线段相交的次数 输入: n:线段的个数 seg.begin.x,seg.begin.y,seg.end.x,seg.end.y:分别表示线段p1p2的点坐标 输出: n个线段中两两相交的次数 样例输入 2 1 0 0 0 0 1 0 0 样例输出: 1 */ #include<cstdio> using namespace std; struct point { double x, y; }; struct segment { point begin, end; }; double min(double x, double y) { return (x < y) ? x : y; } double max(double x, double y) { return (x > y) ? x : y; } //判断pk是否在线段<pi, pj>上 bool onsegment(point pi, point pj, point pk) { if(min(pi.x, pj.x) <= pk.x && pk.x <= max(pi.x, pj.x)) { if(min(pi.y, pj.y) <= pk.y && pk.y <= max(pi.y, pj.y)) { return true; } } return false; } //计算向量<pk, pi>与向量<pj, pi>的叉乘 double direction(point pi, point pj, point pk) { return (pi.x - pk.x) * (pi.y - pk.y) - (pi.x - pj.x) * (pi.y - pk.y); } //判断p1p2以及p3p4是否相交 bool judge(point p1, point p2, point p3, point p4) { double d1 = direction(p3, p4, p1); double d2 = direction(p3, p4, p2); double d3 = direction(p1, p2, p3); double d4 = direction(p1, p2, p4); if((d1 * d2 < 0) && (d3 * d4 < 0))//如果p1、p2在线段p3p4的两侧并且p3、p4在线段p1p2的两侧 return true; if((d1 == 0) && onsegment(p3, p4, p1))//p1在线段p3p4上 return true; if((d2 == 0) && onsegment(p3, p4, p2))//p2在线段p3p4上 return true; if((d3 == 0) && onsegment(p1, p2, p3))//p3在线段p1p2上 return true; if((d4 == 0) && onsegment(p1, p2, p4))//p4在线段p1p2上 return true; return false; } //求直线p1p2与直线p3p4之间的交点,纯粹性的数学公式求解了 point getIntersection(point p1, point p2, point p3, point p4) { /*根据两点式化为标准式,进而求线性方程组*/ point crossPoint; double tempLeft,tempRight; //求x坐标 tempLeft = (p4.x - p3.x) * (p1.y - p2.y) - (p2.x - p1.x) * (p3.y - p4.y); tempRight = (p1.y - p3.y) * (p2.x - p1.x) * (p4.x - p3.x) + p3.x * (p4.y - p3.y) * (p2.x - p1.x) - p1.x * (p2.y - p1.y) * (p4.x - p3.x); crossPoint.x =tempRight / tempLeft ; //求y坐标 tempLeft = (p1.x - p2.x) * (p4.y - p3.y) - (p2.y - p1.y) * (p3.x - p4.x); tempRight = p2.y * (p1.x - p2.x) * (p4.y - p3.y) + (p4.x- p2.x) * (p4.y - p3.y) * (p1.y - p2.y) - p4.y * (p3.x - p4.x) * (p2.y - p1.y); crossPoint.y = tempRight / tempLeft ; return crossPoint; } int main() { int n; segment seg[2];//两个线段 point intersection; scanf_s("%d", &n); while(n --)//测试次数 { for(int i = 1 ; i <= 2 ; i ++) { scanf_s("%lf%lf%lf%lf", &seg[i].begin.x, &seg[i].begin.y, &seg[i].end.x, &seg[i].end.y); } if(judge(seg[1].begin, seg[1].end, seg[2].begin, seg[2].end)) intersection = getIntersection(seg[1].begin, seg[1].end, seg[2].begin, seg[2].end); printf_s("(%lf, %lf)\n", intersection.x, intersection.y); } return 0; }
相关文章推荐
- Algorithm Design——最大公约数、最小公倍数
- Algorithm Design——凸包
- Algorithm Design——判断线段是否相交
- Algorithm Design Everyday——2.查找学生信息
- Algorithm Design——查找
- Algorithm Design——高精度整数四则运算
- Algorithm Design——并查集
- Algorithm Design——最小生成树
- Algorithm Design——最短路径
- Algorithm常用函数(3)
- Algorithm常用函数(2)
- Algorithm Design Everyday——1.魔女数字7
- Algorithm常用函数(1)
- 字符串匹配算法之Boyer-Moore-Horspool Algorithm
- 蒙哥马利(Montgomery)算法简介
- Django ModelForm的使用
- Django Form
- Django 自验证
- django如何使ForeignKey字段显示树状结构
- HDU3635Dragon Balls(并查集)